| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Type::Params::Signature; |
|
2
|
|
|
|
|
|
|
|
|
3
|
75
|
|
|
75
|
|
2597
|
use 5.008001; |
|
|
75
|
|
|
|
|
312
|
|
|
4
|
75
|
|
|
75
|
|
874
|
use strict; |
|
|
75
|
|
|
|
|
222
|
|
|
|
75
|
|
|
|
|
2148
|
|
|
5
|
75
|
|
|
75
|
|
2135
|
use warnings; |
|
|
75
|
|
|
|
|
236
|
|
|
|
75
|
|
|
|
|
7000
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
BEGIN { |
|
8
|
75
|
50
|
|
75
|
|
5636
|
if ( $] < 5.010 ) { require Devel::TypeTiny::Perl58Compat } |
|
|
11
|
|
|
|
|
99
|
|
|
9
|
|
|
|
|
|
|
} |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
BEGIN { |
|
12
|
75
|
|
|
75
|
|
324
|
$Type::Params::Signature::AUTHORITY = 'cpan:TOBYINK'; |
|
13
|
75
|
|
|
|
|
5416
|
$Type::Params::Signature::VERSION = '2.010001'; |
|
14
|
|
|
|
|
|
|
} |
|
15
|
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
$Type::Params::Signature::VERSION =~ tr/_//d; |
|
17
|
|
|
|
|
|
|
|
|
18
|
75
|
|
|
73
|
|
582
|
use B (); |
|
|
75
|
|
|
|
|
453
|
|
|
|
75
|
|
|
|
|
3307
|
|
|
19
|
73
|
|
|
73
|
|
40184
|
use Eval::TypeTiny::CodeAccumulator; |
|
|
73
|
|
|
|
|
255
|
|
|
|
73
|
|
|
|
|
3575
|
|
|
20
|
73
|
|
|
73
|
|
716
|
use Types::Standard qw( -is -types -assert ); |
|
|
73
|
|
|
|
|
200
|
|
|
|
73
|
|
|
|
|
2940
|
|
|
21
|
73
|
|
|
73
|
|
14436
|
use Types::TypeTiny qw( -is -types to_TypeTiny ); |
|
|
73
|
|
|
|
|
268
|
|
|
|
73
|
|
|
|
|
2706
|
|
|
22
|
73
|
|
|
73
|
|
190627
|
use Type::Params::Parameter; |
|
|
73
|
|
|
|
|
338
|
|
|
|
73
|
|
|
|
|
70097
|
|
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
my $Attrs = Enum[ qw/ |
|
25
|
|
|
|
|
|
|
caller_level package subname description _is_signature_for ID |
|
26
|
|
|
|
|
|
|
method head tail parameters slurpy |
|
27
|
|
|
|
|
|
|
message on_die next fallback strictness is_named allow_dash method_invocant |
|
28
|
|
|
|
|
|
|
bless class constructor named_to_list list_to_named oo_trace |
|
29
|
|
|
|
|
|
|
class_prefix class_attributes |
|
30
|
|
|
|
|
|
|
returns_scalar returns_list |
|
31
|
|
|
|
|
|
|
want_details want_object want_source can_shortcut coderef |
|
32
|
|
|
|
|
|
|
quux mite_signature is_wrapper |
|
33
|
|
|
|
|
|
|
/ ]; # quux for reasons |
|
34
|
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
sub _croak { |
|
36
|
18
|
|
|
18
|
|
152
|
require Error::TypeTiny; |
|
37
|
18
|
|
|
|
|
121
|
return Error::TypeTiny::croak( pop ); |
|
38
|
|
|
|
|
|
|
} |
|
39
|
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _new_parameter { |
|
41
|
801
|
|
|
801
|
|
1974
|
shift; |
|
42
|
801
|
|
|
|
|
4293
|
'Type::Params::Parameter'->new( @_ ); |
|
43
|
|
|
|
|
|
|
} |
|
44
|
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
sub _new_code_accumulator { |
|
46
|
412
|
|
|
412
|
|
891
|
shift; |
|
47
|
412
|
|
|
|
|
4433
|
'Eval::TypeTiny::CodeAccumulator'->new( @_ ); |
|
48
|
|
|
|
|
|
|
} |
|
49
|
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub new { |
|
51
|
336
|
|
|
336
|
1
|
850
|
my $class = shift; |
|
52
|
336
|
50
|
|
|
|
4806
|
my %self = @_ == 1 ? %{$_[0]} : @_; |
|
|
5
|
|
|
|
|
1104
|
|
|
53
|
336
|
|
|
|
|
1034
|
my $self = bless \%self, $class; |
|
54
|
336
|
|
50
|
|
|
1760
|
$self->{parameters} ||= []; |
|
55
|
336
|
|
50
|
|
|
3568
|
$self->{class_prefix} ||= 'Type::Params::OO::Klass'; |
|
56
|
336
|
100
|
33
|
|
|
1224
|
$self->{next} ||= delete $self->{goto_next} if exists $self->{goto_next}; |
|
57
|
336
|
|
|
|
|
1587
|
$self->BUILD; |
|
58
|
329
|
100
|
|
|
|
6272
|
$Attrs->all( sort keys %$self ) or do { |
|
59
|
6
|
|
|
|
|
39
|
require Carp; |
|
60
|
6
|
|
|
|
|
16
|
require Type::Utils; |
|
61
|
6
|
|
|
|
|
146
|
my @bad = ( ~ $Attrs )->grep( sort keys %$self ); |
|
62
|
6
|
100
|
|
|
|
42
|
Carp::carp( sprintf( |
|
63
|
|
|
|
|
|
|
"Warning: unrecognized signature %s: %s, continuing anyway", |
|
64
|
|
|
|
|
|
|
@bad == 1 ? 'option' : 'options', |
|
65
|
|
|
|
|
|
|
Type::Utils::english_list( @bad ), |
|
66
|
|
|
|
|
|
|
) ); |
|
67
|
|
|
|
|
|
|
}; |
|
68
|
327
|
|
|
|
|
1362
|
return $self; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
{ |
|
72
|
|
|
|
|
|
|
my $klass_id; |
|
73
|
|
|
|
|
|
|
my %klass_cache; |
|
74
|
|
|
|
|
|
|
sub BUILD { |
|
75
|
334
|
|
|
334
|
1
|
1306
|
my $self = shift; |
|
76
|
|
|
|
|
|
|
|
|
77
|
334
|
100
|
100
|
|
|
3525
|
if ( $self->{named_to_list} and not is_ArrayRef $self->{named_to_list} ) { |
|
78
|
15
|
|
|
|
|
35
|
$self->{named_to_list} = [ map $_->name, @{ $self->{parameters} } ]; |
|
|
15
|
|
|
|
|
742
|
|
|
79
|
|
|
|
|
|
|
} |
|
80
|
|
|
|
|
|
|
|
|
81
|
334
|
50
|
|
|
|
1261
|
if ( delete $self->{rationalize_slurpies} ) { |
|
82
|
334
|
|
|
|
|
1315
|
$self->_rationalize_slurpies; |
|
83
|
|
|
|
|
|
|
} |
|
84
|
|
|
|
|
|
|
|
|
85
|
329
|
100
|
|
|
|
4953
|
if ( $self->{method} ) { |
|
86
|
41
|
|
|
|
|
141
|
my $type = $self->{method}; |
|
87
|
|
|
|
|
|
|
$type = |
|
88
|
|
|
|
|
|
|
is_Int($type) ? Defined : |
|
89
|
41
|
0
|
|
|
|
316
|
is_Str($type) ? do { require Type::Utils; Type::Utils::dwim_type( $type, $self->{package} ? ( for => $self->{package} ) : () ) } : |
|
|
3
|
50
|
|
|
|
410
|
|
|
|
3
|
100
|
|
|
|
24
|
|
|
90
|
|
|
|
|
|
|
to_TypeTiny( $type ); |
|
91
|
41
|
|
50
|
|
|
208
|
unshift @{ $self->{head} ||= [] }, $self->_new_parameter( |
|
|
41
|
|
|
|
|
595
|
|
|
92
|
|
|
|
|
|
|
name => 'invocant', |
|
93
|
|
|
|
|
|
|
type => $type, |
|
94
|
|
|
|
|
|
|
); |
|
95
|
|
|
|
|
|
|
} |
|
96
|
|
|
|
|
|
|
|
|
97
|
329
|
|
|
|
|
1733
|
$self->_rationalize_returns; |
|
98
|
|
|
|
|
|
|
|
|
99
|
329
|
100
|
100
|
|
|
8127
|
if ( defined $self->{bless} and is_BoolLike $self->{bless} and $self->{bless} and not $self->{named_to_list} ) { |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
100
|
52
|
|
|
|
|
1645
|
my $klass_key = $self->_klass_key; |
|
101
|
52
|
|
66
|
|
|
3425
|
$self->{bless} = ( $klass_cache{$klass_key} ||= sprintf( '%s%d', $self->{class_prefix}, ++$klass_id ) ); |
|
102
|
52
|
100
|
|
|
|
272
|
$self->{oo_trace} = 1 unless exists $self->{oo_trace}; |
|
103
|
52
|
|
|
|
|
749
|
$self->make_class; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
327
|
100
|
|
|
|
5430
|
if ( is_ArrayRef $self->{class} ) { |
|
106
|
11
|
|
|
|
|
39
|
$self->{constructor} = $self->{class}->[1]; |
|
107
|
11
|
|
|
|
|
658
|
$self->{class} = $self->{class}->[0]; |
|
108
|
|
|
|
|
|
|
} |
|
109
|
|
|
|
|
|
|
} |
|
110
|
|
|
|
|
|
|
} |
|
111
|
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
sub _klass_key { |
|
113
|
52
|
|
|
52
|
|
124
|
my $self = shift; |
|
114
|
|
|
|
|
|
|
|
|
115
|
52
|
|
|
|
|
121
|
my @parameters = @{ $self->parameters }; |
|
|
52
|
|
|
|
|
567
|
|
|
116
|
51
|
100
|
|
|
|
223
|
if ( $self->has_slurpy ) { |
|
117
|
3
|
|
|
|
|
6
|
push @parameters, $self->slurpy; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
|
|
120
|
73
|
|
|
69
|
|
2730
|
no warnings 'uninitialized'; |
|
|
73
|
|
|
|
|
379
|
|
|
|
73
|
|
|
|
|
615351
|
|
|
121
|
|
|
|
|
|
|
join( |
|
122
|
|
|
|
|
|
|
'|', |
|
123
|
|
|
|
|
|
|
map sprintf( '%s*%s*%s', $_->name, $_->getter, $_->predicate ), |
|
124
|
51
|
|
|
|
|
363
|
sort { $a->{name} cmp $b->{name} } @parameters |
|
|
62
|
|
|
|
|
366
|
|
|
125
|
|
|
|
|
|
|
); |
|
126
|
|
|
|
|
|
|
} |
|
127
|
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub _rationalize_slurpies { |
|
129
|
333
|
|
|
334
|
|
782
|
my $self = shift; |
|
130
|
|
|
|
|
|
|
|
|
131
|
333
|
|
|
|
|
1424
|
my $parameters = $self->parameters; |
|
132
|
|
|
|
|
|
|
|
|
133
|
333
|
100
|
|
|
|
1224
|
if ( $self->is_named ) { |
|
|
|
100
|
|
|
|
|
|
|
134
|
179
|
|
|
|
|
420
|
my ( @slurpy, @rest ); |
|
135
|
|
|
|
|
|
|
|
|
136
|
179
|
|
|
|
|
843
|
for my $parameter ( @$parameters ) { |
|
137
|
424
|
100
|
|
|
|
1817
|
if ( $parameter->type->is_strictly_a_type_of( Slurpy ) ) { |
|
|
|
100
|
|
|
|
|
|
|
138
|
28
|
|
|
|
|
113
|
push @slurpy, $parameter; |
|
139
|
|
|
|
|
|
|
} |
|
140
|
|
|
|
|
|
|
elsif ( $parameter->{slurpy} ) { |
|
141
|
3
|
|
|
|
|
342
|
$parameter->{type} = Slurpy[ $parameter->type ]; |
|
142
|
3
|
|
|
|
|
16
|
push @slurpy, $parameter; |
|
143
|
|
|
|
|
|
|
} |
|
144
|
|
|
|
|
|
|
else { |
|
145
|
397
|
|
|
|
|
1742
|
push @rest, $parameter; |
|
146
|
|
|
|
|
|
|
} |
|
147
|
|
|
|
|
|
|
} |
|
148
|
|
|
|
|
|
|
|
|
149
|
179
|
100
|
|
|
|
1228
|
if ( @slurpy == 1 ) { |
|
|
|
100
|
|
|
|
|
|
|
150
|
25
|
|
|
|
|
124
|
my $constraint = $slurpy[0]->type; |
|
151
|
25
|
100
|
66
|
|
|
138
|
if ( $constraint->type_parameter && $constraint->type_parameter->{uniq} == Any->{uniq} or $constraint->my_slurp_into eq 'HASH' ) { |
|
|
|
|
100
|
|
|
|
|
|
152
|
24
|
|
|
|
|
133
|
$self->{slurpy} = $slurpy[0]; |
|
153
|
24
|
|
|
|
|
118
|
@$parameters = @rest; |
|
154
|
|
|
|
|
|
|
} |
|
155
|
|
|
|
|
|
|
else { |
|
156
|
1
|
|
|
|
|
6
|
$self->_croak( 'Signatures with named parameters can only have slurpy parameters which are a subtype of HashRef' ); |
|
157
|
|
|
|
|
|
|
} |
|
158
|
|
|
|
|
|
|
} |
|
159
|
|
|
|
|
|
|
elsif ( @slurpy ) { |
|
160
|
1
|
|
|
|
|
6
|
$self->_croak( 'Found multiple slurpy parameters! There can be only one' ); |
|
161
|
|
|
|
|
|
|
} |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
elsif ( @$parameters ) { |
|
164
|
151
|
100
|
|
|
|
770
|
if ( $parameters->[-1]->type->is_strictly_a_type_of( Slurpy ) ) { |
|
|
|
100
|
|
|
|
|
|
|
165
|
40
|
|
|
|
|
206
|
$self->{slurpy} = pop @$parameters; |
|
166
|
|
|
|
|
|
|
} |
|
167
|
|
|
|
|
|
|
elsif ( $parameters->[-1]{slurpy} ) { |
|
168
|
7
|
|
|
|
|
44
|
$self->{slurpy} = pop @$parameters; |
|
169
|
7
|
|
|
|
|
45
|
$self->{slurpy}{type} = Slurpy[ $self->{slurpy}{type} ]; |
|
170
|
|
|
|
|
|
|
} |
|
171
|
|
|
|
|
|
|
|
|
172
|
151
|
|
|
|
|
604
|
for my $parameter ( @$parameters ) { |
|
173
|
214
|
100
|
66
|
|
|
977
|
if ( $parameter->type->is_strictly_a_type_of( Slurpy ) or $parameter->{slurpy} ) { |
|
174
|
3
|
|
|
|
|
17
|
$self->_croak( 'Parameter following slurpy parameter' ); |
|
175
|
|
|
|
|
|
|
} |
|
176
|
|
|
|
|
|
|
} |
|
177
|
|
|
|
|
|
|
} |
|
178
|
|
|
|
|
|
|
|
|
179
|
326
|
100
|
100
|
|
|
1896
|
if ( $self->{slurpy} and $self->{slurpy}->has_default ) { |
|
180
|
1
|
|
|
|
|
6
|
require Carp; |
|
181
|
1
|
|
|
|
|
3
|
our @CARP_NOT = ( __PACKAGE__, 'Type::Params' ); |
|
182
|
1
|
|
|
|
|
166
|
Carp::carp( "Warning: the default for the slurpy parameter will be ignored, continuing anyway" ); |
|
183
|
1
|
|
|
|
|
8
|
delete $self->{slurpy}{default}; |
|
184
|
|
|
|
|
|
|
} |
|
185
|
|
|
|
|
|
|
|
|
186
|
326
|
100
|
100
|
|
|
2012
|
if ( $self->{slurpy} and $self->{slurpy}->optional ) { |
|
187
|
1
|
|
|
|
|
10
|
require Carp; |
|
188
|
1
|
|
|
|
|
5
|
our @CARP_NOT = ( __PACKAGE__, 'Type::Params' ); |
|
189
|
1
|
|
|
|
|
267
|
Carp::carp( "Warning: the optional for the slurpy parameter will be ignored, continuing anyway" ); |
|
190
|
1
|
|
|
|
|
14
|
delete $self->{slurpy}{optional}; |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
sub _rationalize_returns { |
|
195
|
348
|
|
|
351
|
|
893
|
my $self = shift; |
|
196
|
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
my $typify = sub { |
|
198
|
131
|
|
|
134
|
|
272
|
my $ref = shift; |
|
199
|
131
|
100
|
|
|
|
406
|
if ( is_Str $$ref ) { |
|
200
|
1
|
|
|
|
|
9
|
require Type::Utils; |
|
201
|
1
|
50
|
|
|
|
37
|
$$ref = Type::Utils::dwim_type( $$ref, $self->{package} ? ( for => $self->{package} ) : () ); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
else { |
|
204
|
130
|
|
|
|
|
449
|
$$ref = to_TypeTiny( $$ref ); |
|
205
|
|
|
|
|
|
|
} |
|
206
|
348
|
|
|
|
|
2694
|
}; |
|
207
|
|
|
|
|
|
|
|
|
208
|
348
|
100
|
|
|
|
1644
|
if ( my $r = delete $self->{returns} ) { |
|
209
|
7
|
|
|
|
|
43
|
$typify->( \ $r ); |
|
210
|
7
|
|
33
|
|
|
90
|
$self->{returns_scalar} ||= $r; |
|
211
|
7
|
|
33
|
|
|
74
|
$self->{returns_list} ||= ArrayRef->of( $r ); |
|
212
|
|
|
|
|
|
|
} |
|
213
|
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
exists $self->{$_} && $typify->( \ $self->{$_} ) |
|
215
|
348
|
|
66
|
|
|
2415
|
for qw/ returns_scalar returns_list /; |
|
216
|
|
|
|
|
|
|
|
|
217
|
348
|
|
|
|
|
2673
|
return $self; |
|
218
|
|
|
|
|
|
|
} |
|
219
|
|
|
|
|
|
|
|
|
220
|
|
|
|
|
|
|
sub _parameters_from_list { |
|
221
|
370
|
|
|
373
|
|
1975
|
my ( $class, $style, $list, %opts ) = @_; |
|
222
|
370
|
|
|
|
|
744
|
my @return; |
|
223
|
370
|
|
|
|
|
869
|
my $is_named = ( $style eq 'named' ); |
|
224
|
|
|
|
|
|
|
|
|
225
|
370
|
|
|
|
|
1256
|
while ( @$list ) { |
|
226
|
758
|
|
|
|
|
1476
|
my ( $type, %param_opts ); |
|
227
|
758
|
100
|
|
|
|
2254
|
if ( $is_named ) { |
|
228
|
422
|
|
|
|
|
1822
|
$param_opts{name} = assert_Str( shift( @$list ) ); |
|
229
|
|
|
|
|
|
|
} |
|
230
|
758
|
100
|
66
|
|
|
7972
|
if ( is_HashRef $list->[0] and exists $list->[0]{slurpy} and not is_Bool $list->[0]{slurpy} ) { |
|
|
|
|
33
|
|
|
|
|
|
231
|
2
|
|
|
|
|
4
|
my %new_opts = %{ shift( @$list ) }; |
|
|
2
|
|
|
|
|
9
|
|
|
232
|
2
|
|
|
|
|
7
|
$type = delete $new_opts{slurpy}; |
|
233
|
2
|
|
|
|
|
6
|
%param_opts = ( %param_opts, %new_opts, slurpy => 1 ); |
|
234
|
|
|
|
|
|
|
} |
|
235
|
|
|
|
|
|
|
else { |
|
236
|
756
|
|
|
|
|
1687
|
$type = shift( @$list ); |
|
237
|
|
|
|
|
|
|
} |
|
238
|
758
|
100
|
|
|
|
3365
|
if ( is_HashRef( $list->[0] ) ) { |
|
239
|
74
|
100
|
100
|
|
|
364
|
unless ( exists $list->[0]{slurpy} and not is_Bool $list->[0]{slurpy} ) { |
|
240
|
72
|
|
|
|
|
197
|
%param_opts = ( %param_opts, %{ +shift( @$list ) } ); |
|
|
72
|
|
|
|
|
331
|
|
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
$param_opts{type} = |
|
244
|
4
|
|
|
|
|
13
|
is_Int($type) ? ( $type ? Any : do { $param_opts{optional} = !!1; Any; } ) : |
|
|
4
|
|
|
|
|
17
|
|
|
245
|
758
|
100
|
|
|
|
5787
|
is_Str($type) ? do { require Type::Utils; Type::Utils::dwim_type( $type, $opts{package} ? ( for => $opts{package} ) : () ) } : |
|
|
2
|
50
|
|
|
|
37
|
|
|
|
2
|
100
|
|
|
|
20
|
|
|
|
|
100
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
to_TypeTiny( $type ); |
|
247
|
758
|
|
|
|
|
3738
|
my $parameter = $class->_new_parameter( %param_opts ); |
|
248
|
758
|
|
|
|
|
4099
|
push @return, $parameter; |
|
249
|
|
|
|
|
|
|
} |
|
250
|
|
|
|
|
|
|
|
|
251
|
370
|
|
|
|
|
2182
|
return \@return; |
|
252
|
|
|
|
|
|
|
} |
|
253
|
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
sub new_from_compile { |
|
255
|
331
|
|
|
334
|
1
|
449302
|
my $class = shift; |
|
256
|
331
|
|
|
|
|
762
|
my $style = shift; |
|
257
|
331
|
|
|
|
|
832
|
my $is_named = ( $style eq 'named' ); |
|
258
|
|
|
|
|
|
|
|
|
259
|
331
|
|
|
|
|
811
|
my %opts = (); |
|
260
|
331
|
|
66
|
|
|
3014
|
while ( is_HashRef $_[0] and not exists $_[0]{slurpy} ) { |
|
261
|
423
|
|
|
|
|
1060
|
%opts = ( %opts, %{ +shift } ); |
|
|
423
|
|
|
|
|
7274
|
|
|
262
|
|
|
|
|
|
|
} |
|
263
|
|
|
|
|
|
|
|
|
264
|
331
|
|
|
|
|
1001
|
for my $pos ( qw/ head tail / ) { |
|
265
|
662
|
100
|
|
|
|
6288
|
next unless defined $opts{$pos}; |
|
266
|
39
|
100
|
|
|
|
156
|
if ( is_Int( $opts{$pos} ) ) { |
|
267
|
6
|
|
|
|
|
29
|
$opts{$pos} = [ ( Any ) x $opts{$pos} ]; |
|
268
|
|
|
|
|
|
|
} |
|
269
|
39
|
|
|
|
|
230
|
$opts{$pos} = $class->_parameters_from_list( positional => $opts{$pos}, %opts ); |
|
270
|
|
|
|
|
|
|
} |
|
271
|
|
|
|
|
|
|
|
|
272
|
331
|
|
|
|
|
1270
|
my $list = [ @_ ]; |
|
273
|
331
|
|
|
|
|
1136
|
$opts{is_named} = $is_named; |
|
274
|
331
|
|
|
|
|
1886
|
$opts{parameters} = $class->_parameters_from_list( $style => $list, %opts ); |
|
275
|
|
|
|
|
|
|
|
|
276
|
331
|
|
|
|
|
2242
|
my $self = $class->new( %opts, rationalize_slurpies => 1 ); |
|
277
|
324
|
|
|
|
|
3122
|
return $self; |
|
278
|
|
|
|
|
|
|
} |
|
279
|
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
sub new_from_v2api { |
|
281
|
356
|
|
|
359
|
1
|
1175
|
my ( $class, $opts ) = @_; |
|
282
|
|
|
|
|
|
|
|
|
283
|
356
|
|
100
|
|
|
2237
|
my $positional = delete( $opts->{positional} ) || delete( $opts->{pos} ); |
|
284
|
356
|
|
|
|
|
981
|
my $named = delete( $opts->{named} ); |
|
285
|
356
|
|
100
|
|
|
2225
|
my $multiple = delete( $opts->{multiple} ) || delete( $opts->{multi} ); |
|
286
|
|
|
|
|
|
|
|
|
287
|
356
|
100
|
100
|
|
|
2387
|
$class->_croak( "Signature must be positional, named, or multiple" ) |
|
|
|
|
100
|
|
|
|
|
|
288
|
|
|
|
|
|
|
unless $positional || $named || $multiple; |
|
289
|
|
|
|
|
|
|
|
|
290
|
354
|
100
|
|
|
|
1248
|
if ( $multiple ) { |
|
291
|
22
|
100
|
|
|
|
187
|
if ( is_HashRef $multiple ) { |
|
|
|
100
|
|
|
|
|
|
|
292
|
1
|
|
|
|
|
4
|
my @tmp; |
|
293
|
1
|
|
|
|
|
8
|
while ( my ( $name, $alt ) = each %$multiple ) { |
|
294
|
6
|
50
|
|
|
|
50
|
push @tmp, |
|
|
|
50
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
is_HashRef($alt) ? { ID => $name, %$alt } : |
|
296
|
|
|
|
|
|
|
is_ArrayRef($alt) ? { ID => $name, pos => $alt } : |
|
297
|
|
|
|
|
|
|
is_CodeRef($alt) ? { ID => $name, closure => $alt } : |
|
298
|
|
|
|
|
|
|
$class->_croak( "Bad alternative in multiple signature" ); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
1
|
|
|
|
|
9
|
$multiple = \@tmp; |
|
301
|
|
|
|
|
|
|
} |
|
302
|
|
|
|
|
|
|
elsif ( not is_ArrayRef $multiple ) { |
|
303
|
2
|
|
|
|
|
7
|
$multiple = []; |
|
304
|
|
|
|
|
|
|
} |
|
305
|
22
|
100
|
|
|
|
100
|
unshift @$multiple, { positional => $positional } if $positional; |
|
306
|
22
|
100
|
|
|
|
67
|
unshift @$multiple, { named => $named } if $named; |
|
307
|
22
|
|
|
|
|
4407
|
require Type::Params::Alternatives; |
|
308
|
22
|
|
|
|
|
226
|
return 'Type::Params::Alternatives'->new( |
|
309
|
|
|
|
|
|
|
base_options => $opts, |
|
310
|
|
|
|
|
|
|
alternatives => $multiple, |
|
311
|
|
|
|
|
|
|
sig_class => $class, |
|
312
|
|
|
|
|
|
|
); |
|
313
|
|
|
|
|
|
|
} |
|
314
|
|
|
|
|
|
|
|
|
315
|
332
|
|
|
|
|
980
|
my ( $sig_kind, $args ) = ( pos => $positional ); |
|
316
|
332
|
100
|
|
|
|
1135
|
if ( $named ) { |
|
317
|
178
|
100
|
|
|
|
663
|
$opts->{bless} = 1 unless exists $opts->{bless}; |
|
318
|
178
|
|
|
|
|
447
|
( $sig_kind, $args ) = ( named => $named ); |
|
319
|
178
|
100
|
|
|
|
633
|
$class->_croak( "Signature cannot have both positional and named arguments" ) |
|
320
|
|
|
|
|
|
|
if $positional; |
|
321
|
|
|
|
|
|
|
} |
|
322
|
|
|
|
|
|
|
|
|
323
|
330
|
|
|
|
|
1671
|
return $class->new_from_compile( $sig_kind, $opts, @$args ); |
|
324
|
|
|
|
|
|
|
} |
|
325
|
|
|
|
|
|
|
|
|
326
|
683
|
|
|
686
|
1
|
4556
|
sub package { $_[0]{package} } |
|
327
|
685
|
|
|
688
|
1
|
5784
|
sub subname { $_[0]{subname} } |
|
328
|
344
|
|
|
346
|
1
|
2298
|
sub description { $_[0]{description} } sub has_description { exists $_[0]{description} } |
|
|
0
|
|
|
2
|
1
|
0
|
|
|
329
|
344
|
|
|
346
|
1
|
1529
|
sub method { $_[0]{method} } |
|
330
|
1575
|
|
|
1577
|
1
|
5718
|
sub head { $_[0]{head} } sub has_head { exists $_[0]{head} } |
|
|
387
|
|
|
389
|
1
|
2956
|
|
|
331
|
1361
|
|
|
1361
|
1
|
4114
|
sub tail { $_[0]{tail} } sub has_tail { exists $_[0]{tail} } |
|
|
64
|
|
|
64
|
1
|
176
|
|
|
332
|
1
|
|
|
1
|
1
|
426
|
sub parameters { $_[0]{parameters} } sub has_parameters { exists $_[0]{parameters} } |
|
|
1288
|
|
|
1288
|
1
|
9378
|
|
|
333
|
876
|
|
|
876
|
1
|
3414
|
sub slurpy { $_[0]{slurpy} } sub has_slurpy { exists $_[0]{slurpy} } |
|
|
244
|
|
|
244
|
1
|
1598
|
|
|
334
|
1959
|
|
|
1959
|
1
|
13944
|
sub on_die { $_[0]{on_die} } sub has_on_die { exists $_[0]{on_die} } |
|
|
7
|
|
|
7
|
1
|
32
|
|
|
335
|
1386
|
|
|
1386
|
1
|
4581
|
sub strictness { $_[0]{strictness} } sub has_strictness { exists $_[0]{strictness} } |
|
|
949
|
|
|
949
|
1
|
5295
|
|
|
336
|
712
|
|
|
712
|
1
|
3715
|
sub next { $_[0]{next} } |
|
337
|
0
|
|
|
0
|
1
|
0
|
sub goto_next { $_[0]{next} } |
|
338
|
2207
|
|
|
2207
|
1
|
8678
|
sub is_named { $_[0]{is_named} } |
|
339
|
590
|
|
|
590
|
1
|
1231
|
sub allow_dash { $_[0]{allow_dash} } |
|
340
|
710
|
|
|
710
|
1
|
3683
|
sub bless { $_[0]{bless} } |
|
341
|
182
|
|
|
182
|
1
|
714
|
sub class { $_[0]{class} } |
|
342
|
24
|
|
|
24
|
1
|
149
|
sub constructor { $_[0]{constructor} } |
|
343
|
209
|
|
|
209
|
1
|
1077
|
sub named_to_list { $_[0]{named_to_list} } |
|
344
|
907
|
|
|
907
|
1
|
3703
|
sub list_to_named { $_[0]{list_to_named} } |
|
345
|
66
|
|
|
66
|
1
|
291
|
sub oo_trace { $_[0]{oo_trace} } |
|
346
|
94
|
|
|
94
|
1
|
862
|
sub returns_scalar{ $_[0]{returns_scalar} } sub has_returns_scalar{ defined $_[0]{returns_scalar} } |
|
|
16
|
|
|
16
|
0
|
81
|
|
|
347
|
102
|
|
|
102
|
1
|
442
|
sub returns_list { $_[0]{returns_list} } sub has_returns_list { defined $_[0]{returns_list} } |
|
|
16
|
|
|
16
|
0
|
108
|
|
|
348
|
|
|
|
|
|
|
|
|
349
|
53
|
100
|
|
53
|
0
|
455
|
sub method_invocant { $_[0]{method_invocant} = defined( $_[0]{method_invocant} ) ? $_[0]{method_invocant} : 'undef' } |
|
350
|
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
sub can_shortcut { |
|
352
|
|
|
|
|
|
|
return $_[0]{can_shortcut} |
|
353
|
508
|
100
|
|
508
|
1
|
2162
|
if exists $_[0]{can_shortcut}; |
|
354
|
|
|
|
|
|
|
$_[0]{can_shortcut} = !( |
|
355
|
|
|
|
|
|
|
$_[0]->slurpy or |
|
356
|
171
|
|
100
|
|
|
655
|
grep $_->might_supply_new_value, @{ $_[0]->parameters } |
|
357
|
|
|
|
|
|
|
); |
|
358
|
|
|
|
|
|
|
} |
|
359
|
|
|
|
|
|
|
|
|
360
|
|
|
|
|
|
|
sub coderef { |
|
361
|
344
|
|
66
|
344
|
1
|
2544
|
$_[0]{coderef} ||= $_[0]->_build_coderef; |
|
362
|
|
|
|
|
|
|
} |
|
363
|
|
|
|
|
|
|
|
|
364
|
|
|
|
|
|
|
sub _build_coderef { |
|
365
|
344
|
|
|
344
|
|
788
|
my $self = shift; |
|
366
|
344
|
|
66
|
|
|
1384
|
my $coderef = $self->_new_code_accumulator( |
|
367
|
|
|
|
|
|
|
description => $self->description |
|
368
|
|
|
|
|
|
|
|| sprintf( q{parameter validation for '%s::%s'}, $self->package || '', $self->subname || '__ANON__' ) |
|
369
|
|
|
|
|
|
|
); |
|
370
|
|
|
|
|
|
|
|
|
371
|
344
|
|
|
|
|
1852
|
$self->_coderef_start( $coderef ); |
|
372
|
342
|
100
|
|
|
|
998
|
$self->_coderef_head( $coderef ) if $self->has_head; |
|
373
|
342
|
100
|
|
|
|
1054
|
$self->_coderef_tail( $coderef ) if $self->has_tail; |
|
374
|
342
|
|
|
|
|
1796
|
$self->_coderef_parameters( $coderef ); |
|
375
|
341
|
100
|
|
|
|
1087
|
if ( $self->has_slurpy ) { |
|
|
|
100
|
|
|
|
|
|
|
376
|
70
|
|
|
|
|
289
|
$self->_coderef_slurpy( $coderef ); |
|
377
|
|
|
|
|
|
|
} |
|
378
|
|
|
|
|
|
|
elsif ( $self->is_named ) { |
|
379
|
148
|
|
|
|
|
661
|
$self->_coderef_extra_names( $coderef ); |
|
380
|
|
|
|
|
|
|
} |
|
381
|
341
|
|
|
|
|
1780
|
$self->_coderef_end( $coderef ); |
|
382
|
|
|
|
|
|
|
|
|
383
|
341
|
|
|
|
|
1813
|
return $coderef; |
|
384
|
|
|
|
|
|
|
} |
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
sub _coderef_start { |
|
387
|
344
|
|
|
344
|
|
1077
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
388
|
|
|
|
|
|
|
|
|
389
|
344
|
|
|
|
|
1657
|
$coderef->add_line( 'sub {' ); |
|
390
|
344
|
|
|
|
|
1138
|
$coderef->{indent} .= "\t"; |
|
391
|
|
|
|
|
|
|
|
|
392
|
344
|
100
|
|
|
|
1359
|
if ( my $next = $self->next ) { |
|
393
|
67
|
100
|
|
|
|
381
|
if ( is_CodeLike $next ) { |
|
394
|
66
|
|
|
|
|
424
|
$coderef->add_variable( '$__NEXT__', \$next ); |
|
395
|
|
|
|
|
|
|
} |
|
396
|
|
|
|
|
|
|
else { |
|
397
|
1
|
|
|
|
|
6
|
$coderef->add_line( 'my $__NEXT__ = shift;' ); |
|
398
|
1
|
|
|
|
|
5
|
$coderef->add_gap; |
|
399
|
|
|
|
|
|
|
} |
|
400
|
|
|
|
|
|
|
} |
|
401
|
|
|
|
|
|
|
|
|
402
|
344
|
100
|
|
|
|
1522
|
if ( $self->method ) { |
|
403
|
|
|
|
|
|
|
# Passed to parameter defaults |
|
404
|
48
|
|
|
|
|
161
|
$self->{method_invocant} = '$__INVOCANT__'; |
|
405
|
48
|
|
|
|
|
203
|
$coderef->add_line( sprintf 'my %s = $_[0];', $self->method_invocant ); |
|
406
|
48
|
|
|
|
|
222
|
$coderef->add_gap; |
|
407
|
|
|
|
|
|
|
} |
|
408
|
|
|
|
|
|
|
|
|
409
|
344
|
|
|
|
|
1579
|
$self->_coderef_start_extra( $coderef ); |
|
410
|
|
|
|
|
|
|
|
|
411
|
343
|
|
|
|
|
754
|
my $extravars = ''; |
|
412
|
343
|
100
|
|
|
|
1254
|
if ( $self->has_head ) { |
|
413
|
60
|
|
|
|
|
153
|
$extravars .= ', @head'; |
|
414
|
|
|
|
|
|
|
} |
|
415
|
343
|
100
|
|
|
|
1235
|
if ( $self->has_tail ) { |
|
416
|
16
|
|
|
|
|
51
|
$extravars .= ', @tail'; |
|
417
|
|
|
|
|
|
|
} |
|
418
|
|
|
|
|
|
|
|
|
419
|
343
|
100
|
|
|
|
1063
|
if ( $self->is_named ) { |
|
|
|
100
|
|
|
|
|
|
|
420
|
172
|
|
|
|
|
1349
|
$coderef->add_line( "my ( \%out, \%in, \%tmp, \$tmp, \$dtmp$extravars );" ); |
|
421
|
|
|
|
|
|
|
} |
|
422
|
|
|
|
|
|
|
elsif ( $self->can_shortcut ) { |
|
423
|
102
|
|
|
|
|
595
|
$coderef->add_line( "my ( \%tmp, \$tmp$extravars );" ); |
|
424
|
|
|
|
|
|
|
} |
|
425
|
|
|
|
|
|
|
else { |
|
426
|
69
|
|
|
|
|
453
|
$coderef->add_line( "my ( \@out, \%tmp, \$tmp, \$dtmp$extravars );" ); |
|
427
|
|
|
|
|
|
|
} |
|
428
|
|
|
|
|
|
|
|
|
429
|
343
|
100
|
|
|
|
1310
|
if ( $self->has_on_die ) { |
|
430
|
7
|
|
|
|
|
26
|
$coderef->add_variable( '$__ON_DIE__', \ $self->on_die ); |
|
431
|
|
|
|
|
|
|
} |
|
432
|
|
|
|
|
|
|
|
|
433
|
343
|
|
|
|
|
1389
|
$coderef->add_gap; |
|
434
|
|
|
|
|
|
|
|
|
435
|
343
|
|
|
|
|
1536
|
$self->_coderef_check_count( $coderef ); |
|
436
|
|
|
|
|
|
|
|
|
437
|
342
|
|
|
|
|
1410
|
$coderef->add_gap; |
|
438
|
|
|
|
|
|
|
|
|
439
|
342
|
|
|
|
|
783
|
$self; |
|
440
|
|
|
|
|
|
|
} |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
322
|
|
|
sub _coderef_start_extra {} |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
sub _coderef_check_count { |
|
445
|
322
|
|
|
322
|
|
971
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
446
|
|
|
|
|
|
|
|
|
447
|
322
|
|
|
|
|
745
|
my $strictness_test = ''; |
|
448
|
322
|
100
|
100
|
|
|
1009
|
if ( defined $self->strictness and $self->strictness eq 1 ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
449
|
1
|
|
|
|
|
3
|
$strictness_test = ''; |
|
450
|
|
|
|
|
|
|
} |
|
451
|
|
|
|
|
|
|
elsif ( $self->strictness ) { |
|
452
|
3
|
|
|
|
|
8
|
$strictness_test = sprintf '( not %s ) or ', $self->strictness; |
|
453
|
|
|
|
|
|
|
} |
|
454
|
|
|
|
|
|
|
elsif ( $self->has_strictness ) { |
|
455
|
1
|
|
|
|
|
4
|
return $self; |
|
456
|
|
|
|
|
|
|
} |
|
457
|
|
|
|
|
|
|
|
|
458
|
321
|
|
|
|
|
788
|
my $headtail = 0; |
|
459
|
321
|
100
|
|
|
|
964
|
$headtail += @{ $self->head } if $self->has_head; |
|
|
60
|
|
|
|
|
297
|
|
|
460
|
321
|
100
|
|
|
|
1001
|
$headtail += @{ $self->tail } if $self->has_tail; |
|
|
16
|
|
|
|
|
41
|
|
|
461
|
|
|
|
|
|
|
|
|
462
|
321
|
|
|
|
|
962
|
my $is_named = $self->is_named; |
|
463
|
321
|
|
|
|
|
703
|
my $min_args = 0; |
|
464
|
321
|
|
|
|
|
726
|
my $max_args = 0; |
|
465
|
321
|
|
|
|
|
684
|
my $seen_optional = 0; |
|
466
|
321
|
|
|
|
|
638
|
for my $parameter ( @{ $self->parameters } ) { |
|
|
321
|
|
|
|
|
941
|
|
|
467
|
600
|
100
|
|
|
|
2311
|
if ( $parameter->optional ) { |
|
468
|
131
|
|
|
|
|
2635
|
++$seen_optional; |
|
469
|
131
|
|
|
|
|
346
|
++$max_args; |
|
470
|
|
|
|
|
|
|
} |
|
471
|
|
|
|
|
|
|
else { |
|
472
|
469
|
100
|
100
|
|
|
28232
|
$seen_optional and !$is_named and $self->_croak( |
|
473
|
|
|
|
|
|
|
'Non-Optional parameter following Optional parameter', |
|
474
|
|
|
|
|
|
|
); |
|
475
|
468
|
|
|
|
|
902
|
++$max_args; |
|
476
|
468
|
|
|
|
|
1074
|
++$min_args; |
|
477
|
|
|
|
|
|
|
} |
|
478
|
|
|
|
|
|
|
} |
|
479
|
|
|
|
|
|
|
|
|
480
|
320
|
100
|
|
|
|
1224
|
undef $max_args if $self->has_slurpy; |
|
481
|
|
|
|
|
|
|
|
|
482
|
|
|
|
|
|
|
# Note: code related to $max_args_if_hash is currently commented out |
|
483
|
|
|
|
|
|
|
# because it handles this badly: |
|
484
|
|
|
|
|
|
|
# |
|
485
|
|
|
|
|
|
|
# my %opts = ( x => 1, y => 1 ); |
|
486
|
|
|
|
|
|
|
# your_func( %opts, y => 2 ); # override y |
|
487
|
|
|
|
|
|
|
# |
|
488
|
|
|
|
|
|
|
|
|
489
|
320
|
100
|
100
|
|
|
2250
|
if ( $is_named and $self->list_to_named ) { |
|
|
|
100
|
|
|
|
|
|
|
490
|
5
|
|
|
|
|
41
|
require List::Util; |
|
491
|
5
|
|
|
|
|
14
|
my $args_if_hashref = $headtail + 1; |
|
492
|
5
|
100
|
|
|
|
11
|
my $min_args_if_list = $headtail + List::Util::sum( 0, map { $_->optional ? 0 : $_->in_list ? 1 : 2 } @{ $self->parameters } ); |
|
|
10
|
50
|
|
|
|
41
|
|
|
|
5
|
|
|
|
|
27
|
|
|
493
|
5
|
|
|
|
|
34
|
$self->{min_args} = List::Util::min( $args_if_hashref, $min_args_if_list ); |
|
494
|
|
|
|
|
|
|
|
|
495
|
|
|
|
|
|
|
$coderef->add_line( $strictness_test . sprintf( |
|
496
|
|
|
|
|
|
|
"\@_ >= %d\n\tor %s;", |
|
497
|
|
|
|
|
|
|
$self->{min_args}, |
|
498
|
5
|
|
|
|
|
36
|
$self->_make_count_fail( |
|
499
|
|
|
|
|
|
|
coderef => $coderef, |
|
500
|
|
|
|
|
|
|
got => 'scalar( @_ )', |
|
501
|
|
|
|
|
|
|
), |
|
502
|
|
|
|
|
|
|
) ); |
|
503
|
|
|
|
|
|
|
} |
|
504
|
|
|
|
|
|
|
elsif ( $is_named ) { |
|
505
|
167
|
|
|
|
|
461
|
my $args_if_hashref = $headtail + 1; |
|
506
|
167
|
100
|
|
|
|
297
|
my $hashref_index = @{ $self->head || [] }; |
|
|
167
|
|
|
|
|
875
|
|
|
507
|
167
|
|
|
|
|
465
|
my $arity_if_hash = $headtail % 2; |
|
508
|
167
|
|
|
|
|
440
|
my $min_args_if_hash = $headtail + ( 2 * $min_args ); |
|
509
|
|
|
|
|
|
|
#my $max_args_if_hash = defined( $max_args ) |
|
510
|
|
|
|
|
|
|
# ? ( $headtail + ( 2 * $max_args ) ) |
|
511
|
|
|
|
|
|
|
# : undef; |
|
512
|
|
|
|
|
|
|
|
|
513
|
167
|
|
|
|
|
1421
|
require List::Util; |
|
514
|
167
|
|
|
|
|
1090
|
$self->{min_args} = List::Util::min( $args_if_hashref, $min_args_if_hash ); |
|
515
|
|
|
|
|
|
|
#if ( defined $max_args_if_hash ) { |
|
516
|
|
|
|
|
|
|
# $self->{max_args} = List::Util::max( $args_if_hashref, $max_args_if_hash ); |
|
517
|
|
|
|
|
|
|
#} |
|
518
|
|
|
|
|
|
|
|
|
519
|
167
|
|
|
|
|
380
|
my $extra_conditions = ''; |
|
520
|
|
|
|
|
|
|
#if ( defined $max_args_if_hash and $min_args_if_hash==$max_args_if_hash ) { |
|
521
|
|
|
|
|
|
|
# $extra_conditions .= " && \@_ == $min_args_if_hash" |
|
522
|
|
|
|
|
|
|
#} |
|
523
|
|
|
|
|
|
|
#else { |
|
524
|
167
|
100
|
|
|
|
684
|
$extra_conditions .= " && \@_ >= $min_args_if_hash" |
|
525
|
|
|
|
|
|
|
if $min_args_if_hash; |
|
526
|
|
|
|
|
|
|
# $extra_conditions .= " && \@_ <= $max_args_if_hash" |
|
527
|
|
|
|
|
|
|
# if defined $max_args_if_hash; |
|
528
|
|
|
|
|
|
|
#} |
|
529
|
|
|
|
|
|
|
|
|
530
|
167
|
|
|
|
|
1038
|
$coderef->add_line( $strictness_test . sprintf( |
|
531
|
|
|
|
|
|
|
"\@_ == %d && %s\n\tor \@_ %% 2 == %d%s\n\tor %s;", |
|
532
|
|
|
|
|
|
|
$args_if_hashref, |
|
533
|
|
|
|
|
|
|
HashRef->inline_check( sprintf '$_[%d]', $hashref_index ), |
|
534
|
|
|
|
|
|
|
$arity_if_hash, |
|
535
|
|
|
|
|
|
|
$extra_conditions, |
|
536
|
|
|
|
|
|
|
$self->_make_count_fail( |
|
537
|
|
|
|
|
|
|
coderef => $coderef, |
|
538
|
|
|
|
|
|
|
got => 'scalar( @_ )', |
|
539
|
|
|
|
|
|
|
), |
|
540
|
|
|
|
|
|
|
) ); |
|
541
|
|
|
|
|
|
|
} |
|
542
|
|
|
|
|
|
|
else { |
|
543
|
148
|
|
|
|
|
376
|
$min_args += $headtail; |
|
544
|
148
|
100
|
|
|
|
548
|
$max_args += $headtail if defined $max_args; |
|
545
|
|
|
|
|
|
|
|
|
546
|
148
|
|
|
|
|
506
|
$self->{min_args} = $min_args; |
|
547
|
148
|
|
|
|
|
436
|
$self->{max_args} = $max_args; |
|
548
|
|
|
|
|
|
|
|
|
549
|
148
|
100
|
100
|
|
|
1145
|
if ( defined $max_args and $min_args == $max_args ) { |
|
|
|
100
|
100
|
|
|
|
|
|
550
|
81
|
|
|
|
|
445
|
$coderef->add_line( $strictness_test . sprintf( |
|
551
|
|
|
|
|
|
|
"\@_ == %d\n\tor %s;", |
|
552
|
|
|
|
|
|
|
$min_args, |
|
553
|
|
|
|
|
|
|
$self->_make_count_fail( |
|
554
|
|
|
|
|
|
|
coderef => $coderef, |
|
555
|
|
|
|
|
|
|
minimum => $min_args, |
|
556
|
|
|
|
|
|
|
maximum => $max_args, |
|
557
|
|
|
|
|
|
|
got => 'scalar( @_ )', |
|
558
|
|
|
|
|
|
|
), |
|
559
|
|
|
|
|
|
|
) ); |
|
560
|
|
|
|
|
|
|
} |
|
561
|
|
|
|
|
|
|
elsif ( $min_args and defined $max_args ) { |
|
562
|
11
|
|
|
|
|
70
|
$coderef->add_line( $strictness_test . sprintf( |
|
563
|
|
|
|
|
|
|
"\@_ >= %d && \@_ <= %d\n\tor %s;", |
|
564
|
|
|
|
|
|
|
$min_args, |
|
565
|
|
|
|
|
|
|
$max_args, |
|
566
|
|
|
|
|
|
|
$self->_make_count_fail( |
|
567
|
|
|
|
|
|
|
coderef => $coderef, |
|
568
|
|
|
|
|
|
|
minimum => $min_args, |
|
569
|
|
|
|
|
|
|
maximum => $max_args, |
|
570
|
|
|
|
|
|
|
got => 'scalar( @_ )', |
|
571
|
|
|
|
|
|
|
), |
|
572
|
|
|
|
|
|
|
) ); |
|
573
|
|
|
|
|
|
|
} |
|
574
|
|
|
|
|
|
|
else { |
|
575
|
56
|
|
100
|
|
|
527
|
$coderef->add_line( $strictness_test . sprintf( |
|
|
|
|
100
|
|
|
|
|
|
576
|
|
|
|
|
|
|
"\@_ >= %d\n\tor %s;", |
|
577
|
|
|
|
|
|
|
$min_args || 0, |
|
578
|
|
|
|
|
|
|
$self->_make_count_fail( |
|
579
|
|
|
|
|
|
|
coderef => $coderef, |
|
580
|
|
|
|
|
|
|
minimum => $min_args || 0, |
|
581
|
|
|
|
|
|
|
got => 'scalar( @_ )', |
|
582
|
|
|
|
|
|
|
), |
|
583
|
|
|
|
|
|
|
) ); |
|
584
|
|
|
|
|
|
|
} |
|
585
|
|
|
|
|
|
|
} |
|
586
|
|
|
|
|
|
|
} |
|
587
|
|
|
|
|
|
|
|
|
588
|
|
|
|
|
|
|
sub _coderef_head { |
|
589
|
60
|
|
|
60
|
|
184
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
590
|
60
|
50
|
|
|
|
211
|
$self->has_head or return; |
|
591
|
|
|
|
|
|
|
|
|
592
|
60
|
|
|
|
|
140
|
my $size = @{ $self->head }; |
|
|
60
|
|
|
|
|
177
|
|
|
593
|
60
|
|
|
|
|
350
|
$coderef->add_line( sprintf( |
|
594
|
|
|
|
|
|
|
'@head = splice( @_, 0, %d );', |
|
595
|
|
|
|
|
|
|
$size, |
|
596
|
|
|
|
|
|
|
) ); |
|
597
|
|
|
|
|
|
|
|
|
598
|
60
|
|
|
|
|
207
|
$coderef->add_gap; |
|
599
|
|
|
|
|
|
|
|
|
600
|
60
|
|
|
|
|
114
|
my $i = 0; |
|
601
|
60
|
|
|
|
|
144
|
for my $parameter ( @{ $self->head } ) { |
|
|
60
|
|
|
|
|
172
|
|
|
602
|
68
|
|
|
|
|
724
|
$parameter->_make_code( |
|
603
|
|
|
|
|
|
|
signature => $self, |
|
604
|
|
|
|
|
|
|
coderef => $coderef, |
|
605
|
|
|
|
|
|
|
input_slot => sprintf( '$head[%d]', $i ), |
|
606
|
|
|
|
|
|
|
input_var => '@head', |
|
607
|
|
|
|
|
|
|
output_slot => sprintf( '$head[%d]', $i ), |
|
608
|
|
|
|
|
|
|
output_var => undef, |
|
609
|
|
|
|
|
|
|
index => $i, |
|
610
|
|
|
|
|
|
|
type => 'head', |
|
611
|
|
|
|
|
|
|
display_var => sprintf( '$_[%d]', $i ), |
|
612
|
|
|
|
|
|
|
); |
|
613
|
68
|
|
|
|
|
243
|
++$i; |
|
614
|
|
|
|
|
|
|
} |
|
615
|
|
|
|
|
|
|
|
|
616
|
60
|
|
|
|
|
151
|
$self; |
|
617
|
|
|
|
|
|
|
} |
|
618
|
|
|
|
|
|
|
|
|
619
|
|
|
|
|
|
|
sub _coderef_tail { |
|
620
|
16
|
|
|
16
|
|
51
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
621
|
16
|
50
|
|
|
|
38
|
$self->has_tail or return; |
|
622
|
|
|
|
|
|
|
|
|
623
|
16
|
|
|
|
|
33
|
my $size = @{ $self->tail }; |
|
|
16
|
|
|
|
|
39
|
|
|
624
|
16
|
|
|
|
|
115
|
$coderef->add_line( sprintf( |
|
625
|
|
|
|
|
|
|
'@tail = splice( @_, -%d );', |
|
626
|
|
|
|
|
|
|
$size, |
|
627
|
|
|
|
|
|
|
) ); |
|
628
|
|
|
|
|
|
|
|
|
629
|
16
|
|
|
|
|
91
|
$coderef->add_gap; |
|
630
|
|
|
|
|
|
|
|
|
631
|
16
|
|
|
|
|
29
|
my $i = 0; |
|
632
|
16
|
|
|
|
|
27
|
my $n = @{ $self->tail }; |
|
|
16
|
|
|
|
|
42
|
|
|
633
|
16
|
|
|
|
|
31
|
for my $parameter ( @{ $self->tail } ) { |
|
|
16
|
|
|
|
|
43
|
|
|
634
|
42
|
|
|
|
|
325
|
$parameter->_make_code( |
|
635
|
|
|
|
|
|
|
signature => $self, |
|
636
|
|
|
|
|
|
|
coderef => $coderef, |
|
637
|
|
|
|
|
|
|
input_slot => sprintf( '$tail[%d]', $i ), |
|
638
|
|
|
|
|
|
|
input_var => '@tail', |
|
639
|
|
|
|
|
|
|
output_slot => sprintf( '$tail[%d]', $i ), |
|
640
|
|
|
|
|
|
|
output_var => undef, |
|
641
|
|
|
|
|
|
|
index => $i, |
|
642
|
|
|
|
|
|
|
type => 'tail', |
|
643
|
|
|
|
|
|
|
display_var => sprintf( '$_[-%d]', $n - $i ), |
|
644
|
|
|
|
|
|
|
); |
|
645
|
42
|
|
|
|
|
164
|
++$i; |
|
646
|
|
|
|
|
|
|
} |
|
647
|
|
|
|
|
|
|
|
|
648
|
16
|
|
|
|
|
43
|
$self; |
|
649
|
|
|
|
|
|
|
} |
|
650
|
|
|
|
|
|
|
|
|
651
|
|
|
|
|
|
|
sub _coderef_parameters { |
|
652
|
342
|
|
|
342
|
|
1023
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
653
|
|
|
|
|
|
|
|
|
654
|
342
|
100
|
|
|
|
1118
|
if ( $self->is_named ) { |
|
655
|
|
|
|
|
|
|
|
|
656
|
172
|
100
|
|
|
|
533
|
if ( $self->list_to_named ) { |
|
657
|
5
|
|
|
|
|
38
|
require Type::Tiny::Enum; |
|
658
|
5
|
|
|
|
|
15
|
my $Keys = Type::Tiny::Enum->new( values => [ map { $_->name, $_->_all_aliases($self) } @{ $self->parameters } ] ); |
|
|
10
|
|
|
|
|
33
|
|
|
|
5
|
|
|
|
|
14
|
|
|
659
|
5
|
|
|
|
|
40
|
$coderef->addf( 'my @positional;' ); |
|
660
|
5
|
|
|
|
|
21
|
$coderef->addf( '{' ); |
|
661
|
5
|
|
|
|
|
21
|
$coderef->increase_indent; |
|
662
|
5
|
|
|
|
|
16
|
$coderef->addf( 'last if ( @_ == 0 );' ); |
|
663
|
5
|
|
|
|
|
30
|
$coderef->addf( 'last if ( @_ == 1 and %s );', HashRef->inline_check( '$_[0]' ) ); |
|
664
|
5
|
|
|
|
|
31
|
$coderef->addf( 'last if ( @_ %% 2 == 0 and %s );', $Keys->inline_check( '$_[0]' ) ); |
|
665
|
5
|
|
|
|
|
23
|
$coderef->addf( 'push @positional, shift @_;' ); |
|
666
|
5
|
|
|
|
|
21
|
$coderef->addf( 'redo;' ); |
|
667
|
5
|
|
|
|
|
24
|
$coderef->decrease_indent; |
|
668
|
5
|
|
|
|
|
17
|
$coderef->addf( '}' ); |
|
669
|
5
|
|
|
|
|
16
|
$coderef->add_gap; |
|
670
|
|
|
|
|
|
|
} |
|
671
|
|
|
|
|
|
|
|
|
672
|
172
|
|
|
|
|
815
|
$coderef->add_line( sprintf( |
|
673
|
|
|
|
|
|
|
'%%in = ( @_ == 1 and %s ) ? %%{ $_[0] } : @_;', |
|
674
|
|
|
|
|
|
|
HashRef->inline_check( '$_[0]' ), |
|
675
|
|
|
|
|
|
|
) ); |
|
676
|
172
|
|
|
|
|
713
|
$coderef->add_gap; |
|
677
|
|
|
|
|
|
|
|
|
678
|
172
|
|
|
|
|
315
|
for my $parameter ( @{ $self->parameters } ) { |
|
|
172
|
|
|
|
|
544
|
|
|
679
|
391
|
|
|
|
|
13075
|
my $qname = B::perlstring( $parameter->name ); |
|
680
|
391
|
|
|
|
|
1860
|
$parameter->_make_code( |
|
681
|
|
|
|
|
|
|
signature => $self, |
|
682
|
|
|
|
|
|
|
coderef => $coderef, |
|
683
|
|
|
|
|
|
|
is_named => 1, |
|
684
|
|
|
|
|
|
|
input_slot => sprintf( '$in{%s}', $qname ), |
|
685
|
|
|
|
|
|
|
output_slot => sprintf( '$out{%s}', $qname ), |
|
686
|
|
|
|
|
|
|
display_var => sprintf( '$_{%s}', $qname ), |
|
687
|
|
|
|
|
|
|
key => $parameter->name, |
|
688
|
|
|
|
|
|
|
type => 'named_arg', |
|
689
|
|
|
|
|
|
|
); |
|
690
|
|
|
|
|
|
|
} |
|
691
|
|
|
|
|
|
|
|
|
692
|
172
|
100
|
|
|
|
1572
|
if ( $self->list_to_named ) { |
|
693
|
5
|
|
|
|
|
21
|
$coderef->add_line( sprintf( |
|
694
|
|
|
|
|
|
|
'@positional and %s;', |
|
695
|
|
|
|
|
|
|
$self->_make_general_fail( |
|
696
|
|
|
|
|
|
|
coderef => $coderef, |
|
697
|
|
|
|
|
|
|
message => q{'Superfluous positional arguments'}, |
|
698
|
|
|
|
|
|
|
), |
|
699
|
|
|
|
|
|
|
) ); |
|
700
|
|
|
|
|
|
|
} |
|
701
|
|
|
|
|
|
|
} |
|
702
|
|
|
|
|
|
|
else { |
|
703
|
170
|
|
|
|
|
742
|
my $can_shortcut = $self->can_shortcut; |
|
704
|
170
|
100
|
|
|
|
500
|
my $head_size = $self->has_head ? @{ $self->head } : 0; |
|
|
36
|
|
|
|
|
114
|
|
|
705
|
|
|
|
|
|
|
|
|
706
|
170
|
|
|
|
|
371
|
my $i = 0; |
|
707
|
170
|
|
|
|
|
382
|
for my $parameter ( @{ $self->parameters } ) { |
|
|
170
|
|
|
|
|
453
|
|
|
708
|
209
|
100
|
|
|
|
2390
|
$parameter->_make_code( |
|
|
|
100
|
|
|
|
|
|
|
709
|
|
|
|
|
|
|
signature => $self, |
|
710
|
|
|
|
|
|
|
coderef => $coderef, |
|
711
|
|
|
|
|
|
|
is_named => 0, |
|
712
|
|
|
|
|
|
|
input_slot => sprintf( '$_[%d]', $i ), |
|
713
|
|
|
|
|
|
|
input_var => '@_', |
|
714
|
|
|
|
|
|
|
output_slot => ( $can_shortcut ? undef : sprintf( '$_[%d]', $i ) ), |
|
715
|
|
|
|
|
|
|
output_var => ( $can_shortcut ? undef : '@out' ), |
|
716
|
|
|
|
|
|
|
index => $i, |
|
717
|
|
|
|
|
|
|
display_var => sprintf( '$_[%d]', $i + $head_size ), |
|
718
|
|
|
|
|
|
|
); |
|
719
|
208
|
|
|
|
|
806
|
++$i; |
|
720
|
|
|
|
|
|
|
} |
|
721
|
|
|
|
|
|
|
} |
|
722
|
|
|
|
|
|
|
} |
|
723
|
|
|
|
|
|
|
|
|
724
|
|
|
|
|
|
|
sub _coderef_slurpy { |
|
725
|
70
|
|
|
70
|
|
240
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
726
|
70
|
50
|
|
|
|
195
|
return unless $self->has_slurpy; |
|
727
|
|
|
|
|
|
|
|
|
728
|
70
|
|
|
|
|
210
|
my $parameter = $self->slurpy; |
|
729
|
70
|
|
|
|
|
282
|
my $constraint = $parameter->type; |
|
730
|
70
|
|
|
|
|
717
|
my $slurp_into = $constraint->my_slurp_into; |
|
731
|
70
|
|
|
|
|
648
|
my $real_type = $constraint->my_unslurpy; |
|
732
|
|
|
|
|
|
|
|
|
733
|
70
|
100
|
66
|
|
|
302
|
if ( $self->is_named ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
734
|
24
|
|
|
|
|
106
|
$coderef->add_line( 'my $SLURPY = \\%in;' ); |
|
735
|
|
|
|
|
|
|
} |
|
736
|
|
|
|
|
|
|
elsif ( $real_type and $real_type->{uniq} == Any->{uniq} ) { |
|
737
|
|
|
|
|
|
|
|
|
738
|
|
|
|
|
|
|
$coderef->add_line( sprintf( |
|
739
|
|
|
|
|
|
|
'my $SLURPY = [ @_[ %d .. $#_ ] ];', |
|
740
|
1
|
|
|
|
|
8
|
scalar( @{ $self->parameters } ), |
|
|
1
|
|
|
|
|
3
|
|
|
741
|
|
|
|
|
|
|
) ); |
|
742
|
|
|
|
|
|
|
} |
|
743
|
|
|
|
|
|
|
elsif ( $slurp_into eq 'HASH' ) { |
|
744
|
|
|
|
|
|
|
|
|
745
|
29
|
|
|
|
|
253
|
my $index = scalar( @{ $self->parameters } ); |
|
|
29
|
|
|
|
|
91
|
|
|
746
|
29
|
|
33
|
|
|
118
|
$coderef->add_line( sprintf( |
|
747
|
|
|
|
|
|
|
'my $SLURPY = ( $#_ == %d and ( %s ) ) ? { %%{ $_[%d] } } : ( ( $#_ - %d ) %% 2 ) ? { @_[ %d .. $#_ ] } : %s;', |
|
748
|
|
|
|
|
|
|
$index, |
|
749
|
|
|
|
|
|
|
HashRef->inline_check("\$_[$index]"), |
|
750
|
|
|
|
|
|
|
$index, |
|
751
|
|
|
|
|
|
|
$index, |
|
752
|
|
|
|
|
|
|
$index, |
|
753
|
|
|
|
|
|
|
$self->_make_general_fail( |
|
754
|
|
|
|
|
|
|
coderef => $coderef, |
|
755
|
|
|
|
|
|
|
message => sprintf( |
|
756
|
|
|
|
|
|
|
qq{sprintf( "Odd number of elements in %%s", %s )}, |
|
757
|
|
|
|
|
|
|
B::perlstring( ( $real_type or $constraint )->display_name ), |
|
758
|
|
|
|
|
|
|
), |
|
759
|
|
|
|
|
|
|
), |
|
760
|
|
|
|
|
|
|
) ); |
|
761
|
|
|
|
|
|
|
} |
|
762
|
|
|
|
|
|
|
else { |
|
763
|
|
|
|
|
|
|
|
|
764
|
|
|
|
|
|
|
$coderef->add_line( sprintf( |
|
765
|
|
|
|
|
|
|
'my $SLURPY = [ @_[ %d .. $#_ ] ];', |
|
766
|
16
|
|
|
|
|
152
|
scalar( @{ $self->parameters } ), |
|
|
16
|
|
|
|
|
59
|
|
|
767
|
|
|
|
|
|
|
) ); |
|
768
|
|
|
|
|
|
|
} |
|
769
|
|
|
|
|
|
|
|
|
770
|
70
|
|
|
|
|
312
|
$coderef->add_gap; |
|
771
|
|
|
|
|
|
|
|
|
772
|
70
|
100
|
|
|
|
248
|
$parameter->_make_code( |
|
773
|
|
|
|
|
|
|
signature => $self, |
|
774
|
|
|
|
|
|
|
coderef => $coderef, |
|
775
|
|
|
|
|
|
|
input_slot => '$SLURPY', |
|
776
|
|
|
|
|
|
|
display_var => '$SLURPY', |
|
777
|
|
|
|
|
|
|
index => 0, |
|
778
|
|
|
|
|
|
|
is_slurpy => 1, |
|
779
|
|
|
|
|
|
|
$self->is_named |
|
780
|
|
|
|
|
|
|
? ( output_slot => sprintf( '$out{%s}', B::perlstring( $parameter->name ) ) ) |
|
781
|
|
|
|
|
|
|
: ( output_var => '@out' ) |
|
782
|
|
|
|
|
|
|
); |
|
783
|
|
|
|
|
|
|
} |
|
784
|
|
|
|
|
|
|
|
|
785
|
|
|
|
|
|
|
sub _coderef_extra_names { |
|
786
|
148
|
|
|
148
|
|
449
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
787
|
|
|
|
|
|
|
|
|
788
|
148
|
50
|
33
|
|
|
426
|
return $self if $self->has_strictness && ! $self->strictness; |
|
789
|
|
|
|
|
|
|
|
|
790
|
148
|
|
|
|
|
11199
|
require Type::Utils; |
|
791
|
148
|
|
|
|
|
470
|
my $english_list = 'Type::Utils::english_list'; |
|
792
|
148
|
100
|
|
|
|
466
|
if ( $Type::Tiny::AvoidCallbacks ) { |
|
793
|
8
|
|
|
|
|
23
|
$english_list = 'join q{, } => '; |
|
794
|
|
|
|
|
|
|
} |
|
795
|
|
|
|
|
|
|
|
|
796
|
148
|
|
|
|
|
634
|
$coderef->add_line( '# Unrecognized parameters' ); |
|
797
|
148
|
50
|
33
|
|
|
742
|
$coderef->add_line( sprintf( |
|
798
|
|
|
|
|
|
|
'%s if %skeys %%in;', |
|
799
|
|
|
|
|
|
|
$self->_make_general_fail( |
|
800
|
|
|
|
|
|
|
coderef => $coderef, |
|
801
|
|
|
|
|
|
|
message => "sprintf( q{Unrecognized parameter%s: %s}, keys( %in ) > 1 ? q{s} : q{}, $english_list( sort keys %in ) )", |
|
802
|
|
|
|
|
|
|
), |
|
803
|
|
|
|
|
|
|
defined( $self->strictness ) && $self->strictness ne 1 |
|
804
|
|
|
|
|
|
|
? sprintf( '%s && ', $self->strictness ) |
|
805
|
|
|
|
|
|
|
: '' |
|
806
|
|
|
|
|
|
|
) ); |
|
807
|
148
|
|
|
|
|
479
|
$coderef->add_gap; |
|
808
|
|
|
|
|
|
|
} |
|
809
|
|
|
|
|
|
|
|
|
810
|
|
|
|
|
|
|
sub _coderef_end { |
|
811
|
341
|
|
|
341
|
|
951
|
my ( $self, $coderef ) = ( shift, @_ ); |
|
812
|
|
|
|
|
|
|
|
|
813
|
341
|
100
|
100
|
|
|
1601
|
if ( $self->{_is_signature_for} and $self->next ) { |
|
814
|
47
|
100
|
|
|
|
212
|
$coderef->add_variable( '$return_check_for_scalar', \ $self->returns_scalar->compiled_check ) |
|
815
|
|
|
|
|
|
|
if $self->has_returns_scalar; |
|
816
|
47
|
100
|
|
|
|
220
|
$coderef->add_variable( '$return_check_for_list', \ $self->returns_list->compiled_check ) |
|
817
|
|
|
|
|
|
|
if $self->has_returns_list; |
|
818
|
|
|
|
|
|
|
} |
|
819
|
|
|
|
|
|
|
|
|
820
|
341
|
100
|
100
|
|
|
1202
|
if ( $self->bless and $self->oo_trace ) { |
|
821
|
44
|
|
|
|
|
144
|
my $package = $self->package; |
|
822
|
44
|
|
|
|
|
133
|
my $subname = $self->subname; |
|
823
|
44
|
50
|
33
|
|
|
240
|
if ( defined $package and defined $subname ) { |
|
824
|
44
|
|
|
|
|
488
|
$coderef->add_line( sprintf( |
|
825
|
|
|
|
|
|
|
'$out{"~~caller"} = %s;', |
|
826
|
|
|
|
|
|
|
B::perlstring( "$package\::$subname" ), |
|
827
|
|
|
|
|
|
|
) ); |
|
828
|
44
|
|
|
|
|
135
|
$coderef->add_gap; |
|
829
|
|
|
|
|
|
|
} |
|
830
|
|
|
|
|
|
|
} |
|
831
|
|
|
|
|
|
|
|
|
832
|
341
|
|
|
|
|
1361
|
$self->_coderef_end_extra( $coderef ); |
|
833
|
341
|
|
|
|
|
1610
|
$coderef->add_line( $self->_make_return_expression( is_early => 0, allow_full_statements => 1 ) . ';' ); |
|
834
|
341
|
|
|
|
|
2405
|
$coderef->{indent} =~ s/\t$//; |
|
835
|
341
|
|
|
|
|
1263
|
$coderef->add_line( '}' ); |
|
836
|
|
|
|
|
|
|
|
|
837
|
341
|
|
|
|
|
745
|
$self; |
|
838
|
|
|
|
|
|
|
} |
|
839
|
|
|
|
|
|
|
|
|
840
|
|
|
|
320
|
|
|
sub _coderef_end_extra {} |
|
841
|
|
|
|
|
|
|
|
|
842
|
|
|
|
|
|
|
sub _make_return_list { |
|
843
|
339
|
|
|
339
|
|
695
|
my $self = shift; |
|
844
|
|
|
|
|
|
|
|
|
845
|
339
|
|
|
|
|
682
|
my @return_list; |
|
846
|
339
|
100
|
|
|
|
1347
|
if ( $self->has_head ) { |
|
847
|
60
|
|
|
|
|
188
|
push @return_list, '@head'; |
|
848
|
|
|
|
|
|
|
} |
|
849
|
|
|
|
|
|
|
|
|
850
|
339
|
100
|
|
|
|
1085
|
if ( not $self->is_named ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
851
|
167
|
100
|
|
|
|
591
|
push @return_list, $self->can_shortcut ? '@_' : '@out'; |
|
852
|
|
|
|
|
|
|
} |
|
853
|
|
|
|
|
|
|
elsif ( $self->named_to_list ) { |
|
854
|
|
|
|
|
|
|
push @return_list, map( |
|
855
|
|
|
|
|
|
|
sprintf( '$out{%s}', B::perlstring( $_ ) ), |
|
856
|
14
|
|
|
|
|
35
|
@{ $self->named_to_list }, |
|
|
14
|
|
|
|
|
41
|
|
|
857
|
|
|
|
|
|
|
); |
|
858
|
|
|
|
|
|
|
} |
|
859
|
|
|
|
|
|
|
elsif ( $self->class ) { |
|
860
|
24
|
|
100
|
|
|
81
|
push @return_list, sprintf( |
|
861
|
|
|
|
|
|
|
'%s->%s( \%%out )', |
|
862
|
|
|
|
|
|
|
B::perlstring( $self->class ), |
|
863
|
|
|
|
|
|
|
$self->constructor || 'new', |
|
864
|
|
|
|
|
|
|
); |
|
865
|
|
|
|
|
|
|
} |
|
866
|
|
|
|
|
|
|
elsif ( $self->bless ) { |
|
867
|
55
|
|
|
|
|
149
|
push @return_list, sprintf( |
|
868
|
|
|
|
|
|
|
'bless( \%%out, %s )', |
|
869
|
|
|
|
|
|
|
B::perlstring( $self->bless ), |
|
870
|
|
|
|
|
|
|
); |
|
871
|
|
|
|
|
|
|
} |
|
872
|
|
|
|
|
|
|
else { |
|
873
|
79
|
|
|
|
|
256
|
push @return_list, '\%out'; |
|
874
|
|
|
|
|
|
|
} |
|
875
|
|
|
|
|
|
|
|
|
876
|
339
|
100
|
|
|
|
1051
|
if ( $self->has_tail ) { |
|
877
|
16
|
|
|
|
|
42
|
push @return_list, '@tail'; |
|
878
|
|
|
|
|
|
|
} |
|
879
|
|
|
|
|
|
|
|
|
880
|
339
|
|
|
|
|
1341
|
return @return_list; |
|
881
|
|
|
|
|
|
|
} |
|
882
|
|
|
|
|
|
|
|
|
883
|
|
|
|
|
|
|
sub _make_return_expression { |
|
884
|
360
|
|
|
360
|
|
1616
|
my ( $self, %args ) = @_; |
|
885
|
|
|
|
|
|
|
|
|
886
|
360
|
|
|
|
|
1448
|
my $list = join q{, }, $self->_make_return_list; |
|
887
|
|
|
|
|
|
|
|
|
888
|
360
|
100
|
66
|
|
|
1083
|
if ( $self->next ) { |
|
|
|
100
|
|
|
|
|
|
|
889
|
67
|
100
|
66
|
|
|
640
|
if ( $self->{_is_signature_for} and ( $self->has_returns_list or $self->has_returns_scalar ) ) { |
|
|
|
100
|
100
|
|
|
|
|
|
|
|
50
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
890
|
8
|
|
|
|
|
21
|
my $call = sprintf '$__NEXT__->( %s )', $list; |
|
891
|
8
|
|
|
|
|
37
|
return $self->_make_typed_return_expression( $call ); |
|
892
|
|
|
|
|
|
|
} |
|
893
|
|
|
|
|
|
|
elsif ( $list eq '@_' ) { |
|
894
|
8
|
|
|
|
|
71
|
return sprintf 'goto( $__NEXT__ )'; |
|
895
|
|
|
|
|
|
|
} |
|
896
|
|
|
|
|
|
|
elsif ( $args{allow_full_statements} and not ( $args{is_early} or not exists $args{is_early} ) ) { |
|
897
|
|
|
|
|
|
|
# We are allowed to return full statements, not |
|
898
|
|
|
|
|
|
|
# forced to use do {...} to make an expression. |
|
899
|
51
|
|
|
|
|
409
|
return sprintf '@_ = ( %s ); goto $__NEXT__', $list; |
|
900
|
|
|
|
|
|
|
} |
|
901
|
|
|
|
|
|
|
else { |
|
902
|
0
|
|
|
|
|
0
|
return sprintf 'do { @_ = ( %s ); goto $__NEXT__ }', $list; |
|
903
|
|
|
|
|
|
|
} |
|
904
|
|
|
|
|
|
|
} |
|
905
|
|
|
|
|
|
|
elsif ( $args{is_early} or not exists $args{is_early} ) { |
|
906
|
19
|
|
|
|
|
123
|
return sprintf 'return( %s )', $list; |
|
907
|
|
|
|
|
|
|
} |
|
908
|
|
|
|
|
|
|
else { |
|
909
|
274
|
|
|
|
|
1822
|
return sprintf '( %s )', $list; |
|
910
|
|
|
|
|
|
|
} |
|
911
|
|
|
|
|
|
|
} |
|
912
|
|
|
|
|
|
|
|
|
913
|
|
|
|
|
|
|
sub _make_typed_return_expression { |
|
914
|
8
|
|
|
8
|
|
33
|
my ( $self, $expr ) = @_; |
|
915
|
|
|
|
|
|
|
|
|
916
|
8
|
50
|
|
|
|
27
|
return sprintf 'wantarray ? %s : defined( wantarray ) ? %s : do { %s; undef; }', |
|
|
|
50
|
|
|
|
|
|
|
917
|
|
|
|
|
|
|
$self->has_returns_list ? $self->_make_typed_list_return_expression( $expr, $self->returns_list ) : $expr, |
|
918
|
|
|
|
|
|
|
$self->has_returns_scalar ? $self->_make_typed_scalar_return_expression( $expr, $self->returns_scalar ) : $expr, |
|
919
|
|
|
|
|
|
|
$expr; |
|
920
|
|
|
|
|
|
|
} |
|
921
|
|
|
|
|
|
|
|
|
922
|
|
|
|
|
|
|
sub _make_typed_scalar_return_expression { |
|
923
|
8
|
|
|
8
|
|
29
|
my ( $self, $expr, $constraint ) = @_; |
|
924
|
|
|
|
|
|
|
|
|
925
|
8
|
50
|
|
|
|
42
|
if ( $constraint->{uniq} == Any->{uniq} ) { |
|
|
|
100
|
|
|
|
|
|
|
926
|
0
|
|
|
|
|
0
|
return $expr; |
|
927
|
|
|
|
|
|
|
} |
|
928
|
|
|
|
|
|
|
elsif ( $constraint->can_be_inlined ) { |
|
929
|
7
|
|
|
|
|
28
|
return sprintf 'do { my $__RETURN__ = %s; ( %s ) ? $__RETURN__ : %s }', |
|
930
|
|
|
|
|
|
|
$expr, |
|
931
|
|
|
|
|
|
|
$constraint->inline_check( '$__RETURN__' ), |
|
932
|
|
|
|
|
|
|
$self->_make_constraint_fail( constraint => $constraint, varname => '$__RETURN__' ); |
|
933
|
|
|
|
|
|
|
} |
|
934
|
|
|
|
|
|
|
else { |
|
935
|
1
|
|
|
|
|
4
|
return sprintf 'do { my $__RETURN__ = %s; $return_check_for_scalar->( $__RETURN__ ) ? $__RETURN__ : %s }', |
|
936
|
|
|
|
|
|
|
$expr, |
|
937
|
|
|
|
|
|
|
$self->_make_constraint_fail( constraint => $constraint, varname => '$__RETURN__' ); |
|
938
|
|
|
|
|
|
|
} |
|
939
|
|
|
|
|
|
|
} |
|
940
|
|
|
|
|
|
|
|
|
941
|
|
|
|
|
|
|
sub _make_typed_list_return_expression { |
|
942
|
8
|
|
|
8
|
|
29
|
my ( $self, $expr, $constraint ) = @_; |
|
943
|
|
|
|
|
|
|
|
|
944
|
8
|
|
|
|
|
46
|
my $slurp_into = Slurpy->of( $constraint )->my_slurp_into; |
|
945
|
8
|
100
|
|
|
|
63
|
my $varname = $slurp_into eq 'HASH' ? '%__RETURN__' : '@__RETURN__'; |
|
946
|
|
|
|
|
|
|
|
|
947
|
8
|
50
|
|
|
|
59
|
if ( $constraint->{uniq} == Any->{uniq} ) { |
|
|
|
100
|
|
|
|
|
|
|
948
|
0
|
|
|
|
|
0
|
return $expr; |
|
949
|
|
|
|
|
|
|
} |
|
950
|
|
|
|
|
|
|
elsif ( $constraint->can_be_inlined ) { |
|
951
|
7
|
|
|
|
|
34
|
return sprintf 'do { my %s = %s; my $__RETURN__ = \ %s; ( %s ) ? %s : %s }', |
|
952
|
|
|
|
|
|
|
$varname, |
|
953
|
|
|
|
|
|
|
$expr, |
|
954
|
|
|
|
|
|
|
$varname, |
|
955
|
|
|
|
|
|
|
$constraint->inline_check( '$__RETURN__' ), |
|
956
|
|
|
|
|
|
|
$varname, |
|
957
|
|
|
|
|
|
|
$self->_make_constraint_fail( constraint => $constraint, varname => '$__RETURN__', display_var => "\\$varname" ); |
|
958
|
|
|
|
|
|
|
} |
|
959
|
|
|
|
|
|
|
else { |
|
960
|
1
|
|
|
|
|
9
|
return sprintf 'do { my %s = %s; my $__RETURN__ = \ %s; $return_check_for_list->( $__RETURN__ ) ? %s : %s }', |
|
961
|
|
|
|
|
|
|
$varname, |
|
962
|
|
|
|
|
|
|
$expr, |
|
963
|
|
|
|
|
|
|
$varname, |
|
964
|
|
|
|
|
|
|
$varname, |
|
965
|
|
|
|
|
|
|
$self->_make_constraint_fail( constraint => $constraint, varname => '$__RETURN__', display_var => "\\$varname" ); |
|
966
|
|
|
|
|
|
|
} |
|
967
|
|
|
|
|
|
|
} |
|
968
|
|
|
|
|
|
|
|
|
969
|
|
|
|
|
|
|
sub _make_general_fail { |
|
970
|
519
|
|
|
519
|
|
2039
|
my ( $self, %args ) = ( shift, @_ ); |
|
971
|
|
|
|
|
|
|
|
|
972
|
|
|
|
|
|
|
return sprintf( |
|
973
|
|
|
|
|
|
|
$self->has_on_die |
|
974
|
|
|
|
|
|
|
? q{return( "Error::TypeTiny"->throw_cb( $__ON_DIE__, message => %s ) )} |
|
975
|
|
|
|
|
|
|
: q{"Error::TypeTiny"->throw( message => %s )}, |
|
976
|
|
|
|
|
|
|
$args{message}, |
|
977
|
519
|
100
|
|
|
|
1346
|
); |
|
978
|
|
|
|
|
|
|
} |
|
979
|
|
|
|
|
|
|
|
|
980
|
|
|
|
|
|
|
sub _make_constraint_fail { |
|
981
|
777
|
|
|
777
|
|
5096
|
my ( $self, %args ) = ( shift, @_ ); |
|
982
|
|
|
|
|
|
|
|
|
983
|
|
|
|
|
|
|
return sprintf( |
|
984
|
|
|
|
|
|
|
$self->has_on_die |
|
985
|
|
|
|
|
|
|
? q{return( Type::Tiny::_failed_check( %d, %s, %s, varname => %s, on_die => $__ON_DIE__ ) )} |
|
986
|
|
|
|
|
|
|
: q{Type::Tiny::_failed_check( %d, %s, %s, varname => %s )}, |
|
987
|
|
|
|
|
|
|
$args{constraint}{uniq}, |
|
988
|
|
|
|
|
|
|
B::perlstring( $args{constraint}->display_name ), |
|
989
|
|
|
|
|
|
|
$args{varname}, |
|
990
|
777
|
100
|
66
|
|
|
2275
|
B::perlstring( $args{display_var} || $args{varname} ), |
|
991
|
|
|
|
|
|
|
); |
|
992
|
|
|
|
|
|
|
} |
|
993
|
|
|
|
|
|
|
|
|
994
|
|
|
|
|
|
|
sub _make_count_fail { |
|
995
|
320
|
|
|
320
|
|
2070
|
my ( $self, %args ) = ( shift, @_ ); |
|
996
|
|
|
|
|
|
|
|
|
997
|
320
|
|
|
|
|
789
|
my @counts; |
|
998
|
320
|
50
|
|
|
|
1347
|
if ( $args{got} ) { |
|
999
|
|
|
|
|
|
|
push @counts, sprintf( |
|
1000
|
|
|
|
|
|
|
'got => %s', |
|
1001
|
|
|
|
|
|
|
$args{got}, |
|
1002
|
320
|
|
|
|
|
1181
|
); |
|
1003
|
|
|
|
|
|
|
} |
|
1004
|
320
|
|
|
|
|
2731
|
for my $c ( qw/ minimum maximum / ) { |
|
1005
|
640
|
100
|
|
|
|
3511
|
is_Int( $args{$c} ) or next; |
|
1006
|
|
|
|
|
|
|
push @counts, sprintf( |
|
1007
|
|
|
|
|
|
|
'%s => %s', |
|
1008
|
|
|
|
|
|
|
$c, |
|
1009
|
240
|
|
|
|
|
1053
|
$args{$c}, |
|
1010
|
|
|
|
|
|
|
); |
|
1011
|
|
|
|
|
|
|
} |
|
1012
|
|
|
|
|
|
|
|
|
1013
|
320
|
50
|
33
|
|
|
1129
|
if ( my $package = $self->package and my $subname = $self->subname ) { |
|
1014
|
320
|
100
|
100
|
|
|
2698
|
push @counts, sprintf( |
|
1015
|
|
|
|
|
|
|
'target => %s', |
|
1016
|
|
|
|
|
|
|
B::perlstring( "$package\::$subname" ), |
|
1017
|
|
|
|
|
|
|
) if $package ne '__ANON__' && $subname ne '__ANON__'; |
|
1018
|
|
|
|
|
|
|
} |
|
1019
|
|
|
|
|
|
|
|
|
1020
|
320
|
100
|
|
|
|
1061
|
return sprintf( |
|
1021
|
|
|
|
|
|
|
$self->has_on_die |
|
1022
|
|
|
|
|
|
|
? q{return( "Error::TypeTiny::WrongNumberOfParameters"->throw_cb( $__ON_DIE__, %s ) )} |
|
1023
|
|
|
|
|
|
|
: q{"Error::TypeTiny::WrongNumberOfParameters"->throw( %s )}, |
|
1024
|
|
|
|
|
|
|
join( q{, }, @counts ), |
|
1025
|
|
|
|
|
|
|
); |
|
1026
|
|
|
|
|
|
|
} |
|
1027
|
|
|
|
|
|
|
|
|
1028
|
|
|
|
|
|
|
sub class_attributes { |
|
1029
|
65
|
|
|
65
|
1
|
128
|
my $self = shift; |
|
1030
|
65
|
|
66
|
|
|
354
|
$self->{class_attributes} ||= $self->_build_class_attributes; |
|
1031
|
|
|
|
|
|
|
} |
|
1032
|
|
|
|
|
|
|
|
|
1033
|
|
|
|
|
|
|
sub _build_class_attributes { |
|
1034
|
49
|
|
|
49
|
|
104
|
my $self = shift; |
|
1035
|
49
|
|
|
|
|
150
|
my %predicates; |
|
1036
|
|
|
|
|
|
|
my %getters; |
|
1037
|
|
|
|
|
|
|
|
|
1038
|
49
|
|
|
|
|
101
|
my @parameters = @{ $self->parameters }; |
|
|
49
|
|
|
|
|
492
|
|
|
1039
|
49
|
100
|
|
|
|
170
|
if ( $self->has_slurpy ) { |
|
1040
|
1
|
|
|
|
|
2
|
push @parameters, $self->slurpy; |
|
1041
|
|
|
|
|
|
|
} |
|
1042
|
|
|
|
|
|
|
|
|
1043
|
49
|
|
|
|
|
180
|
for my $parameter ( @parameters ) { |
|
1044
|
|
|
|
|
|
|
|
|
1045
|
98
|
|
|
|
|
354
|
my $name = $parameter->name; |
|
1046
|
98
|
100
|
|
|
|
285
|
if ( my $predicate = $parameter->predicate ) { |
|
1047
|
31
|
50
|
|
|
|
162
|
$predicate =~ /^[^0-9\W]\w*$/ |
|
1048
|
|
|
|
|
|
|
or $self->_croak( "Bad accessor name: \"$predicate\"" ); |
|
1049
|
31
|
|
|
|
|
87
|
$predicates{$predicate} = $name; |
|
1050
|
|
|
|
|
|
|
} |
|
1051
|
98
|
50
|
|
|
|
255
|
if ( my $getter = $parameter->getter ) { |
|
1052
|
98
|
100
|
|
|
|
493
|
$getter =~ /^[^0-9\W]\w*$/ |
|
1053
|
|
|
|
|
|
|
or $self->_croak( "Bad accessor name: \"$getter\"" ); |
|
1054
|
96
|
|
|
|
|
337
|
$getters{$getter} = $name; |
|
1055
|
|
|
|
|
|
|
} |
|
1056
|
|
|
|
|
|
|
} |
|
1057
|
|
|
|
|
|
|
|
|
1058
|
|
|
|
|
|
|
return { |
|
1059
|
47
|
|
|
|
|
364
|
exists_predicates => \%predicates, |
|
1060
|
|
|
|
|
|
|
getters => \%getters, |
|
1061
|
|
|
|
|
|
|
}; |
|
1062
|
|
|
|
|
|
|
} |
|
1063
|
|
|
|
|
|
|
|
|
1064
|
|
|
|
|
|
|
sub make_class { |
|
1065
|
49
|
|
|
49
|
1
|
135
|
my $self = shift; |
|
1066
|
|
|
|
|
|
|
|
|
1067
|
49
|
|
50
|
|
|
436
|
my $env = uc( $ENV{PERL_TYPE_PARAMS_XS} || 'XS' ); |
|
1068
|
49
|
50
|
33
|
|
|
428
|
if ( $env eq 'PP' or $ENV{PERL_ONLY} ) { |
|
1069
|
0
|
|
|
|
|
0
|
$self->make_class_pp; |
|
1070
|
|
|
|
|
|
|
} |
|
1071
|
|
|
|
|
|
|
|
|
1072
|
49
|
|
|
|
|
161
|
$self->make_class_xs; |
|
1073
|
|
|
|
|
|
|
} |
|
1074
|
|
|
|
|
|
|
|
|
1075
|
|
|
|
|
|
|
sub make_class_xs { |
|
1076
|
49
|
|
|
49
|
1
|
100
|
my $self = shift; |
|
1077
|
|
|
|
|
|
|
|
|
1078
|
49
|
50
|
|
|
|
171
|
eval { |
|
1079
|
49
|
|
|
|
|
8728
|
require Class::XSAccessor; |
|
1080
|
49
|
|
|
|
|
44002
|
'Class::XSAccessor'->VERSION( '1.17' ); |
|
1081
|
49
|
|
|
|
|
370
|
1; |
|
1082
|
|
|
|
|
|
|
} or return $self->make_class_pp; |
|
1083
|
|
|
|
|
|
|
|
|
1084
|
49
|
|
|
|
|
248
|
my $attr = $self->class_attributes; |
|
1085
|
|
|
|
|
|
|
|
|
1086
|
47
|
|
|
|
|
214
|
'Class::XSAccessor'->import( |
|
1087
|
|
|
|
|
|
|
class => $self->bless, |
|
1088
|
|
|
|
|
|
|
replace => 1, |
|
1089
|
|
|
|
|
|
|
%$attr, |
|
1090
|
|
|
|
|
|
|
); |
|
1091
|
|
|
|
|
|
|
|
|
1092
|
47
|
|
|
|
|
12347
|
$self->make_extra_methods; |
|
1093
|
|
|
|
|
|
|
} |
|
1094
|
|
|
|
|
|
|
|
|
1095
|
|
|
|
|
|
|
sub make_class_pp { |
|
1096
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
|
1097
|
|
|
|
|
|
|
|
|
1098
|
0
|
|
|
|
|
0
|
my $code = $self->make_class_pp_code; |
|
1099
|
0
|
|
|
|
|
0
|
do { |
|
1100
|
0
|
|
|
|
|
0
|
local $@; |
|
1101
|
0
|
0
|
|
|
|
0
|
eval( $code ) or die( $@ ); |
|
1102
|
|
|
|
|
|
|
}; |
|
1103
|
|
|
|
|
|
|
|
|
1104
|
0
|
|
|
|
|
0
|
$self->make_extra_methods; |
|
1105
|
|
|
|
|
|
|
} |
|
1106
|
|
|
|
|
|
|
|
|
1107
|
|
|
|
|
|
|
sub make_class_pp_code { |
|
1108
|
58
|
|
|
58
|
1
|
127
|
my $self = shift; |
|
1109
|
|
|
|
|
|
|
|
|
1110
|
58
|
100
|
66
|
|
|
150
|
return '' |
|
|
|
|
100
|
|
|
|
|
|
1111
|
|
|
|
|
|
|
unless $self->is_named && $self->bless && !$self->named_to_list; |
|
1112
|
|
|
|
|
|
|
|
|
1113
|
16
|
|
|
|
|
63
|
my $coderef = $self->_new_code_accumulator; |
|
1114
|
16
|
|
|
|
|
81
|
my $attr = $self->class_attributes; |
|
1115
|
|
|
|
|
|
|
|
|
1116
|
16
|
|
|
|
|
59
|
$coderef->add_line( '{' ); |
|
1117
|
16
|
|
|
|
|
38
|
$coderef->{indent} = "\t"; |
|
1118
|
16
|
|
|
|
|
53
|
$coderef->add_line( sprintf( 'package %s;', $self->bless ) ); |
|
1119
|
16
|
|
|
|
|
49
|
$coderef->add_line( 'use strict;' ); |
|
1120
|
16
|
|
|
|
|
47
|
$coderef->add_line( 'no warnings;' ); |
|
1121
|
|
|
|
|
|
|
|
|
1122
|
16
|
|
|
|
|
28
|
for my $function ( sort keys %{ $attr->{getters} } ) { |
|
|
16
|
|
|
|
|
124
|
|
|
1123
|
34
|
|
|
|
|
68
|
my $slot = $attr->{getters}{$function}; |
|
1124
|
34
|
|
|
|
|
156
|
$coderef->add_line( sprintf( |
|
1125
|
|
|
|
|
|
|
'sub %s { $_[0]{%s} }', |
|
1126
|
|
|
|
|
|
|
$function, |
|
1127
|
|
|
|
|
|
|
B::perlstring( $slot ), |
|
1128
|
|
|
|
|
|
|
) ); |
|
1129
|
|
|
|
|
|
|
} |
|
1130
|
|
|
|
|
|
|
|
|
1131
|
16
|
|
|
|
|
36
|
for my $function ( sort keys %{ $attr->{exists_predicates} } ) { |
|
|
16
|
|
|
|
|
47
|
|
|
1132
|
12
|
|
|
|
|
18
|
my $slot = $attr->{exists_predicates}{$function}; |
|
1133
|
12
|
|
|
|
|
38
|
$coderef->add_line( sprintf( |
|
1134
|
|
|
|
|
|
|
'sub %s { exists $_[0]{%s} }', |
|
1135
|
|
|
|
|
|
|
$function, |
|
1136
|
|
|
|
|
|
|
B::perlstring( $slot ), |
|
1137
|
|
|
|
|
|
|
) ); |
|
1138
|
|
|
|
|
|
|
} |
|
1139
|
|
|
|
|
|
|
|
|
1140
|
16
|
|
|
|
|
52
|
$coderef->add_line( '1;' ); |
|
1141
|
16
|
|
|
|
|
37
|
$coderef->{indent} = ""; |
|
1142
|
16
|
|
|
|
|
48
|
$coderef->add_line( '}' ); |
|
1143
|
|
|
|
|
|
|
|
|
1144
|
16
|
|
|
|
|
43
|
return $coderef->code; |
|
1145
|
|
|
|
|
|
|
} |
|
1146
|
|
|
|
|
|
|
|
|
1147
|
|
|
|
|
|
|
sub make_extra_methods { |
|
1148
|
47
|
|
|
47
|
0
|
111
|
my $self = shift; |
|
1149
|
|
|
|
|
|
|
|
|
1150
|
47
|
|
|
|
|
96
|
my @parameters = @{ $self->parameters }; |
|
|
47
|
|
|
|
|
164
|
|
|
1151
|
47
|
100
|
|
|
|
136
|
if ( $self->has_slurpy ) { |
|
1152
|
1
|
|
|
|
|
3
|
push @parameters, $self->slurpy; |
|
1153
|
|
|
|
|
|
|
} |
|
1154
|
|
|
|
|
|
|
|
|
1155
|
47
|
|
|
|
|
263
|
my $coderef = $self->_new_code_accumulator; |
|
1156
|
47
|
|
|
|
|
253
|
$coderef->add_line( '{' ); |
|
1157
|
47
|
|
|
|
|
130
|
$coderef->{indent} = "\t"; |
|
1158
|
47
|
|
|
|
|
180
|
$coderef->add_line( sprintf( 'package %s;', $self->bless ) ); |
|
1159
|
47
|
|
|
|
|
175
|
$coderef->add_line( 'use strict;' ); |
|
1160
|
47
|
|
|
|
|
198
|
$coderef->add_line( 'no warnings;' ); |
|
1161
|
|
|
|
|
|
|
|
|
1162
|
47
|
|
|
|
|
754
|
$coderef->add_line( 'my @FIELDS = (' ); |
|
1163
|
47
|
|
|
|
|
130
|
for my $p ( @parameters ) { |
|
1164
|
96
|
|
|
|
|
306
|
$coderef->add_line( "\t" . B::perlstring( $p->name ) . "," ) |
|
1165
|
|
|
|
|
|
|
} |
|
1166
|
47
|
|
|
|
|
172
|
$coderef->add_line( ');' ); |
|
1167
|
|
|
|
|
|
|
|
|
1168
|
47
|
|
|
|
|
88
|
my @enum; |
|
1169
|
47
|
|
|
|
|
164
|
$coderef->add_line( 'my %FIELDS = (' ); |
|
1170
|
47
|
|
|
|
|
157
|
for my $p ( @parameters ) { |
|
1171
|
96
|
|
|
|
|
309
|
$coderef->add_line( "\t" . B::perlstring( $p->name ) . " => " . B::perlstring( $p->name ) . "," ); |
|
1172
|
96
|
|
|
|
|
349
|
for my $p2 ( $p->_all_aliases($self) ) { |
|
1173
|
15
|
|
|
|
|
59
|
$coderef->add_line( "\t" . B::perlstring( $p2 ) . " => " . B::perlstring( $p->name ) . "," ); |
|
1174
|
|
|
|
|
|
|
} |
|
1175
|
96
|
|
|
|
|
272
|
push @enum, $p->name, $p->_all_aliases($self); |
|
1176
|
|
|
|
|
|
|
} |
|
1177
|
47
|
|
|
|
|
241
|
$coderef->add_line( ');' ); |
|
1178
|
47
|
|
|
|
|
279
|
my $enum = ArrayRef[ Enum[ @enum ] ]; |
|
1179
|
|
|
|
|
|
|
|
|
1180
|
47
|
|
|
|
|
523
|
$coderef->add_line( 'sub __TO_LIST__ {' ); |
|
1181
|
47
|
|
|
|
|
1127
|
$coderef->add_line( "\t" . 'my ( $arg, $fields ) = @_;' ); |
|
1182
|
47
|
|
|
|
|
164
|
$coderef->add_line( "\t" . 'return map $arg->{$_}, @FIELDS if not defined $fields;' ); |
|
1183
|
47
|
50
|
33
|
|
|
197
|
if ( ( defined $self->strictness and $self->strictness eq 1 ) or not $self->has_strictness ){ |
|
|
|
0
|
33
|
|
|
|
|
|
1184
|
47
|
|
|
|
|
272
|
$coderef->add_line( "\t" . $enum->inline_assert( '$fields' ) ); |
|
1185
|
|
|
|
|
|
|
} |
|
1186
|
|
|
|
|
|
|
elsif ( $self->strictness ) { |
|
1187
|
0
|
|
|
|
|
0
|
$coderef->add_line( "\t" . sprintf( 'if ( %s ) { %s }', $self->strictness, $enum->inline_assert( '$fields' ) ) ); |
|
1188
|
|
|
|
|
|
|
} |
|
1189
|
47
|
|
|
|
|
229
|
$coderef->add_line( "\t" . 'return map $arg->{$FIELDS{$_}}, @$fields;' ); |
|
1190
|
47
|
|
|
|
|
170
|
$coderef->add_line( '}' ); |
|
1191
|
|
|
|
|
|
|
|
|
1192
|
47
|
|
|
|
|
157
|
$coderef->add_line( 'sub __TO_ARRAYREF__ {' ); |
|
1193
|
47
|
|
|
|
|
184
|
$coderef->add_line( "\t" . 'my ( $arg, $fields ) = @_;' ); |
|
1194
|
47
|
|
|
|
|
163
|
$coderef->add_line( "\t" . 'return [ map $arg->{$_}, @FIELDS ] if not defined $fields;' ); |
|
1195
|
47
|
50
|
33
|
|
|
158
|
if ( ( defined $self->strictness and $self->strictness eq 1 ) or not $self->has_strictness ){ |
|
|
|
0
|
33
|
|
|
|
|
|
1196
|
47
|
|
|
|
|
181
|
$coderef->add_line( "\t" . $enum->inline_assert( '$fields' ) ); |
|
1197
|
|
|
|
|
|
|
} |
|
1198
|
|
|
|
|
|
|
elsif ( $self->strictness ) { |
|
1199
|
0
|
|
|
|
|
0
|
$coderef->add_line( "\t" . sprintf( 'if ( %s ) { %s }', $self->strictness, $enum->inline_assert( '$fields' ) ) ); |
|
1200
|
|
|
|
|
|
|
} |
|
1201
|
47
|
|
|
|
|
196
|
$coderef->add_line( "\t" . 'return [ map $arg->{$FIELDS{$_}}, @$fields ];' ); |
|
1202
|
47
|
|
|
|
|
149
|
$coderef->add_line( '}' ); |
|
1203
|
|
|
|
|
|
|
|
|
1204
|
47
|
|
|
|
|
164
|
$coderef->add_line( 'sub __TO_HASHREF__ {' ); |
|
1205
|
47
|
|
|
|
|
189
|
$coderef->add_line( "\t" . 'my ( $arg, $fields ) = @_;' ); |
|
1206
|
47
|
|
|
|
|
161
|
$coderef->add_line( "\t" . 'return +{ map { ; $_ => $arg->{$_} } @FIELDS } if not defined $fields;' ); |
|
1207
|
47
|
50
|
33
|
|
|
150
|
if ( ( defined $self->strictness and $self->strictness eq 1 ) or not $self->has_strictness ){ |
|
|
|
0
|
33
|
|
|
|
|
|
1208
|
47
|
|
|
|
|
175
|
$coderef->add_line( "\t" . $enum->inline_assert( '$fields' ) ); |
|
1209
|
|
|
|
|
|
|
} |
|
1210
|
|
|
|
|
|
|
elsif ( $self->strictness ) { |
|
1211
|
0
|
|
|
|
|
0
|
$coderef->add_line( "\t" . sprintf( 'if ( %s ) { %s }', $self->strictness, $enum->inline_assert( '$fields' ) ) ); |
|
1212
|
|
|
|
|
|
|
} |
|
1213
|
47
|
|
|
|
|
189
|
$coderef->add_line( "\t" . 'return +{ map { ; $_ => $arg->{$FIELDS{$_}} } @$fields };' ); |
|
1214
|
47
|
|
|
|
|
147
|
$coderef->add_line( '}' ); |
|
1215
|
|
|
|
|
|
|
|
|
1216
|
47
|
|
|
|
|
146
|
$coderef->add_line( '1;' ); |
|
1217
|
47
|
|
|
|
|
121
|
$coderef->{indent} = ""; |
|
1218
|
47
|
|
|
|
|
153
|
$coderef->add_line( '}' ); |
|
1219
|
|
|
|
|
|
|
|
|
1220
|
47
|
|
|
|
|
534
|
my $code = $coderef->code; |
|
1221
|
47
|
|
|
|
|
111
|
local $@; |
|
1222
|
47
|
50
|
|
19
|
|
6223
|
eval( $code ) or die( $@ ); |
|
|
20
|
100
|
|
14
|
|
119
|
|
|
|
16
|
100
|
|
14
|
|
47
|
|
|
|
19
|
100
|
|
14
|
|
603
|
|
|
|
19
|
0
|
|
14
|
|
106
|
|
|
|
18
|
0
|
|
|
|
32
|
|
|
|
18
|
0
|
|
|
|
3305
|
|
|
|
24
|
0
|
|
|
|
162
|
|
|
|
19
|
|
|
|
|
712
|
|
|
|
19
|
|
|
|
|
2982
|
|
|
|
18
|
|
|
|
|
114
|
|
|
|
18
|
|
|
|
|
52
|
|
|
|
17
|
|
|
|
|
2976
|
|
|
|
17
|
|
|
|
|
121
|
|
|
|
14
|
|
|
|
|
43
|
|
|
|
14
|
|
|
|
|
2015
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
1223
|
|
|
|
|
|
|
|
|
1224
|
|
|
|
|
|
|
Type::Tiny::_install_overloads( |
|
1225
|
|
|
|
|
|
|
$self->bless, |
|
1226
|
0
|
|
|
7
|
|
0
|
'bool' => sub { 1 }, |
|
1227
|
47
|
|
|
|
|
267
|
'@{}' => '__TO_ARRAYREF__', |
|
1228
|
|
|
|
|
|
|
'fallback' => !!1, |
|
1229
|
|
|
|
|
|
|
); |
|
1230
|
|
|
|
|
|
|
} |
|
1231
|
|
|
|
|
|
|
|
|
1232
|
|
|
|
|
|
|
sub return_wanted { |
|
1233
|
311
|
|
|
310
|
1
|
1048
|
my $self = shift; |
|
1234
|
311
|
|
|
|
|
1473
|
my $coderef = $self->coderef; |
|
1235
|
|
|
|
|
|
|
|
|
1236
|
305
|
100
|
|
|
|
2069
|
if ( $self->{want_source} ) { |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
1237
|
11
|
|
|
|
|
90
|
return $coderef->code; |
|
1238
|
|
|
|
|
|
|
} |
|
1239
|
|
|
|
|
|
|
elsif ( $self->{want_object} ) { # undocumented for now |
|
1240
|
4
|
|
|
|
|
15
|
return $self; |
|
1241
|
|
|
|
|
|
|
} |
|
1242
|
|
|
|
|
|
|
elsif ( $self->{want_details} ) { |
|
1243
|
|
|
|
|
|
|
return { |
|
1244
|
|
|
|
|
|
|
min_args => $self->{min_args}, |
|
1245
|
|
|
|
|
|
|
max_args => $self->{max_args}, |
|
1246
|
|
|
|
|
|
|
environment => $coderef->{env}, |
|
1247
|
65
|
|
|
|
|
339
|
source => $coderef->code, |
|
1248
|
|
|
|
|
|
|
closure => $coderef->compile, |
|
1249
|
|
|
|
|
|
|
named => $self->is_named, |
|
1250
|
|
|
|
|
|
|
class_definition => $self->make_class_pp_code, |
|
1251
|
|
|
|
|
|
|
}; |
|
1252
|
|
|
|
|
|
|
} |
|
1253
|
|
|
|
|
|
|
|
|
1254
|
237
|
|
|
|
|
1472
|
return $coderef->compile; |
|
1255
|
|
|
|
|
|
|
} |
|
1256
|
|
|
|
|
|
|
|
|
1257
|
|
|
|
|
|
|
1; |
|
1258
|
|
|
|
|
|
|
|
|
1259
|
|
|
|
|
|
|
__END__ |