Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Perl/Critic/Policy/ValuesAndExpressions/RequireConstantVersion.pm |
Statements | Executed 30 statements in 1.19ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 16µs | 33µs | BEGIN@25 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 16µs | 16µs | BEGIN@10 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 16µs | 18µs | supported_parameters | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 8µs | 37µs | BEGIN@20 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 8µs | 44µs | BEGIN@14 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 8µs | 384µs | BEGIN@15 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 8µs | 678µs | BEGIN@16 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 7µs | 76µs | BEGIN@27 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 7µs | 10µs | BEGIN@12 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 7µs | 18µs | BEGIN@11 | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
1 | 1 | 1 | 6µs | 7µs | default_severity | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _check_for_assignment_operator | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _validate_operator_bind_regex | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _validate_word_qv | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _validate_word_token | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _validate_word_version | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | _validate_word_vstring | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | applies_to | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | default_themes | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
0 | 0 | 0 | 0s | 0s | violates | Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | ############################################################################## | ||||
2 | # $URL$ | ||||
3 | # $Date$ | ||||
4 | # $Author$ | ||||
5 | # $Revision$ | ||||
6 | ############################################################################## | ||||
7 | |||||
8 | package Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion; | ||||
9 | |||||
10 | 2 | 38µs | 1 | 16µs | # spent 16µs within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@10 which was called:
# once (16µs+0s) by Module::Pluggable::Object::_require at line 10 # spent 16µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@10 |
11 | 2 | 19µs | 2 | 28µs | # spent 18µs (7+11) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@11 which was called:
# once (7µs+11µs) by Module::Pluggable::Object::_require at line 11 # spent 18µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@11
# spent 11µs making 1 call to strict::import |
12 | 2 | 22µs | 2 | 14µs | # spent 10µs (7+3) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@12 which was called:
# once (7µs+3µs) by Module::Pluggable::Object::_require at line 12 # spent 10µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@12
# spent 4µs making 1 call to warnings::import |
13 | |||||
14 | 2 | 22µs | 2 | 81µs | # spent 44µs (8+36) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@14 which was called:
# once (8µs+36µs) by Module::Pluggable::Object::_require at line 14 # spent 44µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@14
# spent 36µs making 1 call to Exporter::import |
15 | 2 | 27µs | 2 | 760µs | # spent 384µs (8+376) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@15 which was called:
# once (8µs+376µs) by Module::Pluggable::Object::_require at line 15 # spent 384µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@15
# spent 376µs making 1 call to English::import |
16 | 1 | 300ns | # spent 678µs (8+670) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@16 which was called:
# once (8µs+670µs) by Module::Pluggable::Object::_require at line 19 | ||
17 | :booleans :characters :classification :data_conversion :language | ||||
18 | :severities | ||||
19 | 1 | 27µs | 2 | 1.35ms | >; # spent 678µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@16
# spent 670µs making 1 call to Exporter::import |
20 | 1 | 400ns | # spent 37µs (8+29) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@20 which was called:
# once (8µs+29µs) by Module::Pluggable::Object::_require at line 24 | ||
21 | is_ppi_constant_element | ||||
22 | get_next_element_in_same_simple_statement | ||||
23 | get_previous_module_used_on_same_line | ||||
24 | 1 | 20µs | 2 | 67µs | }; # spent 37µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@20
# spent 29µs making 1 call to Exporter::import |
25 | 2 | 22µs | 2 | 50µs | # spent 33µs (16+17) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@25 which was called:
# once (16µs+17µs) by Module::Pluggable::Object::_require at line 25 # spent 33µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@25
# spent 17µs making 1 call to Exporter::import |
26 | |||||
27 | 2 | 952µs | 2 | 145µs | # spent 76µs (7+69) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@27 which was called:
# once (7µs+69µs) by Module::Pluggable::Object::_require at line 27 # spent 76µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::BEGIN@27
# spent 69µs making 1 call to base::import |
28 | |||||
29 | 1 | 600ns | our $VERSION = '1.121'; | ||
30 | |||||
31 | #----------------------------------------------------------------------------- | ||||
32 | |||||
33 | 1 | 2µs | 1 | 30µs | Readonly::Scalar my $BIND_REGEX => q<=~>; # spent 30µs making 1 call to Readonly::Scalar |
34 | 1 | 900ns | 1 | 22µs | Readonly::Scalar my $DOLLAR => q<$>; # spent 22µs making 1 call to Readonly::Scalar |
35 | # All uses of the $DOLLAR variable below are to prevent false failures in | ||||
36 | # xt/author/93_version.t. | ||||
37 | 1 | 800ns | 1 | 20µs | Readonly::Scalar my $QV => q<qv>; # spent 20µs making 1 call to Readonly::Scalar |
38 | 1 | 800ns | 1 | 20µs | Readonly::Scalar my $VERSION_MODULE => q<version>; # spent 20µs making 1 call to Readonly::Scalar |
39 | 1 | 4µs | 2 | 22µs | Readonly::Scalar my $VERSION_VARIABLE => $DOLLAR . q<VERSION>; # spent 20µs making 1 call to Readonly::Scalar
# spent 1µs making 1 call to Readonly::Scalar::FETCH |
40 | |||||
41 | # Operators which would make a new value our of our $VERSION, and therefore | ||||
42 | # not modify it. I'm sure this list is not exhaustive. The logical operators | ||||
43 | # generally do not qualify for this list. At least, I think not. | ||||
44 | 1 | 5µs | 2 | 52µs | Readonly::Hash my %OPERATOR_WHICH_MAKES_NEW_VALUE => hashify( qw{ # spent 44µs making 1 call to Readonly::Hash
# spent 7µs making 1 call to Perl::Critic::Utils::hashify |
45 | = . + - * ** / % ^ ~ & | > < == != >= <= eq ne gt lt ge le | ||||
46 | } ); | ||||
47 | |||||
48 | 1 | 4µs | 2 | 22µs | Readonly::Scalar my $DESC => $DOLLAR . q<VERSION value must be a constant>; # spent 21µs making 1 call to Readonly::Scalar
# spent 1µs making 1 call to Readonly::Scalar::FETCH |
49 | 1 | 3µs | 2 | 21µs | Readonly::Scalar my $EXPL => qq<Computed ${DOLLAR}VERSION may tie the code to a single repository, or cause spooky action from a distance>; # spent 20µs making 1 call to Readonly::Scalar
# spent 1µs making 1 call to Readonly::Scalar::FETCH |
50 | |||||
51 | #----------------------------------------------------------------------------- | ||||
52 | |||||
53 | # spent 18µs (16+3) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::supported_parameters which was called:
# once (16µs+3µs) by Perl::Critic::Policy::new at line 88 of Perl/Critic/Policy.pm | ||||
54 | { | ||||
55 | 1 | 12µs | 2 | 3µs | name => 'allow_version_without_use_on_same_line', # spent 3µs making 2 calls to Readonly::Scalar::FETCH, avg 1µs/call |
56 | description => | ||||
57 | q{Allow qv() and version->new() without a 'use version' on the same line.}, | ||||
58 | default_string => $FALSE, | ||||
59 | behavior => 'boolean', | ||||
60 | } | ||||
61 | ); | ||||
62 | } | ||||
63 | 1 | 1µs | # spent 7µs (6+1) within Perl::Critic::Policy::ValuesAndExpressions::RequireConstantVersion::default_severity which was called:
# once (6µs+1µs) by Perl::Critic::Policy::get_severity at line 331 of Perl/Critic/Policy.pm | ||
64 | sub default_themes { return qw( core maintenance ) } | ||||
65 | sub applies_to { return 'PPI::Token::Symbol' } | ||||
66 | |||||
67 | #----------------------------------------------------------------------------- | ||||
68 | |||||
69 | sub violates { | ||||
70 | my ( $self, $elem, $doc ) = @_; | ||||
71 | |||||
72 | # Any variable other than $VERSION is ignored. | ||||
73 | return if $VERSION_VARIABLE ne $elem->content(); | ||||
74 | |||||
75 | # Get the next thing (presumably an operator) after $VERSION. The $VERSION | ||||
76 | # might be in a list, so if we get nothing we move upwards until we hit a | ||||
77 | # simple statement. If we have nothing at this point, we do not understand | ||||
78 | # the code, and so we return. | ||||
79 | my $operator; | ||||
80 | return if | ||||
81 | not $operator = get_next_element_in_same_simple_statement( $elem ); | ||||
82 | |||||
83 | # If the next operator is a regex binding, and its other operand is a | ||||
84 | # substitution operator, it is an attempt to modify $VERSION, so we | ||||
85 | # return an error to that effect. | ||||
86 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
87 | if $self->_validate_operator_bind_regex( $operator, $elem ); | ||||
88 | |||||
89 | # If the presumptive operator is not an assignment operator of some sort, | ||||
90 | # we are not modifying $VERSION at all, and so we just return. | ||||
91 | return if not $operator = _check_for_assignment_operator( $operator ); | ||||
92 | |||||
93 | # If there is no operand to the right of the assignment, we do not | ||||
94 | # understand the code; simply return. | ||||
95 | my $value; | ||||
96 | return if not $value = $operator->snext_sibling(); | ||||
97 | |||||
98 | # If the value is symbol '$VERSION', just return as we will see it again | ||||
99 | # later. | ||||
100 | return if | ||||
101 | $value->isa( 'PPI::Token::Symbol' ) | ||||
102 | and $value->content() eq $VERSION_VARIABLE; | ||||
103 | |||||
104 | # If the value is a word, there are a number of acceptable things it could | ||||
105 | # be. Check for these. If there was a problem, return it. | ||||
106 | $value = $self->_validate_word_token( $elem, $value ); | ||||
107 | return $value if $value->isa( 'Perl::Critic::Exception' ); | ||||
108 | |||||
109 | # If the value is anything but a constant, we cry foul. | ||||
110 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
111 | if not is_ppi_constant_element( $value ); | ||||
112 | |||||
113 | # If we have nothing after the value, it is OK. | ||||
114 | my $structure; | ||||
115 | return if | ||||
116 | not $structure = get_next_element_in_same_simple_statement( $value ); | ||||
117 | |||||
118 | # If we have a semicolon after the value, it is OK. | ||||
119 | return if $SCOLON eq $structure->content(); | ||||
120 | |||||
121 | # If there is anything else after the value, we cry foul. | ||||
122 | return $self->violation( $DESC, $EXPL, $elem ); | ||||
123 | } | ||||
124 | |||||
125 | #----------------------------------------------------------------------------- | ||||
126 | |||||
127 | # Check for an assignment operator. This is made more complicated by the fact | ||||
128 | # that PPI parses things like '||=' as two PPI::Token::Operators: '||' and | ||||
129 | # '='. So we take the first presumptive operator as an argument. If it is not | ||||
130 | # a PPI::Token::Operator, we return. If it's '=', we return it. If it is any | ||||
131 | # other operator, we see if the next significant token is '=', and if so | ||||
132 | # return that. | ||||
133 | |||||
134 | sub _check_for_assignment_operator { | ||||
135 | my ( $operator ) = @_; | ||||
136 | |||||
137 | return if not $operator->isa( 'PPI::Token::Operator' ); | ||||
138 | return $operator if $EQUAL eq $operator->content(); | ||||
139 | |||||
140 | my $next; | ||||
141 | return if not $next = $operator->snext_sibling(); | ||||
142 | return if not $next->isa( 'PPI::Token::Operator' ); | ||||
143 | return $next if $EQUAL eq $next->content(); | ||||
144 | |||||
145 | return; | ||||
146 | } | ||||
147 | |||||
148 | #----------------------------------------------------------------------------- | ||||
149 | |||||
150 | # Validate a bind_regex ('=~') operator appearing after $VERSION. We return | ||||
151 | # true if the operator is in fact '=~', and its next sibling isa | ||||
152 | # PPI::Token::Regexp::Substitute. Otherwise we return false. | ||||
153 | |||||
154 | sub _validate_operator_bind_regex { | ||||
155 | my ( $self, $operator, $elem ) = @_; | ||||
156 | |||||
157 | # We are not interested in anything but '=~ s/../../'. | ||||
158 | return if $BIND_REGEX ne $operator->content(); | ||||
159 | my $operand; | ||||
160 | return if not $operand = $operator->snext_sibling(); | ||||
161 | return if not $operand->isa( 'PPI::Token::Regexp::Substitute' ); | ||||
162 | |||||
163 | # The substitution is OK if it is of the form | ||||
164 | # '($var = $VERSION) =~ s/../../'. | ||||
165 | |||||
166 | # We can't look like the desired form if we have a next sig. sib. | ||||
167 | return $TRUE if $elem->snext_sibling(); | ||||
168 | |||||
169 | # We can't look like the desired form if we are not in a list. | ||||
170 | my $containing_list; | ||||
171 | $containing_list = $elem->parent() | ||||
172 | and $containing_list->isa( 'PPI::Statement' ) | ||||
173 | and $containing_list = $containing_list->parent() | ||||
174 | and $containing_list->isa( 'PPI::Structure::List' ) | ||||
175 | or return $TRUE; | ||||
176 | |||||
177 | # If we have no prior element, we're ( $VERSION ) =~ s/../../, | ||||
178 | # which flunks. | ||||
179 | my $prior = $elem->sprevious_sibling() or return $TRUE; | ||||
180 | |||||
181 | # If the prior element is an operator which makes a new value, we pass. | ||||
182 | return if $prior->isa( 'PPI::Token::Operator' ) | ||||
183 | && $OPERATOR_WHICH_MAKES_NEW_VALUE{ $prior->content() }; | ||||
184 | |||||
185 | # Now things get complicated, as RT #55600 shows. We need to grub through | ||||
186 | # the entire list, looking for something that looks like a subroutine | ||||
187 | # call, but without parens around the argument list. This catches the | ||||
188 | # ticket's case, which was | ||||
189 | # ( $foo = sprintf '%s/%s', __PACKAGE__, $VERSION ) =~ s/../../. | ||||
190 | my $current = $prior; | ||||
191 | while( $prior = $current->sprevious_sibling() ) { | ||||
192 | $prior->isa( 'PPI::Token::Word' ) or next; | ||||
193 | is_function_call( $prior) or next; | ||||
194 | # If this function has its own argument list, we need to keep looking; | ||||
195 | # otherwise we have found a function with no parens, and we can | ||||
196 | # return. | ||||
197 | $current->isa( 'PPI::Structure::List' ) | ||||
198 | or return; | ||||
199 | } continue { | ||||
200 | $current = $prior; | ||||
201 | } | ||||
202 | |||||
203 | # Maybe the whole list was arguments for a subroutine or method call. | ||||
204 | $prior = $containing_list->sprevious_sibling() | ||||
205 | or return $TRUE; | ||||
206 | if ( $prior->isa( 'PPI::Token::Word' ) ) { | ||||
207 | return if is_method_call( $prior ); | ||||
208 | return if is_function_call( $prior ); | ||||
209 | } | ||||
210 | |||||
211 | # Anything left is presumed a violation. | ||||
212 | return $TRUE; | ||||
213 | } | ||||
214 | |||||
215 | #----------------------------------------------------------------------------- | ||||
216 | |||||
217 | # Validating a PPI::Token::Word is a complicated business, so we split it out | ||||
218 | # into its own subroutine. The $elem is to be used in forming the error | ||||
219 | # message, and the $value is the PPI::Token::Word we just encountered. The | ||||
220 | # return is either a PPI::Element for further analysis, or a | ||||
221 | # Perl::Critic::Exception to be returned. | ||||
222 | |||||
223 | sub _validate_word_token { | ||||
224 | my ( $self, $elem, $value ) = @_; | ||||
225 | |||||
226 | if ( $value->isa( 'PPI::Token::Word' ) ) { | ||||
227 | my $content = $value->content(); | ||||
228 | |||||
229 | # If the word is of the form 'v\d+' it may be the first portion of a | ||||
230 | # misparsed (by PPI) v-string. It is really a v-string if the next | ||||
231 | # element is a number. Unless v-strings are allowed, we return an | ||||
232 | # error. | ||||
233 | if ( $content =~ m/ \A v \d+ \z /smx ) { | ||||
234 | $value = $self->_validate_word_vstring( $elem, $value ); | ||||
235 | } | ||||
236 | elsif ( $QV eq $content ) { | ||||
237 | # If the word is 'qv' we suspect use of the version module. If | ||||
238 | # 'use version' appears on the same line, _and_ the remainder of | ||||
239 | # the expression is of the form '(value)', we extract the value | ||||
240 | # for further analysis. | ||||
241 | |||||
242 | $value = $self->_validate_word_qv( $elem, $value ); | ||||
243 | } | ||||
244 | elsif ( $VERSION_MODULE eq $content ) { | ||||
245 | # If the word is 'version' we suspect use of the version module. | ||||
246 | # Check to see if it is properly used. | ||||
247 | $value = $self->_validate_word_version( $elem, $value ); | ||||
248 | } | ||||
249 | } | ||||
250 | |||||
251 | return $value; | ||||
252 | } | ||||
253 | |||||
254 | #----------------------------------------------------------------------------- | ||||
255 | |||||
256 | # Validate $VERSION = v1.2.3; | ||||
257 | # Note that this is needed because PPI mis-parses the 'v1.2.3' construct into | ||||
258 | # a word ('v1') and a number of some sort ('.2.3'). This method should only be | ||||
259 | # called if it is already known that the $value is a PPI::Token::Word matching | ||||
260 | # m/ \A v \d+ \z /smx; | ||||
261 | |||||
262 | sub _validate_word_vstring { | ||||
263 | my ( $self, $elem, $value ) = @_; | ||||
264 | |||||
265 | # Check for the second part of the mis-parsed v-string, flunking if it is | ||||
266 | # not found. | ||||
267 | my $next; | ||||
268 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
269 | if | ||||
270 | not $next = $value->snext_sibling() | ||||
271 | or not $next->isa( 'PPI::Token::Number' ); | ||||
272 | |||||
273 | # Return the second part of the v-string for further analysis. | ||||
274 | return $next; | ||||
275 | } | ||||
276 | |||||
277 | #----------------------------------------------------------------------------- | ||||
278 | |||||
279 | # Validate $VERSION = qv(); | ||||
280 | |||||
281 | sub _validate_word_qv { | ||||
282 | my ( $self, $elem, $value ) = @_; | ||||
283 | |||||
284 | # Unless we are specifically allowing this construction without the | ||||
285 | # 'use version;' on the same line, check for it and flunk if we do not | ||||
286 | # find it. | ||||
287 | $self->{_allow_version_without_use_on_same_line} | ||||
288 | or do { | ||||
289 | my $module; | ||||
290 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
291 | if not | ||||
292 | $module = get_previous_module_used_on_same_line($value); | ||||
293 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
294 | if $VERSION_MODULE ne $module->content(); | ||||
295 | }; | ||||
296 | |||||
297 | # Dig out the first argument of 'qv()', flunking if we can not find it. | ||||
298 | my $next; | ||||
299 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
300 | if not ( | ||||
301 | $next = $value->snext_sibling() | ||||
302 | and $next->isa( 'PPI::Structure::List' ) | ||||
303 | and $next = $next->schild( 0 ) | ||||
304 | and $next->isa( 'PPI::Statement::Expression' ) | ||||
305 | and $next = $next->schild( 0 ) | ||||
306 | ); | ||||
307 | |||||
308 | # Return the qv() argument for further analysis. | ||||
309 | return $next; | ||||
310 | } | ||||
311 | |||||
312 | #----------------------------------------------------------------------------- | ||||
313 | |||||
314 | # Validate $VERSION = version->new(); | ||||
315 | |||||
316 | # TODO: Fix this EVIL dual-purpose return value. This is ugggggleeeee. | ||||
317 | sub _validate_word_version { | ||||
318 | my ( $self, $elem, $value ) = @_; | ||||
319 | |||||
320 | # Unless we are specifically allowing this construction without the | ||||
321 | # 'use version;' on the same line, check for it and flunk if we do not | ||||
322 | # find it. | ||||
323 | $self->{_allow_version_without_use_on_same_line} | ||||
324 | or do { | ||||
325 | my $module; | ||||
326 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
327 | if not | ||||
328 | $module = get_previous_module_used_on_same_line($value); | ||||
329 | return $self->violation( $DESC, $EXPL, $elem ) | ||||
330 | if $VERSION_MODULE ne $module->content(); | ||||
331 | }; | ||||
332 | |||||
333 | # Dig out the first argument of '->new()', flunking if we can not find it. | ||||
334 | my $next; | ||||
335 | return $next if | ||||
336 | $next = $value->snext_sibling() | ||||
337 | and $next->isa( 'PPI::Token::Operator' ) | ||||
338 | and q{->} eq $next->content() | ||||
339 | and $next = $next->snext_sibling() | ||||
340 | and $next->isa( 'PPI::Token::Word' ) | ||||
341 | and q{new} eq $next->content() | ||||
342 | and $next = $next->snext_sibling() | ||||
343 | and $next->isa( 'PPI::Structure::List' ) | ||||
344 | and $next = $next->schild( 0 ) | ||||
345 | and $next->isa( 'PPI::Statement::Expression' ) | ||||
346 | and $next = $next->schild( 0 ); | ||||
347 | |||||
348 | return $self->violation( $DESC, $EXPL, $elem ); | ||||
349 | } | ||||
350 | |||||
351 | 1 | 9µs | 1; | ||
352 | |||||
353 | __END__ |