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   1072 use strict;
  6         13  
  6         188  
4 6     6   29 use warnings;
  6         14  
  6         165  
5 6     6   1912 use Devel::Declare ();
  6         18  
  6         140  
6 6     6   3028 use B::Hooks::EndOfScope;
  6         70066  
  6         47  
7 6     6   452 use Carp qw/confess/;
  6         13  
  6         10186  
8              
9             our $VERSION = '0.006022';
10             $VERSION =~ tr/_//d;
11              
12             sub new {
13 23     23 0 90 my $class = shift;
14 23         94 bless {@_}, $class;
15             }
16              
17             sub init {
18 36     36 0 65 my $self = shift;
19 36         120 @{$self}{ qw(Declarator Offset WarningOnRedefined) } = @_;
  36         136  
20 36         85 return $self;
21             }
22              
23             sub offset {
24 606     606 0 836 my $self = shift;
25             return $self->{Offset}
26 606         1651 }
27              
28             sub inc_offset {
29 213     213 0 313 my $self = shift;
30 213         370 $self->{Offset} += shift;
31             }
32              
33             sub declarator {
34 76     76 0 126 my $self = shift;
35             return $self->{Declarator}
36 76         234 }
37              
38             sub warning_on_redefine {
39 11     11 0 21 my $self = shift;
40             return $self->{WarningOnRedefined}
41 11         68 }
42              
43             sub skip_declarator {
44 36     36 0 89 my $self = shift;
45 36         89 my $decl = $self->declarator;
46 36         88 my $len = Devel::Declare::toke_scan_word($self->offset, 0);
47 36 50       98 confess "Couldn't find declarator '$decl'"
48             unless $len;
49              
50 36         101 my $linestr = $self->get_linestr;
51 36         72 my $name = substr($linestr, $self->offset, $len);
52 36 50       96 confess "Expected declarator '$decl', got '${name}'"
53             unless $name eq $decl;
54              
55 36         92 $self->inc_offset($len);
56             }
57              
58             sub skipspace {
59 177     177 0 250 my $self = shift;
60 177         291 $self->inc_offset(Devel::Declare::toke_skipspace($self->offset));
61             }
62              
63             sub get_linestr {
64 179     179 0 262 my $self = shift;
65 179         716 my $line = Devel::Declare::get_linestr();
66 179         336 return $line;
67             }
68              
69             sub set_linestr {
70 97     97 0 184 my $self = shift;
71 97         223 my ($line) = @_;
72 97         216 Devel::Declare::set_linestr($line);
73             }
74              
75             sub strip_name {
76 54     54 0 125 my $self = shift;
77 54         137 $self->skipspace;
78 54 100       2105 if (my $len = Devel::Declare::toke_scan_word( $self->offset, 1 )) {
79 34         73 my $linestr = $self->get_linestr();
80 34         77 my $name = substr( $linestr, $self->offset, $len );
81 34         80 substr( $linestr, $self->offset, $len ) = '';
82 34         108 $self->set_linestr($linestr);
83 34         106 return $name;
84             }
85              
86 20         44 $self->skipspace;
87 20         38 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 100 my $self = shift;
107 38         92 $self->skipspace;
108              
109 38         71 my $linestr = $self->get_linestr();
110 38 100       83 if (substr($linestr, $self->offset, 1) eq '(') {
111 26         53 my $length = Devel::Declare::toke_scan_str($self->offset);
112 26         71 my $proto = Devel::Declare::get_lex_stuff();
113 26         66 Devel::Declare::clear_lex_stuff();
114 26         44 $linestr = $self->get_linestr();
115              
116 26 100       51 substr($linestr, $self->offset,
117             defined($length) ? $length : length($linestr)) = '';
118 26         69 $self->set_linestr($linestr);
119              
120 26         81 return $proto;
121             }
122 12         27 return;
123             }
124              
125             sub strip_names_and_args {
126 2     2 0 11 my $self = shift;
127 2         5 $self->skipspace;
128              
129 2         3 my @args;
130              
131 2         4 my $linestr = $self->get_linestr;
132 2 100       5 if (substr($linestr, $self->offset, 1) eq '(') {
133             # We had a leading paren, so we will now expect comma separated
134             # arguments
135 1         34 substr($linestr, $self->offset, 1) = '';
136 1         16 $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         7 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         6 $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         9 $self->skipspace;
158 3         7 $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         4 substr($linestr, $self->offset, 1) = '';
164 2         5 $self->set_linestr($linestr);
165 2         20 $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       3 if (substr($linestr, $self->offset, 1) eq ')') {
174 1         11 substr($linestr, $self->offset, 1) = '';
175 1         3 $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       4 confess "failed to parse bareword. found ${linestr}"
187             unless defined $thing;
188 1         2 $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         3 push(@args, [ $thing, undef ]);
195             }
196             }
197              
198 2         7 return \@args;
199             }
200              
201             sub strip_attrs {
202 18     18 0 30 my $self = shift;
203 18         40 $self->skipspace;
204              
205 18         47 my $linestr = Devel::Declare::get_linestr;
206 18         31 my $attrs = '';
207              
208 18 100       32 if (substr($linestr, $self->offset, 1) eq ':') {
209 1         4 while (substr($linestr, $self->offset, 1) ne '{') {
210 2 100       6 if (substr($linestr, $self->offset, 1) eq ':') {
211 1         2 substr($linestr, $self->offset, 1) = '';
212 1         3 Devel::Declare::set_linestr($linestr);
213              
214 1         2 $attrs .= ':';
215             }
216              
217 2         6 $self->skipspace;
218 2         6 $linestr = Devel::Declare::get_linestr();
219              
220 2 100       5 if (my $len = Devel::Declare::toke_scan_word($self->offset, 0)) {
221 1         4 my $name = substr($linestr, $self->offset, $len);
222 1         3 substr($linestr, $self->offset, $len) = '';
223 1         3 Devel::Declare::set_linestr($linestr);
224              
225 1         2 $attrs .= " ${name}";
226              
227 1 50       38 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         4 $linestr = Devel::Declare::get_linestr();
241             }
242              
243 18         48 return $attrs;
244             }
245              
246              
247             sub get_curstash_name {
248 54     54 0 158 return Devel::Declare::get_curstash_name;
249             }
250              
251             sub shadow {
252 36     36 0 266 my $self = shift;
253 36         75 my $pack = $self->get_curstash_name;
254 36         132 Devel::Declare::shadow_sub( $pack . '::' . $self->declarator, $_[0] );
255             }
256              
257             sub inject_if_block {
258 36     36 0 171 my $self = shift;
259 36         66 my $inject = shift;
260 36   100     163 my $before = shift || '';
261              
262 36         153 $self->skipspace;
263              
264 36         88 my $linestr = $self->get_linestr;
265 36 100       71 if (substr($linestr, $self->offset, 1) eq '{') {
266 33         68 substr($linestr, $self->offset + 1, 0) = $inject;
267 33         66 substr($linestr, $self->offset, 0) = $before;
268 33         83 $self->set_linestr($linestr);
269 33         74 return 1;
270             }
271 3         7 return 0;
272             }
273              
274             sub scope_injector_call {
275 24     24 0 192 my $self = shift;
276 24   50     99 my $inject = shift || '';
277 24         98 return ' BEGIN { ' . ref($self) . "->inject_scope('${inject}') }; ";
278             }
279              
280             sub inject_scope {
281 21     21 0 179 my $class = shift;
282 21         44 my $inject = shift;
283             on_scope_end {
284 21     21   1095 my $linestr = Devel::Declare::get_linestr;
285 21 50       70 return unless defined $linestr;
286 21         67 my $offset = Devel::Declare::get_linestr_offset;
287 21         124 substr( $linestr, $offset, 0 ) = ';' . $inject;
288 21         73 Devel::Declare::set_linestr($linestr);
289 21         148 };
290             }
291              
292             1;
293             # vi:sw=2 ts=2