summaryrefslogtreecommitdiff
path: root/lib/Tangence/Meta/Property.pm
blob: 5ed1ddc9152e603eb0f7adeece3a376eabcab150 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#  You may distribute under the terms of either the GNU General Public License
#  or the Artistic License (the same terms as Perl itself)
#
#  (C) Paul Evans, 2011-2017 -- leonerd@leonerd.org.uk

package Tangence::Meta::Property 0.26;

use v5.14;
use warnings;

use Tangence::Constants;

use Scalar::Util qw( weaken );

=head1 NAME

C<Tangence::Meta::Property> - structure representing one C<Tangence> property

=head1 DESCRIPTION

This data structure object stores information about one L<Tangence> class
property. Once constructed, such objects are immutable.

=cut

=head1 CONSTRUCTOR

=cut

=head2 new

   $property = Tangence::Meta::Property->new( %args )

Returns a new instance initialised by the given arguments.

=over 8

=item class => Tangence::Meta::Class

Reference to the containing class

=item name => STRING

Name of the property

=item dimension => INT

Dimension of the property, as one of the C<DIM_*> constants from
L<Tangence::Constants>.

=item type => STRING

The element type as a L<Tangence::Meta::Type> reference.

=item smashed => BOOL

Optional. If true, marks that the property is smashed.

=back

=cut

sub new
{
   my $class = shift;
   my %args = @_;
   my $self = bless \%args, $class;
   weaken $self->{class};
   return $self;
}

=head1 ACCESSORS

=cut

=head2 class

   $class = $property->class

Returns the class the property is a member of

=cut

sub class
{
   my $self = shift;
   return $self->{class};
}

=head2 name

   $name = $property->name

Returns the name of the class

=cut

sub name
{
   my $self = shift;
   return $self->{name};
}

=head2 dimension

   $dimension = $property->dimension

Returns the dimension as one of the C<DIM_*> constants.

=cut

sub dimension
{
   my $self = shift;
   return $self->{dimension};
}

=head2 type

   $type = $property->type

Returns the element type as a L<Tangence::Meta::Type> reference.

=cut

sub type
{
   my $self = shift;
   return $self->{type};
}

=head2 overall_type

   $type = $property->overall_type

Returns the type of the entire collection as a L<Tangence::Meta::Type>
reference. For scalar types this will be the element type. For dict types this
will be a hash of the array type. For array, queue and objset types this will
a list of the element type.

=cut

sub overall_type
{
   my $self = shift;
   return $self->{overall_type} ||= do {
      my $type = $self->type;
      my $dim  = $self->dimension;
      if( $dim == DIM_SCALAR ) {
         $type;
      }
      elsif( $dim == DIM_HASH ) {
         $self->make_type( dict => $type );
      }
      elsif( $dim == DIM_ARRAY or $dim == DIM_QUEUE or $dim == DIM_OBJSET ) {
         $self->make_type( list => $type );
      }
      else {
         die "Unrecognised dimension $dim for ->overall_type";
      }
   }
}

=head2 smashed

   $smashed = $property->smashed

Returns true if the property is smashed.

=cut

sub smashed
{
   my $self = shift;
   return $self->{smashed};
}

# For subclasses to override if required
sub make_type
{
   shift;
   return Tangence::Meta::Type->new( @_ );
}

=head1 AUTHOR

Paul Evans <leonerd@leonerd.org.uk>

=cut

0x55AA;