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   1144 use strict;
  6         14  
  6         178  
4 6     6   29 use warnings;
  6         13  
  6         162  
5 6     6   1943 use Devel::Declare ();
  6         33  
  6         142  
6 6     6   2939 use B::Hooks::EndOfScope;
  6         72162  
  6         45  
7 6     6   447 use Carp qw/confess/;
  6         16  
  6         10677  
8              
9             our $VERSION = '0.006_020';
10             $VERSION =~ tr/_//d;
11              
12             sub new {
13 23     23 0 88 my $class = shift;
14 23         120 bless {@_}, $class;
15             }
16              
17             sub init {
18 36     36 0 73 my $self = shift;
19 36         59 @{$self}{ qw(Declarator Offset WarningOnRedefined) } = @_;
  36         155  
20 36         86 return $self;
21             }
22              
23             sub offset {
24 606     606 0 941 my $self = shift;
25             return $self->{Offset}
26 606         1827 }
27              
28             sub inc_offset {
29 213     213 0 336 my $self = shift;
30 213         366 $self->{Offset} += shift;
31             }
32              
33             sub declarator {
34 76     76 0 150 my $self = shift;
35             return $self->{Declarator}
36 76         221 }
37              
38             sub warning_on_redefine {
39 11     11 0 23 my $self = shift;
40             return $self->{WarningOnRedefined}
41 11         70 }
42              
43             sub skip_declarator {
44 36     36 0 92 my $self = shift;
45 36         88 my $decl = $self->declarator;
46 36         98 my $len = Devel::Declare::toke_scan_word($self->offset, 0);
47 36 50       99 confess "Couldn't find declarator '$decl'"
48             unless $len;
49              
50 36         85 my $linestr = $self->get_linestr;
51 36         96 my $name = substr($linestr, $self->offset, $len);
52 36 50       114 confess "Expected declarator '$decl', got '${name}'"
53             unless $name eq $decl;
54              
55 36         85 $self->inc_offset($len);
56             }
57              
58             sub skipspace {
59 177     177 0 282 my $self = shift;
60 177         2505 $self->inc_offset(Devel::Declare::toke_skipspace($self->offset));
61             }
62              
63             sub get_linestr {
64 179     179 0 329 my $self = shift;
65 179         435 my $line = Devel::Declare::get_linestr();
66 179         353 return $line;
67             }
68              
69             sub set_linestr {
70 97     97 0 184 my $self = shift;
71 97         199 my ($line) = @_;
72 97         249 Devel::Declare::set_linestr($line);
73             }
74              
75             sub strip_name {
76 54     54 0 176 my $self = shift;
77 54         128 $self->skipspace;
78 54 100       148 if (my $len = Devel::Declare::toke_scan_word( $self->offset, 1 )) {
79 34         75 my $linestr = $self->get_linestr();
80 34         80 my $name = substr( $linestr, $self->offset, $len );
81 34         81 substr( $linestr, $self->offset, $len ) = '';
82 34         148 $self->set_linestr($linestr);
83 34         146 return $name;
84             }
85              
86 20         47 $self->skipspace;
87 20         40 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 92 my $self = shift;
107 38         112 $self->skipspace;
108              
109 38         75 my $linestr = $self->get_linestr();
110 38 100       81 if (substr($linestr, $self->offset, 1) eq '(') {
111 26         53 my $length = Devel::Declare::toke_scan_str($self->offset);
112 26         84 my $proto = Devel::Declare::get_lex_stuff();
113 26         80 Devel::Declare::clear_lex_stuff();
114 26         47 $linestr = $self->get_linestr();
115              
116 26 100       52 substr($linestr, $self->offset,
117             defined($length) ? $length : length($linestr)) = '';
118 26         72 $self->set_linestr($linestr);
119              
120 26         110 return $proto;
121             }
122 12         33 return;
123             }
124              
125             sub strip_names_and_args {
126 2     2 0 12 my $self = shift;
127 2         5 $self->skipspace;
128              
129 2         4 my @args;
130              
131 2         24 my $linestr = $self->get_linestr;
132 2 100       23 if (substr($linestr, $self->offset, 1) eq '(') {
133             # We had a leading paren, so we will now expect comma separated
134             # arguments
135 1         3 substr($linestr, $self->offset, 1) = '';
136 1         3 $self->set_linestr($linestr);
137 1         2 $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         6 my $thing = $self->strip_name;
145             # If there's no bareword here, bail
146 3 50       9 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         5 push(@args, [ $thing, $self->strip_proto ]);
153             } else {
154             # This had no proto, so store it with an undef
155 1         3 push(@args, [ $thing, undef ]);
156             }
157 3         9 $self->skipspace;
158 3         5 $linestr = $self->get_linestr;
159              
160 3 100       6 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         12 substr($linestr, $self->offset, 1) = '';
164 2         6 $self->set_linestr($linestr);
165 2         4 $self->skipspace;
166             } else {
167             # No comma, get outta here
168 1         3 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         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         3 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       3 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 32 my $self = shift;
203 18         59 $self->skipspace;
204              
205 18         53 my $linestr = Devel::Declare::get_linestr;
206 18         30 my $attrs = '';
207              
208 18 100       35 if (substr($linestr, $self->offset, 1) eq ':') {
209 1         3 while (substr($linestr, $self->offset, 1) ne '{') {
210 2 100       6 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         6 $self->skipspace;
218 2         5 $linestr = Devel::Declare::get_linestr();
219              
220 2 100       5 if (my $len = Devel::Declare::toke_scan_word($self->offset, 0)) {
221 1         3 my $name = substr($linestr, $self->offset, $len);
222 1         2 substr($linestr, $self->offset, $len) = '';
223 1         5 Devel::Declare::set_linestr($linestr);
224              
225 1         2 $attrs .= " ${name}";
226              
227 1 50       3 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         41 $linestr = Devel::Declare::get_linestr();
241             }
242              
243 18         45 return $attrs;
244             }
245              
246              
247             sub get_curstash_name {
248 54     54 0 173 return Devel::Declare::get_curstash_name;
249             }
250              
251             sub shadow {
252 36     36 0 270 my $self = shift;
253 36         76 my $pack = $self->get_curstash_name;
254 36         100 Devel::Declare::shadow_sub( $pack . '::' . $self->declarator, $_[0] );
255             }
256              
257             sub inject_if_block {
258 36     36 0 264 my $self = shift;
259 36         100 my $inject = shift;
260 36   100     142 my $before = shift || '';
261              
262 36         89 $self->skipspace;
263              
264 36         67 my $linestr = $self->get_linestr;
265 36 100       82 if (substr($linestr, $self->offset, 1) eq '{') {
266 33         82 substr($linestr, $self->offset + 1, 0) = $inject;
267 33         68 substr($linestr, $self->offset, 0) = $before;
268 33         81 $self->set_linestr($linestr);
269 33         87 return 1;
270             }
271 3         7 return 0;
272             }
273              
274             sub scope_injector_call {
275 24     24 0 207 my $self = shift;
276 24   50     113 my $inject = shift || '';
277 24         101 return ' BEGIN { ' . ref($self) . "->inject_scope('${inject}') }; ";
278             }
279              
280             sub inject_scope {
281 21     21 0 170 my $class = shift;
282 21         40 my $inject = shift;
283             on_scope_end {
284 21     21   1194 my $linestr = Devel::Declare::get_linestr;
285 21 50       70 return unless defined $linestr;
286 21         52 my $offset = Devel::Declare::get_linestr_offset;
287 21         61 substr( $linestr, $offset, 0 ) = ';' . $inject;
288 21         86 Devel::Declare::set_linestr($linestr);
289 21         131 };
290             }
291              
292             1;
293             # vi:sw=2 ts=2