line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Exporter::Declare::Magic::Parser; |
2
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
36
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
31
|
|
4
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
5
|
use base 'Devel::Declare::Parser'; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
95
|
|
6
|
1
|
|
|
1
|
|
5
|
use Devel::Declare::Interface; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
92
|
|
7
|
1
|
|
|
1
|
|
5
|
BEGIN { Devel::Declare::Interface::register_parser( 'export' )}; |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
__PACKAGE__->add_accessor( '_inject' ); |
10
|
|
|
|
|
|
|
__PACKAGE__->add_accessor( 'parser' ); |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
sub inject { |
13
|
6
|
|
|
6
|
1
|
229
|
my $self = shift; |
14
|
6
|
|
|
|
|
6
|
my @out; |
15
|
|
|
|
|
|
|
|
16
|
6
|
50
|
|
|
|
14
|
if( my $items = $self->_inject() ) { |
17
|
0
|
|
|
|
|
0
|
my $ref = ref( $items ); |
18
|
0
|
0
|
|
|
|
0
|
if ( $ref eq 'ARRAY' ) { |
|
|
0
|
|
|
|
|
|
19
|
0
|
|
|
|
|
0
|
push @out => @$items; |
20
|
|
|
|
|
|
|
} |
21
|
|
|
|
|
|
|
elsif ( !$ref ) { |
22
|
0
|
|
|
|
|
0
|
push @out => $items; |
23
|
|
|
|
|
|
|
} |
24
|
|
|
|
|
|
|
else { |
25
|
0
|
|
|
|
|
0
|
$self->bail( "$items is not a valid injection" ); |
26
|
|
|
|
|
|
|
} |
27
|
|
|
|
|
|
|
} |
28
|
6
|
|
|
|
|
43
|
return @out; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
sub _check_parts { |
32
|
10
|
|
|
10
|
|
12
|
my $self = shift; |
33
|
10
|
|
|
|
|
415
|
$self->bail( "You must provide a name to " . $self->name . "()" ) |
34
|
10
|
50
|
33
|
|
|
26
|
if ( !$self->parts || !@{ $self->parts }); |
35
|
|
|
|
|
|
|
|
36
|
10
|
50
|
|
|
|
230
|
if ( @{ $self->parts } > 3 ) { |
|
10
|
|
|
|
|
200
|
|
37
|
0
|
|
|
|
|
0
|
( undef, undef, undef, my @bad ) = @{ $self->parts }; |
|
0
|
|
|
|
|
0
|
|
38
|
0
|
|
|
|
|
0
|
$self->bail( |
39
|
|
|
|
|
|
|
"Syntax error near: " . join( ' and ', |
40
|
0
|
|
|
|
|
0
|
map { $self->format_part($_)} @bad |
41
|
|
|
|
|
|
|
) |
42
|
|
|
|
|
|
|
); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
sub sort_parts { |
47
|
8
|
|
|
8
|
0
|
214
|
my $self = shift; |
48
|
|
|
|
|
|
|
|
49
|
8
|
100
|
|
|
|
403
|
if ($self->parts->[0] =~ m/^[\%\$\&\@]/) { |
50
|
1
|
|
|
|
|
209
|
$self->parts->[0] = [ |
51
|
|
|
|
|
|
|
$self->parts->[0], |
52
|
|
|
|
|
|
|
undef, |
53
|
|
|
|
|
|
|
]; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
$self->bail( |
57
|
0
|
|
|
|
|
0
|
"Parsing Error, unrecognized tokens: " |
58
|
8
|
50
|
|
|
|
459
|
. join( ', ', map {"'$_'"} $self->has_non_string_or_quote_parts ) |
59
|
|
|
|
|
|
|
) if $self->has_non_string_or_quote_parts; |
60
|
|
|
|
|
|
|
|
61
|
8
|
|
|
|
|
283
|
my ( @names, @specs ); |
62
|
8
|
|
|
|
|
7
|
for my $part (@{ $self->parts }) { |
|
8
|
|
|
|
|
22
|
|
63
|
10
|
50
|
|
|
|
51
|
$self->bail( "Bad part: $part" ) unless ref($part); |
64
|
10
|
50
|
66
|
|
|
39
|
$part->[1] && $part->[1] eq '(' |
65
|
|
|
|
|
|
|
? ( push @specs => $part ) |
66
|
|
|
|
|
|
|
: ( push @names => $part ) |
67
|
|
|
|
|
|
|
} |
68
|
|
|
|
|
|
|
|
69
|
8
|
50
|
|
|
|
19
|
if ( @names > 2 ) { |
70
|
0
|
|
|
|
|
0
|
( undef, undef, my @bad ) = @names; |
71
|
0
|
|
|
|
|
0
|
$self->bail( |
72
|
|
|
|
|
|
|
"Syntax error near: " . join( ' and ', |
73
|
0
|
|
|
|
|
0
|
map { $self->format_part($_)} @bad |
74
|
|
|
|
|
|
|
) |
75
|
|
|
|
|
|
|
); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
|
78
|
8
|
|
|
|
|
15
|
return ( \@names, \@specs ); |
79
|
|
|
|
|
|
|
} |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub strip_prototype { |
82
|
10
|
|
|
10
|
0
|
9
|
my $self = shift; |
83
|
10
|
|
|
|
|
366
|
my $parts = $self->parts; |
84
|
10
|
50
|
|
|
|
253
|
return unless @$parts > 3; |
85
|
0
|
0
|
|
|
|
0
|
return unless ref( $parts->[2] ); |
86
|
0
|
0
|
|
|
|
0
|
return unless $parts->[2]->[0] eq 'sub'; |
87
|
0
|
0
|
|
|
|
0
|
return unless ref( $parts->[3] ); |
88
|
0
|
0
|
|
|
|
0
|
return unless $parts->[3]->[1] eq '('; |
89
|
0
|
0
|
|
|
|
0
|
return unless !$parts->[2]->[1]; |
90
|
0
|
|
|
|
|
0
|
$self->prototype( |
91
|
|
|
|
|
|
|
$parts->[3]->[1] |
92
|
|
|
|
|
|
|
. $parts->[3]->[0] |
93
|
|
|
|
|
|
|
. $self->end_quote($parts->[3]->[1]) |
94
|
|
|
|
|
|
|
); |
95
|
0
|
|
|
|
|
0
|
delete $parts->[3]; |
96
|
|
|
|
|
|
|
} |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
sub rewrite { |
99
|
10
|
|
|
10
|
1
|
16593
|
my $self = shift; |
100
|
|
|
|
|
|
|
|
101
|
10
|
|
|
|
|
188
|
$self->strip_prototype; |
102
|
10
|
|
|
|
|
22
|
$self->_check_parts; |
103
|
|
|
|
|
|
|
|
104
|
10
|
|
66
|
|
|
234
|
my $is_arrow = $self->parts->[1] |
105
|
|
|
|
|
|
|
&& ($self->parts->[1] eq '=>' || $self->parts->[1] eq ','); |
106
|
10
|
100
|
66
|
|
|
313
|
if ( $is_arrow && $self->parts->[2] ) { |
107
|
2
|
|
|
|
|
18
|
my $is_ref = !ref( $self->parts->[2] ); |
108
|
2
|
100
|
|
|
|
17
|
my $is_sub = $is_ref ? 0 : $self->parts->[2]->[0] eq 'sub'; |
109
|
|
|
|
|
|
|
|
110
|
2
|
100
|
66
|
|
|
16
|
if (( $is_arrow && $is_ref ) |
|
1
|
50
|
66
|
|
|
5
|
|
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
111
|
0
|
|
|
|
|
0
|
|| ( @{ $self->parts } == 1 )) { |
112
|
1
|
|
|
|
|
7
|
$self->new_parts([ $self->parts->[0], $self->parts->[2] ]); |
113
|
1
|
|
|
|
|
12
|
return 1; |
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
elsif (( $is_arrow && $is_sub ) |
116
|
|
|
|
|
|
|
|| ( @{ $self->parts } == 1 )) { |
117
|
1
|
|
|
|
|
20
|
$self->new_parts([ $self->parts->[0] ]); |
118
|
1
|
|
|
|
|
12
|
return 1; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
8
|
|
|
|
|
18
|
my ( $names, $specs ) = $self->sort_parts(); |
123
|
8
|
100
|
|
|
|
34
|
$self->parser( $names->[1] ? $names->[1]->[0] : undef ); |
124
|
8
|
100
|
|
|
|
52
|
push @$names => 'undef' unless @$names > 1; |
125
|
8
|
|
|
|
|
26
|
$self->new_parts( $names ); |
126
|
|
|
|
|
|
|
|
127
|
8
|
50
|
|
|
|
46
|
if ( @$specs ) { |
128
|
0
|
0
|
|
|
|
0
|
$self->bail( "Too many spec defenitions" ) |
129
|
|
|
|
|
|
|
if @$specs > 1; |
130
|
0
|
|
0
|
|
|
0
|
my $specs = eval "{ " . $specs->[0]->[0] . " }" |
131
|
|
|
|
|
|
|
|| $self->bail($@); |
132
|
0
|
|
|
|
|
0
|
$self->_inject( delete $specs->{ inject }); |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
|
135
|
8
|
|
|
|
|
16
|
1; |
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
1; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
__END__ |