File Coverage

blib/lib/Tangence/Meta/Type.pm
Criterion Covered Total %
statement 28 29 96.5
branch 9 10 90.0
condition 9 15 60.0
subroutine 7 7 100.0
pod 2 3 66.6
total 55 64 85.9


line stmt bran cond sub pod time code
1             # You may distribute under the terms of either the GNU General Public License
2             # or the Artistic License (the same terms as Perl itself)
3             #
4             # (C) Paul Evans, 2012-2024 -- leonerd@leonerd.org.uk
5              
6 15     15   177 use v5.26;
  15         51  
7 15     15   81 use warnings;
  15         71  
  15         980  
8 15     15   83 use Object::Pad 0.800;
  15         110  
  15         679  
9              
10             package Tangence::Meta::Type 0.33;
11             class Tangence::Meta::Type :strict(params);
12              
13 15     15   6672 use Carp;
  15         53  
  15         31091  
14              
15             =head1 NAME
16              
17             C - structure representing one C value type
18              
19             =head1 DESCRIPTION
20              
21             This data structure object represents information about a type, such as a
22             method or event argument, a method return value, or a property element type.
23              
24             Due to their simple contents and immutable nature, these objects may be
25             implemented as singletons. Repeated calls to the constructor method for the
26             same type name will yield the same instance.
27              
28             =cut
29              
30             =head1 CONSTRUCTOR
31              
32             =cut
33              
34             =head2 make
35              
36             $type = Tangence::Meta::Type->make( $primitive )
37              
38             Returns an instance to represent the given primitive type signature.
39              
40             $type = Tangence::Meta::Type->make( $aggregate => $member_type )
41              
42             Returns an instance to represent the given aggregation of the given type
43             instance.
44              
45             =cut
46              
47             our %PRIMITIVES;
48             our %LISTS;
49             our %DICTS;
50              
51             sub make
52             {
53 1040     1040 1 1872 my $class = shift;
54              
55 1040 100 66     3428 if( @_ == 1 ) {
    100 33        
    50          
56 820         1664 my ( $sig ) = @_;
57 820   66     13344 return $PRIMITIVES{$sig} //=
58             $class->new( member_type => $sig );
59             }
60             elsif( @_ == 2 and $_[0] eq "list" ) {
61 141         344 my ( undef, $membertype ) = @_;
62 141   66     996 return $LISTS{$membertype->sig} //=
63             $class->new( aggregate => "list", member_type => $membertype );
64             }
65             elsif( @_ == 2 and $_[0] eq "dict" ) {
66 79         199 my ( undef, $membertype ) = @_;
67 79   66     576 return $DICTS{$membertype->sig} //=
68             $class->new( aggregate => "dict", member_type => $membertype );
69             }
70              
71 0         0 die "TODO: @_";
72             }
73              
74             =head2 make _from_sig
75              
76             $type = Tangence::Meta::Type->make_from_sig( $sig )
77              
78             Parses the given full Tangence type signature and returns an instance to
79             represent it.
80              
81             =cut
82              
83 529         797 sub make_from_sig ( $class, $sig )
84 529     529 0 946 {
  529         879  
  529         747  
85 529 100       1609 $sig =~ m/^list\((.*)\)$/ and
86             return $class->make( list => $class->make_from_sig( $1 ) );
87              
88 475 100       1325 $sig =~ m/^dict\((.*)\)$/ and
89             return $class->make( dict => $class->make_from_sig( $1 ) );
90              
91 430         1421 return $class->make( $sig );
92             }
93              
94 1     1 1 4 field $aggregate :param :reader = "prim";
95 1         6 field $member_type :param;
96              
97             =head1 ACCESSORS
98              
99             =cut
100              
101             =head2 aggregate
102              
103             $agg = $type->aggregate
104              
105             Returns C<"prim"> for primitive types, or the aggregation name for list and
106             dict aggregate types.
107              
108             =cut
109              
110             =head2 member_type
111              
112             $member_type = $type->member_type
113              
114             Returns the member type for aggregation types. Throws an exception for
115             primitive types.
116              
117             =cut
118              
119             method member_type
120             {
121             die "Cannot return the member type for primitive types" if $aggregate eq "prim";
122             return $member_type;
123             }
124              
125             =head2 sig
126              
127             $sig = $type->sig
128              
129             Returns the Tangence type signature for the type.
130              
131             =cut
132              
133             method sig
134             {
135             return $self->${\"_sig_for_$aggregate"}();
136             }
137              
138             method _sig_for_prim
139             {
140             return $member_type;
141             }
142              
143             method _sig_for_list
144             {
145             return "list(" . $member_type->sig . ")";
146             }
147              
148             method _sig_for_dict
149             {
150             return "dict(" . $member_type->sig . ")";
151             }
152              
153             =head1 AUTHOR
154              
155             Paul Evans
156              
157             =cut
158              
159             0x55AA;