File Coverage

lib/Perl/PrereqScanner/NotQuiteLite/Context.pm
Criterion Covered Total %
statement 183 208 87.9
branch 105 136 77.2
condition 6 12 50.0
subroutine 49 56 87.5
pod 12 46 26.0
total 355 458 77.5


line stmt bran cond sub pod time code
1             package Perl::PrereqScanner::NotQuiteLite::Context;
2              
3 102     102   547 use strict;
  102         200  
  102         2876  
4 102     102   348 use warnings;
  102         192  
  102         3585  
5 102     102   41680 use CPAN::Meta::Requirements;
  102         644739  
  102         3101  
6 102     102   36730 use Regexp::Trie;
  102         51081  
  102         3259  
7 102     102   38928 use Perl::PrereqScanner::NotQuiteLite::Util;
  102         332  
  102         272669  
8              
9             my %defined_keywords = _keywords();
10              
11             my %default_op_keywords = map {$_ => 1} qw(
12             x eq ne and or xor cmp ge gt le lt not
13             );
14              
15             my %default_conditional_keywords = map {$_ => 1} qw(
16             if elsif unless else
17             );
18              
19             my %default_expects_expr_block = map {$_ => 1} qw(
20             if elsif unless given when
21             for foreach while until
22             );
23              
24             my %default_expects_block_list = map {$_ => 1} qw(
25             map grep sort
26             );
27              
28             my %default_expects_fh_list = map {$_ => 1} qw(
29             print printf say
30             );
31              
32             my %default_expects_fh_or_block_list = (
33             %default_expects_block_list,
34             %default_expects_fh_list,
35             );
36              
37             my %default_expects_block = map {$_ => 1} qw(
38             else default
39             eval sub do while until continue
40             BEGIN END INIT CHECK
41             if elsif unless given when
42             for foreach while until
43             map grep sort
44             );
45              
46             my %default_expects_word = map {$_ => 1} qw(
47             use require no sub
48             );
49              
50             my %enables_utf8 = map {$_ => 1} qw(
51             utf8
52             Mojo::Base
53             Mojo::Base::Che
54             );
55              
56             my $default_g_re_prototype = qr{\G(\([^\)]*?\))};
57              
58             sub new {
59 781     781 1 2630 my ($class, %args) = @_;
60              
61             my %context = (
62             requires => CPAN::Meta::Requirements->new,
63             noes => CPAN::Meta::Requirements->new,
64             file => $args{file},
65             verbose => $args{verbose},
66             optional => $args{optional},
67 781         4066 stash => {},
68             );
69              
70 781 100 66     20926 if ($args{suggests} or $args{recommends}) {
71 157         355 $context{recommends} = CPAN::Meta::Requirements->new;
72             }
73 781 100       2918 if ($args{suggests}) {
74 157         354 $context{suggests} = CPAN::Meta::Requirements->new;
75             }
76 781 100       2648 if ($args{perl_minimum_version}) {
77 83         134 $context{perl} = CPAN::Meta::Requirements->new;
78             }
79 781         2061 for my $type (qw/use no method keyword sub/) {
80 3905 100       8113 if (exists $args{_}{$type}) {
81 3115         3764 for my $key (keys %{$args{_}{$type}}) {
  3115         21138  
82 143905         155541 $context{$type}{$key} = [@{$args{_}{$type}{$key}}];
  143905         308302  
83             }
84             }
85             }
86              
87 781         3639 bless \%context, $class;
88             }
89              
90 38     38 0 159 sub stash { shift->{stash} }
91              
92             sub register_keyword_parser {
93 441     441 1 733 my ($self, $keyword, $parser_info) = @_;
94 441         928 $self->{keyword}{$keyword} = $parser_info;
95 441         1060 $self->{defined_keywords}{$keyword} = 0;
96             }
97              
98             sub remove_keyword_parser {
99 2     2 1 4 my ($self, $keyword) = @_;
100 2         4 delete $self->{keyword}{$keyword};
101 2 50       3 delete $self->{keyword} if !%{$self->{keyword}};
  2         4  
102 2         5 delete $self->{defined_keywords}{$keyword};
103             }
104              
105             sub register_method_parser {
106 2     2 1 4 my ($self, $method, $parser_info) = @_;
107 2         17 $self->{method}{$method} = $parser_info;
108             }
109              
110             *register_keyword = \®ister_keyword_parser;
111             *remove_keyword = \&remove_keyword_parser;
112             *register_method = \®ister_method_parser;
113              
114             sub register_sub_parser {
115 207     207 1 332 my ($self, $keyword, $parser_info) = @_;
116 207         496 $self->{sub}{$keyword} = $parser_info;
117 207         416 $self->{defined_keywords}{$keyword} = 0;
118             }
119              
120 636     636 1 4552 sub requires { shift->{requires} }
121 125     125 0 64315 sub recommends { shift->_optional('recommends') }
122 155     155 1 188874 sub suggests { shift->_optional('suggests') }
123 10     10 0 13227 sub noes { shift->{noes} }
124              
125             sub _optional {
126 280     280   562 my ($self, $key) = @_;
127 280 50       758 my $optional = $self->{$key} or return;
128              
129             # no need to recommend/suggest what are listed as requires
130 280 50       660 if (my $requires = $self->{requires}) {
131 280         720 my $hash = $optional->as_string_hash;
132 280         6194 for my $module (keys %$hash) {
133 102 50 33     472 if (defined $requires->requirements_for_module($module) and
134             $requires->accepts_module($module, $hash->{$module})
135             ) {
136 0         0 $optional->clear_requirement($module);
137             }
138             }
139             }
140 280         1319 $optional;
141             }
142              
143             sub add {
144 1262     1262 1 4313 my $self = shift;
145 1262 100       2331 if ($self->{optional}) {
146 9         36 $self->_add('suggests', @_);
147             } else {
148 1253         2879 $self->_add('requires', @_);
149             }
150             }
151              
152             sub add_recommendation {
153 29     29 0 67 shift->_add('recommends', @_);
154             }
155              
156             sub add_suggestion {
157 8     8 0 15 shift->_add('suggests', @_);
158             }
159              
160             sub add_conditional {
161 89     89 0 678 shift->_add('conditional', @_);
162             }
163              
164             sub add_no {
165 32     32 0 110 shift->_add('noes', @_);
166             }
167              
168             sub add_perl {
169 268     268 0 505 my ($self, $perl, $reason) = @_;
170 268 100       645 return unless $self->{perl};
171 126         262 $self->_add('perl', 'perl', $perl);
172 126         15654 $self->{perl_minimum_version}{$reason} = $perl;
173             }
174              
175             sub _add {
176 1546     1546   3038 my ($self, $type, $module, $version) = @_;
177 1546 100       2952 return unless is_module_name($module);
178              
179 1545 100       3403 my $CMR = $self->_object($type) or return;
180 1528 100       2706 $version = 0 unless defined $version;
181 1528 50       2879 if ($self->{verbose}) {
182 0 0       0 if (!defined $CMR->requirements_for_module($module)) {
183 0         0 print STDERR " found $module $version ($type)\n";
184             }
185             }
186 1528         4953 $CMR->add_minimum($module, "$version");
187             }
188              
189             sub has_added {
190 0     0 1 0 shift->_has_added('requires', @_);
191             }
192              
193             sub has_added_recommendation {
194 0     0 0 0 shift->_has_added('recommends', @_);
195             }
196              
197             sub has_added_suggestion {
198 0     0 0 0 shift->_has_added('suggests', @_);
199             }
200              
201             sub has_added_conditional {
202 12     12 0 41 shift->_has_added('conditional', @_);
203             }
204              
205             sub has_added_no {
206 0     0 0 0 shift->_has_added('no', @_);
207             }
208              
209             sub _has_added {
210 12     12   27 my ($self, $type, $module) = @_;
211 12 50       35 return unless is_module_name($module);
212              
213 12 100       23 my $CMR = $self->_object($type) or return;
214 11 100       36 defined $CMR->requirements_for_module($module) ? 1 : 0;
215             }
216              
217             sub _object {
218 2296     2296   3470 my ($self, $key) = @_;
219 2296 100 100     8783 if ($self->{eval}) {
    100          
    100          
    100          
220 42         68 $key = 'suggests';
221             } elsif ($self->{force_cond}) {
222 7         12 $key = 'recommends';
223             } elsif ($key && $key eq 'conditional') {
224 87 100       166 if ($self->{cond}) {
    100          
225 16         31 $key = 'recommends';
226 25 50       130 } elsif (grep {$_->[0] eq '{' and $_->[2] ne 'BEGIN'} @{$self->{stack} || []}) {
  71 50       210  
227 17         31 $key = 'recommends';
228             } else {
229 54         78 $key = 'requires';
230             }
231             } elsif (!$key) {
232 735         1126 $key = 'requires';
233             }
234 2296 100       6575 $self->{$key} or return;
235             }
236              
237             sub has_callbacks {
238 0     0 1 0 my ($self, $type) = @_;
239 0         0 exists $self->{$type};
240             }
241              
242             sub has_callback_for {
243 945     945 1 1843 my ($self, $type, $name) = @_;
244 945         3713 exists $self->{$type}{$name};
245             }
246              
247             sub run_callback_for {
248 739     739 1 1675 my ($self, $type, $name, @args) = @_;
249 739 100       1532 return unless $self->_object;
250 737         1043 my ($parser, $method, @cb_args) = @{$self->{$type}{$name}};
  737         1982  
251 737         3635 $parser->$method($self, @cb_args, @args);
252             }
253              
254             sub prototype_re {
255 1638     1638 0 2266 my $self = shift;
256 1638 100       2923 if (@_) {
257 118         309 $self->{prototype_re} = shift;
258             }
259 1638 100       3679 return $default_g_re_prototype unless exists $self->{prototype_re};
260 207         548 $self->{prototype_re};
261             }
262              
263             sub quotelike_re {
264 212     212 0 363 my $self = shift;
265 212 100       1166 return qr/qq?/ unless exists $self->{quotelike_re};
266 1         2 $self->{quotelike_re};
267             }
268              
269             sub register_quotelike_keywords {
270 1     1 0 2 my ($self, @keywords) = @_;
271 1         3 push @{$self->{quotelike}}, @keywords;
  1         3  
272 1         24 $self->{defined_keywords}{$_} = 0 for @keywords;
273              
274 1         7 my $trie = Regexp::Trie->new;
275 1 50       4 $trie->add($_) for 'q', 'qq', @{$self->{quotelike} || []};
  1         5  
276 1         46 $self->{quotelike_re} = $trie->regexp;
277             }
278              
279             sub token_expects_block_list {
280 689     689 0 1104 my ($self, $token) = @_;
281 689 100       1464 return 1 if exists $default_expects_block_list{$token};
282 663 50       2064 return 0 if !exists $self->{expects_block_list};
283 0 0       0 return 1 if exists $self->{expects_block_list}{$token};
284 0         0 return 0;
285             }
286              
287             sub token_expects_fh_list {
288 0     0 0 0 my ($self, $token) = @_;
289 0 0       0 return 1 if exists $default_expects_fh_list{$token};
290 0 0       0 return 0 if !exists $self->{expects_fh_list};
291 0 0       0 return 1 if exists $self->{expects_fh_list}{$token};
292 0         0 return 0;
293             }
294              
295             sub token_expects_fh_or_block_list {
296 18     18 0 37 my ($self, $token) = @_;
297 18 100       57 return 1 if exists $default_expects_fh_or_block_list{$token};
298 3 50       15 return 0 if !exists $self->{expects_fh_or_block_list};
299 0 0       0 return 1 if exists $self->{expects_fh_or_block_list}{$token};
300 0         0 return 0;
301             }
302              
303             sub token_expects_expr_block {
304 571     571 0 1003 my ($self, $token) = @_;
305 571 100       1458 return 1 if exists $default_expects_expr_block{$token};
306 359 50       1120 return 0 if !exists $self->{expects_expr_block};
307 0 0       0 return 1 if exists $self->{expects_expr_block}{$token};
308 0         0 return 0;
309             }
310              
311             sub token_expects_block {
312 30373     30373 0 42587 my ($self, $token) = @_;
313 30373 100       51730 return 1 if exists $default_expects_block{$token};
314 27964 100       61071 return 0 if !exists $self->{expects_block};
315 2855 100       5123 return 1 if exists $self->{expects_block}{$token};
316 2375         4290 return 0;
317             }
318              
319             sub token_expects_word {
320 2904     2904 0 4655 my ($self, $token) = @_;
321 2904 100       8037 return 1 if exists $default_expects_word{$token};
322 1790 100       5529 return 0 if !exists $self->{expects_word};
323 394 100       1079 return 1 if exists $self->{expects_word}{$token};
324 194         483 return 0;
325             }
326              
327             sub token_is_conditional {
328 16     16 0 27 my ($self, $token) = @_;
329 16 100       32 return 1 if exists $default_conditional_keywords{$token};
330 14 50       41 return 0 if !exists $self->{is_conditional_keyword};
331 0 0       0 return 1 if exists $self->{is_conditional_keyword}{$token};
332 0         0 return 0;
333             }
334              
335             sub token_is_keyword {
336 6030     6030 0 9456 my ($self, $token) = @_;
337 6030 100       20911 return 1 if exists $defined_keywords{$token};
338 2359 100       6096 return 0 if !exists $self->{defined_keywords};
339 706 100       1713 return 1 if exists $self->{defined_keywords}{$token};
340 540         1259 return 0;
341             }
342              
343             sub token_is_op_keyword {
344 3817     3817 0 5543 my ($self, $token) = @_;
345 3817 100       6935 return 1 if exists $default_op_keywords{$token};
346 3654 100       8496 return 0 if !exists $self->{defined_op_keywords};
347 28 100       44 return 1 if exists $self->{defined_op_keywords}{$token};
348 27         40 return 0;
349             }
350              
351             sub register_keywords {
352 4     4 0 7 my ($self, @keywords) = @_;
353 4         7 for my $keyword (@keywords) {
354 6         17 $self->{defined_keywords}{$keyword} = 0;
355             }
356             }
357              
358             sub register_op_keywords {
359 1     1 0 3 my ($self, @keywords) = @_;
360 1         2 for my $keyword (@keywords) {
361 1         8 $self->{defined_op_keywords}{$keyword} = 0;
362             }
363             }
364              
365             sub remove_keywords {
366 0     0 0 0 my ($self, @keywords) = @_;
367 0         0 for my $keyword (@keywords) {
368 0 0 0     0 delete $self->{defined_keywords}{$keyword} if exists $self->{defined_keywords}{$keyword} and !$self->{defined_keywords}{$keyword};
369             }
370             }
371              
372             sub register_sub_keywords {
373 119     119 0 271 my ($self, @keywords) = @_;
374 119         254 for my $keyword (@keywords) {
375 395         599 $self->{defines_sub}{$keyword} = 1;
376 395         541 $self->{expects_block}{$keyword} = 1;
377 395         553 $self->{expects_word}{$keyword} = 1;
378 395         684 $self->{defined_keywords}{$keyword} = 0;
379             }
380             }
381              
382             sub token_defines_sub {
383 677     677 0 1222 my ($self, $token) = @_;
384 677 100       1950 return 1 if $token eq 'sub';
385 524 100       4197 return 0 if !exists $self->{defines_sub};
386 207 100       1216 return 1 if exists $self->{defines_sub}{$token};
387 9         119 return 0;
388             }
389              
390             sub enables_utf8 {
391 772     772 0 1298 my ($self, $module) = @_;
392 772 100       2339 exists $enables_utf8{$module} ? 1 : 0;
393             }
394              
395             sub add_package {
396 143     143 0 257 my ($self, $package) = @_;
397 143         579 $self->{packages}{$package} = 1;
398             }
399              
400             sub packages {
401 781     781 0 1580 my $self = shift;
402 781 100       1016 keys %{$self->{packages} || {}};
  781         4461  
403             }
404              
405             sub remove_inner_packages_from_requirements {
406 781     781 0 1191 my $self = shift;
407 781         1874 for my $package ($self->packages) {
408 139         306 for my $rel (qw/requires recommends suggests noes/) {
409 556 100       1884 next unless $self->{$rel};
410 280         783 $self->{$rel}->clear_requirement($package);
411             }
412             }
413             }
414              
415             sub merge_perl {
416 781     781 0 1127 my $self = shift;
417 781 100       1996 return unless $self->{perl};
418              
419 83         220 my $perl = $self->{requires}->requirements_for_module('perl');
420 83 100       650 if ($self->{perl}->accepts_module('perl', $perl)) {
421 11         86 delete $self->{perl_minimum_version};
422             } else {
423 72         1326 $self->add(perl => $self->{perl}->requirements_for_module('perl'));
424             }
425             }
426              
427             sub _keywords {
428 102     102   223 my $i = 1;
429 102         727 map {$_ => $i++} qw(
  27132         134500  
430             __CLASS__
431             __DATA__
432             __END__
433             __FILE__
434             __LINE__
435             __PACKAGE__
436             __SUB__
437             ADJUST
438             AUTOLOAD
439             BEGIN
440             CHECK
441             DESTROY
442             END
443             INIT
444             UNITCHECK
445             abs
446             accept
447             alarm
448             all
449             and
450             any
451             atan2
452             bind
453             binmode
454             bless
455             break
456             caller
457             catch
458             chdir
459             chmod
460             chomp
461             chop
462             chown
463             chr
464             chroot
465             class
466             close
467             closedir
468             cmp
469             connect
470             continue
471             cos
472             crypt
473             dbmclose
474             dbmopen
475             default
476             defer
477             defined
478             delete
479             die
480             do
481             dump
482             each
483             else
484             elsif
485             endgrent
486             endhostent
487             endnetent
488             endprotoent
489             endpwent
490             endservent
491             eof
492             eq
493             eval
494             evalbytes
495             exec
496             exists
497             exit
498             exp
499             fc
500             fcntl
501             field
502             fileno
503             finally
504             flock
505             for
506             foreach
507             fork
508             format
509             formline
510             ge
511             getc
512             getgrent
513             getgrgid
514             getgrnam
515             gethostbyaddr
516             gethostbyname
517             gethostent
518             getlogin
519             getnetbyaddr
520             getnetbyname
521             getnetent
522             getpeername
523             getpgrp
524             getppid
525             getpriority
526             getprotobyname
527             getprotobynumber
528             getprotoent
529             getpwent
530             getpwnam
531             getpwuid
532             getservbyname
533             getservbyport
534             getservent
535             getsockname
536             getsockopt
537             given
538             glob
539             gmtime
540             goto
541             grep
542             gt
543             hex
544             if
545             index
546             int
547             ioctl
548             isa
549             join
550             keys
551             kill
552             last
553             lc
554             lcfirst
555             le
556             length
557             link
558             listen
559             local
560             localtime
561             lock
562             log
563             lstat
564             lt
565             m
566             map
567             method
568             mkdir
569             msgctl
570             msgget
571             msgrcv
572             msgsnd
573             my
574             ne
575             next
576             no
577             not
578             oct
579             open
580             opendir
581             or
582             ord
583             our
584             pack
585             package
586             pipe
587             pop
588             pos
589             print
590             printf
591             prototype
592             push
593             q
594             qq
595             qr
596             quotemeta
597             qw
598             qx
599             rand
600             read
601             readdir
602             readline
603             readlink
604             readpipe
605             recv
606             redo
607             ref
608             rename
609             require
610             reset
611             return
612             reverse
613             rewinddir
614             rindex
615             rmdir
616             s
617             say
618             scalar
619             seek
620             seekdir
621             select
622             semctl
623             semget
624             semop
625             send
626             setgrent
627             sethostent
628             setnetent
629             setpgrp
630             setpriority
631             setprotoent
632             setpwent
633             setservent
634             setsockopt
635             shift
636             shmctl
637             shmget
638             shmread
639             shmwrite
640             shutdown
641             sin
642             sleep
643             socket
644             socketpair
645             sort
646             splice
647             split
648             sprintf
649             sqrt
650             srand
651             stat
652             state
653             study
654             sub
655             substr
656             symlink
657             syscall
658             sysopen
659             sysread
660             sysseek
661             system
662             syswrite
663             tell
664             telldir
665             tie
666             tied
667             time
668             times
669             tr
670             truncate
671             try
672             uc
673             ucfirst
674             umask
675             undef
676             unless
677             unlink
678             unpack
679             unshift
680             untie
681             until
682             use
683             utime
684             values
685             vec
686             wait
687             waitpid
688             wantarray
689             warn
690             when
691             while
692             write
693             x
694             xor
695             y
696             );
697             }
698              
699             1;
700              
701             __END__