File Coverage

blib/lib/Devel/Declare/Context/Simple.pm
Criterion Covered Total %
statement 145 164 88.4
branch 28 38 73.6
condition 3 4 75.0
subroutine 25 26 96.1
pod 0 20 0.0
total 201 252 79.7


line stmt bran cond sub pod time code
1             package Devel::Declare::Context::Simple;
2              
3 6     6   874 use strict;
  6         11  
  6         159  
4 6     6   29 use warnings;
  6         10  
  6         133  
5 6     6   1719 use Devel::Declare ();
  6         15  
  6         125  
6 6     6   2475 use B::Hooks::EndOfScope;
  6         61496  
  6         38  
7 6     6   384 use Carp qw/confess/;
  6         13  
  6         8969  
8              
9             our $VERSION = '0.006_021';
10             $VERSION =~ tr/_//d;
11              
12             sub new {
13 23     23 0 77 my $class = shift;
14 23         90 bless {@_}, $class;
15             }
16              
17             sub init {
18 36     36 0 59 my $self = shift;
19 36         59 @{$self}{ qw(Declarator Offset WarningOnRedefined) } = @_;
  36         114  
20 36         74 return $self;
21             }
22              
23             sub offset {
24 606     606 0 700 my $self = shift;
25             return $self->{Offset}
26 606         2861 }
27              
28             sub inc_offset {
29 213     213 0 269 my $self = shift;
30 213         323 $self->{Offset} += shift;
31             }
32              
33             sub declarator {
34 76     76 0 105 my $self = shift;
35             return $self->{Declarator}
36 76         195 }
37              
38             sub warning_on_redefine {
39 11     11 0 20 my $self = shift;
40             return $self->{WarningOnRedefined}
41 11         63 }
42              
43             sub skip_declarator {
44 36     36 0 74 my $self = shift;
45 36         68 my $decl = $self->declarator;
46 36         72 my $len = Devel::Declare::toke_scan_word($self->offset, 0);
47 36 50       91 confess "Couldn't find declarator '$decl'"
48             unless $len;
49              
50 36         80 my $linestr = $self->get_linestr;
51 36         61 my $name = substr($linestr, $self->offset, $len);
52 36 50       77 confess "Expected declarator '$decl', got '${name}'"
53             unless $name eq $decl;
54              
55 36         79 $self->inc_offset($len);
56             }
57              
58             sub skipspace {
59 177     177 0 210 my $self = shift;
60 177         244 $self->inc_offset(Devel::Declare::toke_skipspace($self->offset));
61             }
62              
63             sub get_linestr {
64 179     179 0 231 my $self = shift;
65 179         339 my $line = Devel::Declare::get_linestr();
66 179         271 return $line;
67             }
68              
69             sub set_linestr {
70 97     97 0 116 my $self = shift;
71 97         181 my ($line) = @_;
72 97         196 Devel::Declare::set_linestr($line);
73             }
74              
75             sub strip_name {
76 54     54 0 99 my $self = shift;
77 54         124 $self->skipspace;
78 54 100       82 if (my $len = Devel::Declare::toke_scan_word( $self->offset, 1 )) {
79 34         67 my $linestr = $self->get_linestr();
80 34         64 my $name = substr( $linestr, $self->offset, $len );
81 34         82 substr( $linestr, $self->offset, $len ) = '';
82 34         88 $self->set_linestr($linestr);
83 34         91 return $name;
84             }
85              
86 20         37 $self->skipspace;
87 20         31 return;
88             }
89              
90             sub strip_ident {
91 0     0 0 0 my $self = shift;
92 0         0 $self->skipspace;
93 0 0       0 if (my $len = Devel::Declare::toke_scan_ident( $self->offset )) {
94 0         0 my $linestr = $self->get_linestr();
95 0         0 my $ident = substr( $linestr, $self->offset, $len );
96 0         0 substr( $linestr, $self->offset, $len ) = '';
97 0         0 $self->set_linestr($linestr);
98 0         0 return $ident;
99             }
100              
101 0         0 $self->skipspace;
102 0         0 return;
103             }
104              
105             sub strip_proto {
106 38     38 0 78 my $self = shift;
107 38         73 $self->skipspace;
108              
109 38         61 my $linestr = $self->get_linestr();
110 38 100       65 if (substr($linestr, $self->offset, 1) eq '(') {
111 26         60 my $length = Devel::Declare::toke_scan_str($self->offset);
112 26         59 my $proto = Devel::Declare::get_lex_stuff();
113 26         55 Devel::Declare::clear_lex_stuff();
114 26         42 $linestr = $self->get_linestr();
115              
116 26 100       40 substr($linestr, $self->offset,
117             defined($length) ? $length : length($linestr)) = '';
118 26         56 $self->set_linestr($linestr);
119              
120 26         64 return $proto;
121             }
122 12         44 return;
123             }
124              
125             sub strip_names_and_args {
126 2     2 0 9 my $self = shift;
127 2         4 $self->skipspace;
128              
129 2         3 my @args;
130              
131 2         3 my $linestr = $self->get_linestr;
132 2 100       10 if (substr($linestr, $self->offset, 1) eq '(') {
133             # We had a leading paren, so we will now expect comma separated
134             # arguments
135 1         20 substr($linestr, $self->offset, 1) = '';
136 1         18 $self->set_linestr($linestr);
137 1         3 $self->skipspace;
138              
139             # At this point we expect to have a comma-separated list of
140             # barewords with optional protos afterward, so loop until we
141             # run out of comma-separated values
142 1         2 while (1) {
143             # Get the bareword
144 3         5 my $thing = $self->strip_name;
145             # If there's no bareword here, bail
146 3 50       7 confess "failed to parse bareword. found ${linestr}"
147             unless defined $thing;
148              
149 3         5 $linestr = $self->get_linestr;
150 3 100       6 if (substr($linestr, $self->offset, 1) eq '(') {
151             # This one had a proto, pull it out
152 2         4 push(@args, [ $thing, $self->strip_proto ]);
153             } else {
154             # This had no proto, so store it with an undef
155 1         2 push(@args, [ $thing, undef ]);
156             }
157 3         7 $self->skipspace;
158 3         4 $linestr = $self->get_linestr;
159              
160 3 100       5 if (substr($linestr, $self->offset, 1) eq ',') {
161             # We found a comma, strip it out and set things up for
162             # another iteration
163 2         2 substr($linestr, $self->offset, 1) = '';
164 2         4 $self->set_linestr($linestr);
165 2         10 $self->skipspace;
166             } else {
167             # No comma, get outta here
168 1         2 last;
169             }
170             }
171              
172             # look for the final closing paren of the list
173 1 50       2 if (substr($linestr, $self->offset, 1) eq ')') {
174 1         2 substr($linestr, $self->offset, 1) = '';
175 1         2 $self->set_linestr($linestr);
176 1         2 $self->skipspace;
177             }
178             else {
179             # fail if it isn't there
180 0         0 confess "couldn't find closing paren for argument. found ${linestr}"
181             }
182             } else {
183             # No parens, so expect a single arg
184 1         2 my $thing = $self->strip_name;
185             # If there's no bareword here, bail
186 1 50       3 confess "failed to parse bareword. found ${linestr}"
187             unless defined $thing;
188 1         1 $linestr = $self->get_linestr;
189 1 50       2 if (substr($linestr, $self->offset, 1) eq '(') {
190             # This one had a proto, pull it out
191 0         0 push(@args, [ $thing, $self->strip_proto ]);
192             } else {
193             # This had no proto, so store it with an undef
194 1         2 push(@args, [ $thing, undef ]);
195             }
196             }
197              
198 2         4 return \@args;
199             }
200              
201             sub strip_attrs {
202 18     18 0 23 my $self = shift;
203 18         41 $self->skipspace;
204              
205 18         43 my $linestr = Devel::Declare::get_linestr;
206 18         36 my $attrs = '';
207              
208 18 100       30 if (substr($linestr, $self->offset, 1) eq ':') {
209 1         3 while (substr($linestr, $self->offset, 1) ne '{') {
210 2 100       3 if (substr($linestr, $self->offset, 1) eq ':') {
211 1         3 substr($linestr, $self->offset, 1) = '';
212 1         3 Devel::Declare::set_linestr($linestr);
213              
214 1         2 $attrs .= ':';
215             }
216              
217 2         5 $self->skipspace;
218 2         4 $linestr = Devel::Declare::get_linestr();
219              
220 2 100       3 if (my $len = Devel::Declare::toke_scan_word($self->offset, 0)) {
221 1         3 my $name = substr($linestr, $self->offset, $len);
222 1         1 substr($linestr, $self->offset, $len) = '';
223 1         3 Devel::Declare::set_linestr($linestr);
224              
225 1         2 $attrs .= " ${name}";
226              
227 1 50       2 if (substr($linestr, $self->offset, 1) eq '(') {
228 0         0 my $length = Devel::Declare::toke_scan_str($self->offset);
229 0         0 my $arg = Devel::Declare::get_lex_stuff();
230 0         0 Devel::Declare::clear_lex_stuff();
231 0         0 $linestr = Devel::Declare::get_linestr();
232 0         0 substr($linestr, $self->offset, $length) = '';
233 0         0 Devel::Declare::set_linestr($linestr);
234              
235 0         0 $attrs .= "(${arg})";
236             }
237             }
238             }
239              
240 1         3 $linestr = Devel::Declare::get_linestr();
241             }
242              
243 18         41 return $attrs;
244             }
245              
246              
247             sub get_curstash_name {
248 54     54 0 130 return Devel::Declare::get_curstash_name;
249             }
250              
251             sub shadow {
252 36     36 0 481 my $self = shift;
253 36         63 my $pack = $self->get_curstash_name;
254 36         90 Devel::Declare::shadow_sub( $pack . '::' . $self->declarator, $_[0] );
255             }
256              
257             sub inject_if_block {
258 36     36 0 142 my $self = shift;
259 36         59 my $inject = shift;
260 36   100     137 my $before = shift || '';
261              
262 36         125 $self->skipspace;
263              
264 36         70 my $linestr = $self->get_linestr;
265 36 100       64 if (substr($linestr, $self->offset, 1) eq '{') {
266 33         52 substr($linestr, $self->offset + 1, 0) = $inject;
267 33         51 substr($linestr, $self->offset, 0) = $before;
268 33         69 $self->set_linestr($linestr);
269 33         58 return 1;
270             }
271 3         14 return 0;
272             }
273              
274             sub scope_injector_call {
275 24     24 0 163 my $self = shift;
276 24   50     82 my $inject = shift || '';
277 24         103 return ' BEGIN { ' . ref($self) . "->inject_scope('${inject}') }; ";
278             }
279              
280             sub inject_scope {
281 21     21 0 121 my $class = shift;
282 21         43 my $inject = shift;
283             on_scope_end {
284 21     21   849 my $linestr = Devel::Declare::get_linestr;
285 21 50       58 return unless defined $linestr;
286 21         58 my $offset = Devel::Declare::get_linestr_offset;
287 21         72 substr( $linestr, $offset, 0 ) = ';' . $inject;
288 21         113 Devel::Declare::set_linestr($linestr);
289 21         123 };
290             }
291              
292             1;
293             # vi:sw=2 ts=2