File Coverage

blib/lib/Perl/ToPerl6/Utils.pm
Criterion Covered Total %
statement 313 348 89.9
branch 164 248 66.1
condition 41 78 52.5
subroutine 55 63 87.3
pod 39 39 100.0
total 612 776 78.8


line stmt bran cond sub pod time code
1             # NOTE: This module is way too large. Please think about adding new
2             # functionality into a P::C::Utils::* module instead.
3              
4             package Perl::ToPerl6::Utils;
5              
6 30     30   155512 use 5.006001;
  30         85  
7 30     30   129 use strict;
  30         49  
  30         705  
8 30     30   120 use warnings;
  30         32  
  30         814  
9 30     30   4559 use Readonly;
  30         23275  
  30         1627  
10              
11 30     30   147 use Carp qw( confess );
  30         34  
  30         1538  
12 30     30   134 use English qw(-no_match_vars);
  30         38  
  30         178  
13 30     30   11191 use File::Spec qw();
  30         44  
  30         635  
14 30     30   119 use Scalar::Util qw( blessed );
  30         52  
  30         2191  
15 30     30   16987 use B::Keywords qw();
  30         33800  
  30         779  
16 30     30   14398 use PPI::Token::Quote::Single;
  30         1966857  
  30         1297  
17              
18 30     30   15162 use Perl::ToPerl6::Exception::Fatal::Generic qw{ throw_generic };
  30         76  
  30         882  
19 30     30   15473 use Perl::ToPerl6::Utils::PPI qw< is_ppi_expression_or_generic_statement >;
  30         70  
  30         2227  
20              
21 30     30   199 use Exporter 'import';
  30         38  
  30         154187  
22              
23             our $VERSION = '0.03';
24              
25             #-----------------------------------------------------------------------------
26             # Exportable symbols here.
27              
28             Readonly::Array our @EXPORT_OK => qw(
29             $TRUE
30             $FALSE
31              
32             $POLICY_NAMESPACE
33              
34             $SEVERITY_HIGHEST
35             $SEVERITY_HIGH
36             $SEVERITY_MEDIUM
37             $SEVERITY_LOW
38             $SEVERITY_LOWEST
39             @SEVERITY_NAMES
40              
41             $DEFAULT_VERBOSITY
42             $DEFAULT_VERBOSITY_WITH_FILE_NAME
43              
44             $COLON
45             $COMMA
46             $DQUOTE
47             $EMPTY
48             $EQUAL
49             $FATCOMMA
50             $PERIOD
51             $PIPE
52             $QUOTE
53             $BACKTICK
54             $SCOLON
55             $SPACE
56             $SLASH
57             $BSLASH
58             $LEFT_PAREN
59             $RIGHT_PAREN
60              
61             all_perl_files
62             find_keywords
63             first_arg
64             hashify
65             interpolate
66             is_assignment_operator
67             is_class_name
68             is_function_call
69             is_hash_key
70             is_in_void_context
71             is_included_module_name
72             is_integer
73             is_label_pointer
74             is_method_call
75             is_package_declaration
76             is_perl_bareword
77             is_perl_builtin
78             is_perl_builtin_with_list_context
79             is_perl_builtin_with_multiple_arguments
80             is_perl_builtin_with_no_arguments
81             is_perl_builtin_with_one_argument
82             is_perl_builtin_with_optional_argument
83             is_perl_builtin_with_zero_and_or_one_arguments
84             is_perl_filehandle
85             is_perl_global
86             is_qualified_name
87             is_script
88             is_subroutine_name
89             is_unchecked_call
90             is_valid_numeric_verbosity
91             parse_arg_list
92             transformer_long_name
93             transformer_short_name
94             precedence_of
95             severity_to_number
96             shebang_line
97             split_nodes_on_comma
98             verbosity_to_format
99             words_from_string
100             );
101              
102              
103             # Note: this is deprecated. This should also violate ProhibitAutomaticExportation,
104             # but at the moment, we aren't smart enough to deal with Readonly variables.
105             Readonly::Array our @EXPORT => @EXPORT_OK;
106              
107              
108             Readonly::Hash our %EXPORT_TAGS => (
109             all => [ @EXPORT_OK ],
110             booleans => [ qw{ $TRUE $FALSE } ],
111             severities => [
112             qw{
113             $SEVERITY_HIGHEST
114             $SEVERITY_HIGH
115             $SEVERITY_MEDIUM
116             $SEVERITY_LOW
117             $SEVERITY_LOWEST
118             @SEVERITY_NAMES
119             }
120             ],
121             characters => [
122             qw{
123             $COLON
124             $COMMA
125             $DQUOTE
126             $EMPTY
127             $EQUAL
128             $FATCOMMA
129             $PERIOD
130             $PIPE
131             $QUOTE
132             $BACKTICK
133             $SCOLON
134             $SPACE
135             $SLASH
136             $BSLASH
137             $LEFT_PAREN
138             $RIGHT_PAREN
139             }
140             ],
141             classification => [
142             qw{
143             is_assignment_operator
144             is_class_name
145             is_function_call
146             is_hash_key
147             is_included_module_name
148             is_integer
149             is_label_pointer
150             is_method_call
151             is_package_declaration
152             is_perl_bareword
153             is_perl_builtin
154             is_perl_filehandle
155             is_perl_global
156             is_perl_builtin_with_list_context
157             is_perl_builtin_with_multiple_arguments
158             is_perl_builtin_with_no_arguments
159             is_perl_builtin_with_one_argument
160             is_perl_builtin_with_optional_argument
161             is_perl_builtin_with_zero_and_or_one_arguments
162             is_qualified_name
163             is_script
164             is_subroutine_name
165             is_unchecked_call
166             is_valid_numeric_verbosity
167             }
168             ],
169             data_conversion => [ qw{ hashify words_from_string interpolate } ],
170             ppi => [ qw{ first_arg parse_arg_list } ],
171             internal_lookup => [ qw{ severity_to_number verbosity_to_format } ],
172             language => [ qw{ precedence_of } ],
173             deprecated => [ qw{ find_keywords } ],
174             );
175              
176             #-----------------------------------------------------------------------------
177              
178             Readonly::Scalar our $POLICY_NAMESPACE => 'Perl::ToPerl6::Transformer';
179              
180             #-----------------------------------------------------------------------------
181              
182             Readonly::Scalar our $SEVERITY_HIGHEST => 5;
183             Readonly::Scalar our $SEVERITY_HIGH => 4;
184             Readonly::Scalar our $SEVERITY_MEDIUM => 3;
185             Readonly::Scalar our $SEVERITY_LOW => 2;
186             Readonly::Scalar our $SEVERITY_LOWEST => 1;
187              
188             #-----------------------------------------------------------------------------
189              
190             Readonly::Scalar our $COMMA => q{,};
191             Readonly::Scalar our $EQUAL => q{=};
192             Readonly::Scalar our $FATCOMMA => q{=>};
193             Readonly::Scalar our $COLON => q{:};
194             Readonly::Scalar our $SCOLON => q{;};
195             Readonly::Scalar our $QUOTE => q{'};
196             Readonly::Scalar our $DQUOTE => q{"};
197             Readonly::Scalar our $BACKTICK => q{`};
198             Readonly::Scalar our $PERIOD => q{.};
199             Readonly::Scalar our $PIPE => q{|};
200             Readonly::Scalar our $SPACE => q{ };
201             Readonly::Scalar our $SLASH => q{/};
202             Readonly::Scalar our $BSLASH => q{\\};
203             Readonly::Scalar our $LEFT_PAREN => q{(};
204             Readonly::Scalar our $RIGHT_PAREN => q{)};
205             Readonly::Scalar our $EMPTY => q{};
206             Readonly::Scalar our $TRUE => 1;
207             Readonly::Scalar our $FALSE => 0;
208              
209             #-----------------------------------------------------------------------------
210              
211             #TODO: Should this include punctuations vars?
212              
213              
214              
215             #-----------------------------------------------------------------------------
216              
217             Readonly::Hash my %PRECEDENCE_OF => (
218             '->' => 1,
219             '++' => 2,
220             '--' => 2,
221             '**' => 3,
222             '!' => 4,
223             '~' => 4,
224             '\\' => 4,
225             '=~' => 5,
226             '!~' => 5,
227             '*' => 6,
228             '/' => 6,
229             '%' => 6,
230             'x' => 6,
231             '+' => 7,
232             '-' => 7,
233             '.' => 7,
234             '<<' => 8,
235             '>>' => 8,
236             '-R' => 9,
237             '-W' => 9,
238             '-X' => 9,
239             '-r' => 9,
240             '-w' => 9,
241             '-x' => 9,
242             '-e' => 9,
243             '-O' => 9,
244             '-o' => 9,
245             '-z' => 9,
246             '-s' => 9,
247             '-M' => 9,
248             '-A' => 9,
249             '-C' => 9,
250             '-S' => 9,
251             '-c' => 9,
252             '-b' => 9,
253             '-f' => 9,
254             '-d' => 9,
255             '-p' => 9,
256             '-l' => 9,
257             '-u' => 9,
258             '-g' => 9,
259             '-k' => 9,
260             '-t' => 9,
261             '-T' => 9,
262             '-B' => 9,
263             '<' => 10,
264             '>' => 10,
265             '<=' => 10,
266             '>=' => 10,
267             'lt' => 10,
268             'gt' => 10,
269             'le' => 10,
270             'ge' => 10,
271             '==' => 11,
272             '!=' => 11,
273             '<=>' => 11,
274             'eq' => 11,
275             'ne' => 11,
276             'cmp' => 11,
277             '~~' => 11,
278             '&' => 12,
279             '|' => 13,
280             '^' => 13,
281             '&&' => 14,
282             '//' => 15,
283             '||' => 15,
284             '..' => 16,
285             '...' => 17,
286             '?' => 18,
287             ':' => 18,
288             '=' => 19,
289             '+=' => 19,
290             '-=' => 19,
291             '*=' => 19,
292             '/=' => 19,
293             '%=' => 19,
294             '||=' => 19,
295             '&&=' => 19,
296             '|=' => 19,
297             '&=' => 19,
298             '**=' => 19,
299             'x=' => 19,
300             '.=' => 19,
301             '^=' => 19,
302             '<<=' => 19,
303             '>>=' => 19,
304             '//=' => 19,
305             ',' => 20,
306             '=>' => 20,
307             'not' => 22,
308             'and' => 23,
309             'or' => 24,
310             'xor' => 24,
311             );
312              
313             ## use mogrify
314              
315             Readonly::Scalar my $MIN_PRECEDENCE_TO_TERMINATE_PARENLESS_ARG_LIST =>
316             precedence_of( 'not' );
317              
318             #-----------------------------------------------------------------------------
319              
320             sub hashify {
321 3406     3406 1 7451 return map { $_ => 1 } @_;
  37251         58251  
322             }
323              
324             #-----------------------------------------------------------------------------
325              
326             sub interpolate {
327 18     18 1 23 my ( $literal ) = @_;
328 18   33     885 return eval "\"$literal\"" || confess $EVAL_ERROR;
329             }
330              
331             #-----------------------------------------------------------------------------
332              
333             sub find_keywords {
334 5     5 1 9433 my ( $doc, $keyword ) = @_;
335 5         19 my $nodes_ref = $doc->find('PPI::Token::Word');
336 5 100       214 return if !$nodes_ref;
337 4         4 my @matches = grep { $_ eq $keyword } @{$nodes_ref};
  11         76  
  4         11  
338 4 100       53 return @matches ? \@matches : undef;
339             }
340              
341             #-----------------------------------------------------------------------------
342              
343             sub _name_for_sub_or_stringified_element {
344 35     35   38 my $elem = shift;
345              
346 35 100 100     273 if ( blessed $elem and $elem->isa('PPI::Statement::Sub') ) {
347 2         10 return $elem->name();
348             }
349              
350 33         75 return "$elem";
351             }
352              
353             #-----------------------------------------------------------------------------
354              
355             Readonly::Hash my %BUILTINS => hashify( @B::Keywords::Functions );
356              
357             sub is_perl_builtin {
358 4     4 1 890 my $elem = shift;
359 4 50       13 return if !$elem;
360              
361 4         9 return exists $BUILTINS{ _name_for_sub_or_stringified_element($elem) };
362             }
363              
364             #-----------------------------------------------------------------------------
365              
366             Readonly::Hash my %BAREWORDS => hashify( @B::Keywords::Barewords );
367              
368             sub is_perl_bareword {
369 16     16 1 25 my $elem = shift;
370 16 50       49 return if !$elem;
371              
372 16         41 return exists $BAREWORDS{ _name_for_sub_or_stringified_element($elem) };
373             }
374              
375             #-----------------------------------------------------------------------------
376              
377             sub _build_globals_without_sigils {
378             # B::Keywords as of 1.08 forgot $\
379             my @globals =
380 30     30   129 map { substr $_, 1 }
  4440         5408  
381             @B::Keywords::Arrays,
382             @B::Keywords::Hashes,
383             @B::Keywords::Scalars,
384             '$\\';
385              
386             # Not all of these have sigils
387 30         363 foreach my $filehandle (@B::Keywords::Filehandles) {
388 270         392 (my $stripped = $filehandle) =~ s< \A [*] ><>xms;
389 270         390 push @globals, $stripped;
390             }
391              
392 30         892 return @globals;
393             }
394              
395             Readonly::Array my @GLOBALS_WITHOUT_SIGILS => _build_globals_without_sigils();
396              
397             Readonly::Hash my %GLOBALS => hashify( @GLOBALS_WITHOUT_SIGILS );
398              
399             sub is_perl_global {
400 7     7 1 1841 my $elem = shift;
401 7 50       20 return if !$elem;
402 7         15 my $var_name = "$elem"; #Convert Token::Symbol to string
403 7         26 $var_name =~ s{\A [\$@%*] }{}xms; #Chop off the sigil
404 7         30 return exists $GLOBALS{ $var_name };
405             }
406              
407             #-----------------------------------------------------------------------------
408              
409             Readonly::Hash my %FILEHANDLES => hashify( @B::Keywords::Filehandles );
410              
411             sub is_perl_filehandle {
412 15     15 1 20 my $elem = shift;
413 15 50       45 return if !$elem;
414              
415 15         29 return exists $FILEHANDLES{ _name_for_sub_or_stringified_element($elem) };
416             }
417              
418             ## use mogrify
419             #-----------------------------------------------------------------------------
420              
421             # egrep '=item.*LIST' perlfunc.pod
422             Readonly::Hash my %BUILTINS_WHICH_PROVIDE_LIST_CONTEXT =>
423             hashify(
424             qw{
425             chmod
426             chown
427             die
428             exec
429             formline
430             grep
431             import
432             join
433             kill
434             map
435             no
436             open
437             pack
438             print
439             printf
440             push
441             reverse
442             say
443             sort
444             splice
445             sprintf
446             syscall
447             system
448             tie
449             unlink
450             unshift
451             use
452             utime
453             warn
454             },
455             );
456              
457             sub is_perl_builtin_with_list_context {
458 0     0 1 0 my $elem = shift;
459              
460             return
461             exists
462             $BUILTINS_WHICH_PROVIDE_LIST_CONTEXT{
463 0         0 _name_for_sub_or_stringified_element($elem)
464             };
465             }
466              
467             #-----------------------------------------------------------------------------
468              
469             # egrep '=item.*[A-Z],' perlfunc.pod
470             Readonly::Hash my %BUILTINS_WHICH_TAKE_MULTIPLE_ARGUMENTS =>
471             hashify(
472             qw{
473             accept
474             atan2
475             bind
476             binmode
477             bless
478             connect
479             crypt
480             dbmopen
481             fcntl
482             flock
483             gethostbyaddr
484             getnetbyaddr
485             getpriority
486             getservbyname
487             getservbyport
488             getsockopt
489             index
490             ioctl
491             link
492             listen
493             mkdir
494             msgctl
495             msgget
496             msgrcv
497             msgsnd
498             open
499             opendir
500             pipe
501             read
502             recv
503             rename
504             rindex
505             seek
506             seekdir
507             select
508             semctl
509             semget
510             semop
511             send
512             setpgrp
513             setpriority
514             setsockopt
515             shmctl
516             shmget
517             shmread
518             shmwrite
519             shutdown
520             socket
521             socketpair
522             splice
523             split
524             substr
525             symlink
526             sysopen
527             sysread
528             sysseek
529             syswrite
530             truncate
531             unpack
532             vec
533             waitpid
534             },
535             keys %BUILTINS_WHICH_PROVIDE_LIST_CONTEXT
536             );
537              
538             sub is_perl_builtin_with_multiple_arguments {
539 0     0 1 0 my $elem = shift;
540              
541             return
542             exists
543             $BUILTINS_WHICH_TAKE_MULTIPLE_ARGUMENTS{
544 0         0 _name_for_sub_or_stringified_element($elem)
545             };
546             }
547              
548             #-----------------------------------------------------------------------------
549              
550             Readonly::Hash my %BUILTINS_WHICH_TAKE_NO_ARGUMENTS =>
551             hashify(
552             qw{
553             endgrent
554             endhostent
555             endnetent
556             endprotoent
557             endpwent
558             endservent
559             fork
560             format
561             getgrent
562             gethostent
563             getlogin
564             getnetent
565             getppid
566             getprotoent
567             getpwent
568             getservent
569             setgrent
570             setpwent
571             split
572             time
573             times
574             wait
575             wantarray
576             }
577             );
578              
579             sub is_perl_builtin_with_no_arguments {
580 0     0 1 0 my $elem = shift;
581              
582             return
583             exists
584             $BUILTINS_WHICH_TAKE_NO_ARGUMENTS{
585 0         0 _name_for_sub_or_stringified_element($elem)
586             };
587             }
588              
589             #-----------------------------------------------------------------------------
590              
591             Readonly::Hash my %BUILTINS_WHICH_TAKE_ONE_ARGUMENT =>
592             hashify(
593             qw{
594             closedir
595             dbmclose
596             delete
597             each
598             exists
599             fileno
600             getgrgid
601             getgrnam
602             gethostbyname
603             getnetbyname
604             getpeername
605             getpgrp
606             getprotobyname
607             getprotobynumber
608             getpwnam
609             getpwuid
610             getsockname
611             goto
612             keys
613             local
614             prototype
615             readdir
616             readline
617             readpipe
618             rewinddir
619             scalar
620             sethostent
621             setnetent
622             setprotoent
623             setservent
624             telldir
625             tied
626             untie
627             values
628             }
629             );
630              
631             sub is_perl_builtin_with_one_argument {
632 0     0 1 0 my $elem = shift;
633              
634             return
635             exists
636             $BUILTINS_WHICH_TAKE_ONE_ARGUMENT{
637 0         0 _name_for_sub_or_stringified_element($elem)
638             };
639             }
640              
641             #-----------------------------------------------------------------------------
642              
643             Readonly::Hash my %BUILTINS_WHICH_TAKE_OPTIONAL_ARGUMENT =>
644             hashify(
645             grep { not exists $BUILTINS_WHICH_TAKE_ONE_ARGUMENT{ $_ } }
646             grep { not exists $BUILTINS_WHICH_TAKE_NO_ARGUMENTS{ $_ } }
647             grep { not exists $BUILTINS_WHICH_TAKE_MULTIPLE_ARGUMENTS{ $_ } }
648             @B::Keywords::Functions
649             );
650             ## use mogrify
651              
652             sub is_perl_builtin_with_optional_argument {
653 0     0 1 0 my $elem = shift;
654              
655             return
656             exists
657             $BUILTINS_WHICH_TAKE_OPTIONAL_ARGUMENT{
658 0         0 _name_for_sub_or_stringified_element($elem)
659             };
660             }
661              
662             #-----------------------------------------------------------------------------
663              
664             sub is_perl_builtin_with_zero_and_or_one_arguments {
665 0     0 1 0 my $elem = shift;
666              
667 0 0       0 return if not $elem;
668              
669 0         0 my $name = _name_for_sub_or_stringified_element($elem);
670              
671             return (
672             exists $BUILTINS_WHICH_TAKE_ONE_ARGUMENT{ $name }
673             or exists $BUILTINS_WHICH_TAKE_NO_ARGUMENTS{ $name }
674 0   0     0 or exists $BUILTINS_WHICH_TAKE_OPTIONAL_ARGUMENT{ $name }
675             );
676             }
677              
678             #-----------------------------------------------------------------------------
679              
680             sub is_qualified_name {
681 0     0 1 0 my $name = shift;
682              
683 0 0       0 return if not $name;
684              
685 0         0 return index ( $name, q{::} ) >= 0;
686             }
687              
688             #-----------------------------------------------------------------------------
689              
690             sub precedence_of {
691 36     36 1 764 my $elem = shift;
692 36 50       149 return if !$elem;
693 36 100       284 return $PRECEDENCE_OF{ ref $elem ? "$elem" : $elem };
694             }
695              
696             #-----------------------------------------------------------------------------
697              
698             sub is_hash_key {
699 24     24 1 10537 my $elem = shift;
700 24 50       87 return if !$elem;
701              
702             #If followed by an argument list, then its a function call, not a literal
703 24 100       56 return if _is_followed_by_parens($elem);
704              
705             #Check curly-brace style: $hash{foo} = bar;
706 16         93 my $parent = $elem->parent();
707 16 50       92 return if !$parent;
708 16         64 my $grandparent = $parent->parent();
709 16 50       69 return if !$grandparent;
710 16 100       62 return 1 if $grandparent->isa('PPI::Structure::Subscript');
711              
712              
713             #Check declarative style: %hash = (foo => bar);
714 14         66 my $sib = $elem->snext_sibling();
715 14 50       239 return if !$sib;
716 14 50 33     78 return 1 if $sib->isa('PPI::Token::Operator') && $sib eq '=>';
717              
718 14         49 return;
719             }
720              
721             #-----------------------------------------------------------------------------
722              
723             sub _is_followed_by_parens {
724 24     24   30 my $elem = shift;
725 24 50       66 return if !$elem;
726              
727 24   100     66 my $sibling = $elem->snext_sibling() || return;
728 22         482 return $sibling->isa('PPI::Structure::List');
729             }
730              
731             #-----------------------------------------------------------------------------
732              
733             sub is_included_module_name {
734 15     15 1 21 my $elem = shift;
735 15 50       39 return if !$elem;
736 15         28 my $stmnt = $elem->statement();
737 15 50       149 return if !$stmnt;
738 15 50       74 return if !$stmnt->isa('PPI::Statement::Include');
739 0         0 return $stmnt->schild(1) == $elem;
740             }
741              
742             #-----------------------------------------------------------------------------
743              
744             sub is_integer {
745 289     289 1 390 my ($value) = @_;
746 289 50       589 return 0 if not defined $value;
747              
748 289         2195 return $value =~ m{ \A [+-]? \d+ \z }xms;
749             }
750              
751             #-----------------------------------------------------------------------------
752              
753             sub is_label_pointer {
754 14     14 1 14 my $elem = shift;
755 14 50       34 return if !$elem;
756              
757 14         28 my $statement = $elem->statement();
758 14 50       168 return if !$statement;
759              
760 14         35 my $psib = $elem->sprevious_sibling();
761 14 100       185 return if !$psib;
762              
763 2   66     19 return $statement->isa('PPI::Statement::Break')
764             && $psib =~ m/(?:redo|goto|next|last)/xmso;
765             }
766              
767             #-----------------------------------------------------------------------------
768              
769             sub is_method_call {
770 15     15 1 24 my $elem = shift;
771 15 50       42 return if !$elem;
772              
773 15         42 return _is_dereference_operator( $elem->sprevious_sibling() );
774             }
775              
776             #-----------------------------------------------------------------------------
777              
778             sub is_class_name {
779 15     15 1 17 my $elem = shift;
780 15 50       43 return if !$elem;
781              
782 15   33     54 return _is_dereference_operator( $elem->snext_sibling() )
783             && !_is_dereference_operator( $elem->sprevious_sibling() );
784             }
785              
786             #-----------------------------------------------------------------------------
787              
788             sub _is_dereference_operator {
789 30     30   506 my $elem = shift;
790 30 100       164 return if !$elem;
791              
792 18   66     82 return $elem->isa('PPI::Token::Operator') && $elem eq q{->};
793             }
794              
795             #-----------------------------------------------------------------------------
796              
797             sub is_package_declaration {
798 15     15 1 19 my $elem = shift;
799 15 50       44 return if !$elem;
800 15         51 my $stmnt = $elem->statement();
801 15 50       268 return if !$stmnt;
802 15 50       88 return if !$stmnt->isa('PPI::Statement::Package');
803 0         0 return $stmnt->schild(1) == $elem;
804             }
805              
806             #-----------------------------------------------------------------------------
807              
808             sub is_subroutine_name {
809 17     17 1 274 my $elem = shift;
810 17 50       51 return if !$elem;
811 17         37 my $sib = $elem->sprevious_sibling();
812 17 100       232 return if !$sib;
813 5         16 my $stmnt = $elem->statement();
814 5 50       67 return if !$stmnt;
815 5   66     28 return $stmnt->isa('PPI::Statement::Sub') && $sib eq 'sub';
816             }
817              
818             #-----------------------------------------------------------------------------
819              
820             sub is_function_call {
821 16 50   16 1 1977 my $elem = shift or return;
822              
823 16 100       44 return if is_perl_bareword($elem);
824 15 50       235 return if is_perl_filehandle($elem);
825 15 50       133 return if is_package_declaration($elem);
826 15 50       37 return if is_included_module_name($elem);
827 15 50       37 return if is_method_call($elem);
828 15 50       59 return if is_class_name($elem);
829 15 100       86 return if is_subroutine_name($elem);
830 14 50       28 return if is_label_pointer($elem);
831 14 50       37 return if is_hash_key($elem);
832              
833 14         83 return 1;
834             }
835              
836             #-----------------------------------------------------------------------------
837              
838             sub is_script {
839 8     8 1 7729 my $doc = shift;
840              
841 8         403 warnings::warnif(
842             'deprecated',
843             'Perl::ToPerl6::Utils::is_script($doc) deprecated, use $doc->is_program() instead.',
844             );
845              
846 8 50 33     80 return $doc->is_program()
847             if blessed($doc) && $doc->isa('Perl::ToPerl6::Document');
848              
849 8 100       18 return 1 if shebang_line($doc);
850 3 100       6 return 1 if _is_PL_file($doc);
851 2         8 return 0;
852             }
853              
854             #-----------------------------------------------------------------------------
855              
856             sub _is_PL_file {
857 3     3   6 my ($doc) = @_;
858 3 100       17 return if not $doc->can('filename');
859 1   50     4 my $filename = $doc->filename() || return;
860 1 50       19 return 1 if $filename =~ m/[.] PL \z/xms;
861 0         0 return 0;
862             }
863              
864             #-----------------------------------------------------------------------------
865              
866             sub is_in_void_context {
867 0     0 1 0 my ($token) = @_;
868              
869             # If part of a collective, can't be void.
870 0 0       0 return if $token->sprevious_sibling();
871              
872 0         0 my $parent = $token->statement()->parent();
873 0 0       0 if ($parent) {
874 0 0       0 return if $parent->isa('PPI::Structure::List');
875 0 0       0 return if $parent->isa('PPI::Structure::For');
876 0 0       0 return if $parent->isa('PPI::Structure::Condition');
877 0 0       0 return if $parent->isa('PPI::Structure::Constructor');
878 0 0       0 return if $parent->isa('PPI::Structure::Subscript');
879              
880 0         0 my $grand_parent = $parent->parent();
881 0 0       0 if ($grand_parent) {
882             return if
883 0 0 0     0 $parent->isa('PPI::Structure::Block')
884             and not $grand_parent->isa('PPI::Statement::Compound');
885             }
886             }
887              
888 0         0 return $TRUE;
889             }
890              
891             #-----------------------------------------------------------------------------
892              
893             sub transformer_long_name {
894 2876     2876 1 2964 my ( $transformer_name ) = @_;
895 2876 100       12335 if ( $transformer_name !~ m{ \A $POLICY_NAMESPACE }xms ) {
896 76         139 $transformer_name = $POLICY_NAMESPACE . q{::} . $transformer_name;
897             }
898 2876         7621 return $transformer_name;
899             }
900              
901             #-----------------------------------------------------------------------------
902              
903             sub transformer_short_name {
904 18556     18556 1 17370 my ( $transformer_name ) = @_;
905 18556         70363 $transformer_name =~ s{\A $POLICY_NAMESPACE ::}{}xms;
906 18556         47480 return $transformer_name;
907             }
908              
909             #-----------------------------------------------------------------------------
910              
911             sub first_arg {
912 7     7 1 4439 my $elem = shift;
913 7         23 my $sib = $elem->snext_sibling();
914 7 50       132 return if !$sib;
915              
916 7 100       30 if ( $sib->isa('PPI::Structure::List') ) {
917              
918 2         16 my $expr = $sib->schild(0);
919 2 100       20 return if !$expr;
920 1 50       12 return $expr->isa('PPI::Statement') ? $expr->schild(0) : $expr;
921             }
922              
923 5         8 return $sib;
924             }
925              
926             #-----------------------------------------------------------------------------
927              
928             sub parse_arg_list {
929 11     11 1 12121 my $elem = shift;
930 11         37 my $sib = $elem->snext_sibling();
931 11 50       216 return if !$sib;
932              
933 11 100       40 if ( $sib->isa('PPI::Structure::List') ) {
934              
935             #Pull siblings from list
936 3         33 my @list_contents = $sib->schildren();
937 3 50       42 return if not @list_contents;
938              
939 3         5 my @list_expressions;
940 3         7 foreach my $item (@list_contents) {
941 4 100       17 if (
942             is_ppi_expression_or_generic_statement($item)
943             ) {
944 3         14 push
945             @list_expressions,
946             split_nodes_on_comma( $item->schildren() );
947             }
948             else {
949 1         5 push @list_expressions, $item;
950             }
951             }
952              
953 3         9 return @list_expressions;
954             }
955             else {
956              
957             #Gather up remaining nodes in the statement
958 8         10 my $iter = $elem;
959 8         16 my @arg_list = ();
960              
961 8         16 while ($iter = $iter->snext_sibling() ) {
962 19 100 66     292 last if $iter->isa('PPI::Token::Structure') and $iter eq $SCOLON;
963 11 50 66     46 last if $iter->isa('PPI::Token::Operator')
964             and $MIN_PRECEDENCE_TO_TERMINATE_PARENLESS_ARG_LIST <=
965             precedence_of( $iter );
966 11         64 push @arg_list, $iter;
967             }
968 8         117 return split_nodes_on_comma( @arg_list );
969             }
970             }
971              
972             #---------------------------------
973              
974             sub split_nodes_on_comma {
975 11     11 1 47 my @nodes = @_;
976              
977 11         13 my $i = 0;
978 11         14 my @node_stacks;
979 11         19 for my $node (@nodes) {
980 25 100 66     156 if (
    100 66        
981             $node->isa('PPI::Token::Operator')
982             and ($node eq $COMMA or $node eq $FATCOMMA)
983             ) {
984 8 100       114 if (@node_stacks) {
985 7         8 $i++; #Move forward to next 'node stack'
986             }
987 8         13 next;
988             } elsif ( $node->isa('PPI::Token::QuoteLike::Words' )) {
989 7         13 my $section = $node->{sections}->[0];
990 7         18 my @words = words_from_string(substr $node->content, $section->{position}, $section->{size});
991 7         28 my $loc = $node->location;
992 7         83 for my $word (@words) {
993 10         45 my $token = PPI::Token::Quote::Single->new(q{'} . $word . q{'});
994 10         124 $token->{_location} = $loc;
995 10         14 push @{ $node_stacks[$i++] }, $token;
  10         28  
996             }
997 7         16 next;
998             }
999 10         9 push @{ $node_stacks[$i] }, $node;
  10         23  
1000             }
1001 11         38 return @node_stacks;
1002             }
1003              
1004             #-----------------------------------------------------------------------------
1005              
1006             # XXX: You must keep the regular expressions in extras/perlmogrify.el in sync
1007             # if you change these.
1008             Readonly::Hash my %FORMAT_OF => (
1009             1 => "%f:%l:%c:%m\n",
1010             2 => "%f: (%l:%c) %m\n",
1011             3 => "%m at %f line %l\n",
1012             4 => "%m at line %l, column %c. %e. (Severity: %s)\n",
1013             5 => "%f: %m at line %l, column %c. %e. (Severity: %s)\n",
1014             6 => "%m at line %l, near '%r'. (Severity: %s)\n",
1015             7 => "%f: %m at line %l near '%r'. (Severity: %s)\n",
1016             8 => "[%p] %m at line %l, column %c. (Severity: %s)\n",
1017             9 => "[%p] %m at line %l, near '%r'. (Severity: %s)\n",
1018             10 => "%m at line %l, column %c.\n %p (Severity: %s)\n%d\n",
1019             11 => "%m at line %l, near '%r'.\n %p (Severity: %s)\n%d\n",
1020             );
1021              
1022             Readonly::Scalar our $DEFAULT_VERBOSITY => 4;
1023             Readonly::Scalar our $DEFAULT_VERBOSITY_WITH_FILE_NAME => 5;
1024             Readonly::Scalar my $DEFAULT_FORMAT => $FORMAT_OF{$DEFAULT_VERBOSITY};
1025              
1026             sub is_valid_numeric_verbosity {
1027 73     73 1 162 my ($verbosity) = @_;
1028              
1029 73         491 return exists $FORMAT_OF{$verbosity};
1030             }
1031              
1032             sub verbosity_to_format {
1033 19     19 1 27 my ($verbosity) = @_;
1034 19 100       41 return $DEFAULT_FORMAT if not defined $verbosity;
1035 18 100 66     27 return $FORMAT_OF{abs int $verbosity} || $DEFAULT_FORMAT if is_integer($verbosity);
1036 16         29 return interpolate( $verbosity ); #Otherwise, treat as a format spec
1037             }
1038              
1039             #-----------------------------------------------------------------------------
1040              
1041             Readonly::Hash my %SEVERITY_NUMBER_OF => (
1042             gentle => 5,
1043             stern => 4,
1044             harsh => 3,
1045             cruel => 2,
1046             brutal => 1,
1047             );
1048              
1049             Readonly::Array our @SEVERITY_NAMES => #This is exported!
1050             sort
1051             { $SEVERITY_NUMBER_OF{$a} <=> $SEVERITY_NUMBER_OF{$b} }
1052             keys %SEVERITY_NUMBER_OF;
1053              
1054             sub severity_to_number {
1055 52     52 1 114 my ($severity) = @_;
1056 52 100       178 return _normalize_severity( $severity ) if is_integer( $severity );
1057 6         33 my $severity_number = $SEVERITY_NUMBER_OF{lc $severity};
1058              
1059 6 100       40 if ( not defined $severity_number ) {
1060 1         5 throw_generic qq{Invalid severity: "$severity"};
1061             }
1062              
1063 5         23 return $severity_number;
1064             }
1065              
1066             sub _normalize_severity {
1067 46   50 46   141 my $s = shift || return $SEVERITY_HIGHEST;
1068 46 50       191 $s = $s > $SEVERITY_HIGHEST ? $SEVERITY_HIGHEST : $s;
1069 46 50       156 $s = $s < $SEVERITY_LOWEST ? $SEVERITY_LOWEST : $s;
1070 46         154 return $s;
1071             }
1072              
1073             #-----------------------------------------------------------------------------
1074              
1075             Readonly::Array my @SKIP_DIR => qw( CVS RCS .svn _darcs {arch} .bzr .cdv .git .hg .pc _build blib );
1076             Readonly::Hash my %SKIP_DIR => hashify( @SKIP_DIR );
1077              
1078             sub all_perl_files {
1079              
1080             # Recursively searches a list of directories and returns the paths
1081             # to files that seem to be Perl source code. This subroutine was
1082             # poached from Test::Perl::ToPerl6.
1083              
1084 1     1 1 20 my @queue = @_;
1085 1         3 my @code_files = ();
1086              
1087 1         4 while (@queue) {
1088 55         55 my $file = shift @queue;
1089 55 100       592 if ( -d $file ) {
1090 17 50       296 opendir my ($dh), $file or next;
1091 17         339 my @newfiles = sort readdir $dh;
1092 17         98 closedir $dh;
1093              
1094 17         179 @newfiles = File::Spec->no_upwards(@newfiles);
1095 17         23 @newfiles = grep { not $SKIP_DIR{$_} } @newfiles;
  54         239  
1096 17         91 push @queue, map { File::Spec->catfile($file, $_) } @newfiles;
  54         283  
1097             }
1098              
1099 55 50 66     743 if ( (-f $file) && ! _is_backup($file) && _is_perl($file) ) {
      66        
1100 38         76 push @code_files, $file;
1101             }
1102             }
1103 1         11 return @code_files;
1104             }
1105              
1106              
1107             #-----------------------------------------------------------------------------
1108             # Decide if it's some sort of backup file
1109              
1110             sub _is_backup {
1111 45     45   1985 my ($file) = @_;
1112 45 100       89 return 1 if $file =~ m{ [.] swp \z}xms;
1113 44 100       81 return 1 if $file =~ m{ [.] bak \z}xms;
1114 43 100       67 return 1 if $file =~ m{ ~ \z}xms;
1115 42 100       73 return 1 if $file =~ m{ \A [#] .+ [#] \z}xms;
1116 41         136 return;
1117             }
1118              
1119             #-----------------------------------------------------------------------------
1120             # Returns true if the argument ends with a perl-ish file
1121             # extension, or if it has a shebang-line containing 'perl' This
1122             # subroutine was also poached from Test::Perl::ToPerl6
1123              
1124             sub _is_perl {
1125 55     55   14078 my ($file) = @_;
1126              
1127             #Check filename extensions
1128 55 100       143 return 1 if $file =~ m{ [.] PL \z}xms;
1129 54 100       214 return 1 if $file =~ m{ [.] p[lm] \z}xms;
1130 14 100       53 return 1 if $file =~ m{ [.] t \z}xms;
1131              
1132             #Check for shebang
1133 13 100       428 open my $fh, '<', $file or return;
1134 9         76 my $first = <$fh>;
1135 9 50       66 close $fh or throw_generic "unable to close $file: $OS_ERROR";
1136              
1137 9 100 66     127 return 1 if defined $first && ( $first =~ m{ \A [#]!.*perl }xms );
1138 3         29 return;
1139             }
1140              
1141             #-----------------------------------------------------------------------------
1142              
1143             sub shebang_line {
1144 67     67 1 3840 my $doc = shift;
1145 67         313 my $first_element = $doc->first_element();
1146 67 50       388 return if not $first_element;
1147 67 100       391 return if not $first_element->isa('PPI::Token::Comment');
1148 16         67 my $location = $first_element->location();
1149 16 50       1100 return if !$location;
1150             # The shebang must be the first two characters in the file, according to
1151             # http://en.wikipedia.org/wiki/Shebang_(Unix)
1152 16 50       80 return if $location->[0] != 1; # line number
1153 16 50       43 return if $location->[1] != 1; # column number
1154 16         44 my $shebang = $first_element->content;
1155 16 100       145 return if $shebang !~ m{ \A [#]! }xms;
1156 14         84 return $shebang;
1157             }
1158              
1159             #-----------------------------------------------------------------------------
1160              
1161             sub words_from_string {
1162 877     877 1 1036 my $str = shift;
1163              
1164 877         2625 return split q{ }, $str; # This must be a literal space, not $SPACE
1165             }
1166              
1167             #-----------------------------------------------------------------------------
1168              
1169             Readonly::Hash my %ASSIGNMENT_OPERATORS => hashify( qw( = **= += -= .= *= /= %= x= &= |= ^= <<= >>= &&= ||= //= ) );
1170              
1171             sub is_assignment_operator {
1172 29     29 1 12990 my $elem = shift;
1173              
1174 29         145 return $ASSIGNMENT_OPERATORS{ $elem };
1175             }
1176              
1177             #-----------------------------------------------------------------------------
1178              
1179             sub is_unchecked_call {
1180 14     14 1 3823 my $elem = shift;
1181              
1182 14 50       37 return if not is_function_call( $elem );
1183              
1184             # check to see if there's an '=' or 'unless' or something before this.
1185 14 100       34 if( my $sib = $elem->sprevious_sibling() ){
1186 2 50       46 return if $sib;
1187             }
1188              
1189              
1190 12 50       142 if( my $statement = $elem->statement() ){
1191              
1192             # "open or die" is OK.
1193             # We can't check snext_sibling for 'or' since the next siblings are an
1194             # unknown number of arguments to the system call. Instead, check all of
1195             # the elements to this statement to see if we find 'or' or '||'.
1196              
1197             my $or_operators = sub {
1198 90     90   744 my (undef, $elem) = @_;
1199 90 100       268 return if not $elem->isa('PPI::Token::Operator');
1200 13 100 66     29 return if $elem ne q{or} && $elem ne q{||};
1201 1         16 return 1;
1202 12         175 };
1203              
1204 12 100       46 return if $statement->find( $or_operators );
1205              
1206              
1207 11 50       104 if( my $parent = $elem->statement()->parent() ){
1208              
1209             # Check if we're in an if( open ) {good} else {bad} condition
1210 11 50       171 return if $parent->isa('PPI::Structure::Condition');
1211              
1212             # Return val could be captured in data structure and checked later
1213 11 50       57 return if $parent->isa('PPI::Structure::Constructor');
1214              
1215             # "die if not ( open() )" - It's in list context.
1216 11 100       67 if ( $parent->isa('PPI::Structure::List') ) {
1217 6 100       41 if( my $uncle = $parent->sprevious_sibling() ){
1218 1 50       29 return if $uncle;
1219             }
1220             }
1221             }
1222             }
1223              
1224 10 100       98 return if _is_fatal($elem);
1225              
1226             # Otherwise, return. this system call is unchecked.
1227 3         28 return 1;
1228             }
1229              
1230             # Based upon autodie 2.10.
1231             Readonly::Hash my %AUTODIE_PARAMETER_TO_AFFECTED_BUILTINS_MAP => (
1232             # Map builtins to themselves.
1233             (
1234             map { $_ => { hashify( $_ ) } }
1235             qw<
1236             accept bind binmode chdir chmod close closedir connect
1237             dbmclose dbmopen exec fcntl fileno flock fork getsockopt ioctl
1238             link listen mkdir msgctl msgget msgrcv msgsnd open opendir
1239             pipe read readlink recv rename rmdir seek semctl semget semop
1240             send setsockopt shmctl shmget shmread shutdown socketpair
1241             symlink sysopen sysread sysseek system syswrite truncate umask
1242             unlink
1243             >
1244             ),
1245              
1246             # Generate these using tools/dump-autodie-tag-contents
1247             ':threads' => { hashify( qw< fork > ) },
1248             ':system' => { hashify( qw< exec system > ) },
1249             ':dbm' => { hashify( qw< dbmclose dbmopen > ) },
1250             ':semaphore' => { hashify( qw< semctl semget semop > ) },
1251             ':shm' => { hashify( qw< shmctl shmget shmread > ) },
1252             ':msg' => { hashify( qw< msgctl msgget msgrcv msgsnd > ) },
1253             ':file' => {
1254             hashify(
1255             qw<
1256             binmode chmod close fcntl fileno flock ioctl open sysopen
1257             truncate
1258             >
1259             )
1260             },
1261             ':filesys' => {
1262             hashify(
1263             qw<
1264             chdir closedir link mkdir opendir readlink rename rmdir
1265             symlink umask unlink
1266             >
1267             )
1268             },
1269             ':ipc' => {
1270             hashify(
1271             qw<
1272             msgctl msgget msgrcv msgsnd pipe semctl semget semop shmctl
1273             shmget shmread
1274             >
1275             )
1276             },
1277             ':socket' => {
1278             hashify(
1279             qw<
1280             accept bind connect getsockopt listen recv send setsockopt
1281             shutdown socketpair
1282             >
1283             )
1284             },
1285             ':io' => {
1286             hashify(
1287             qw<
1288             accept bind binmode chdir chmod close closedir connect
1289             dbmclose dbmopen fcntl fileno flock getsockopt ioctl link
1290             listen mkdir msgctl msgget msgrcv msgsnd open opendir pipe
1291             read readlink recv rename rmdir seek semctl semget semop send
1292             setsockopt shmctl shmget shmread shutdown socketpair symlink
1293             sysopen sysread sysseek syswrite truncate umask unlink
1294             >
1295             )
1296             },
1297             ':default' => {
1298             hashify(
1299             qw<
1300             accept bind binmode chdir chmod close closedir connect
1301             dbmclose dbmopen fcntl fileno flock fork getsockopt ioctl link
1302             listen mkdir msgctl msgget msgrcv msgsnd open opendir pipe
1303             read readlink recv rename rmdir seek semctl semget semop send
1304             setsockopt shmctl shmget shmread shutdown socketpair symlink
1305             sysopen sysread sysseek syswrite truncate umask unlink
1306             >
1307             )
1308             },
1309             ':all' => {
1310             hashify(
1311             qw<
1312             accept bind binmode chdir chmod close closedir connect
1313             dbmclose dbmopen exec fcntl fileno flock fork getsockopt ioctl
1314             link listen mkdir msgctl msgget msgrcv msgsnd open opendir
1315             pipe read readlink recv rename rmdir seek semctl semget semop
1316             send setsockopt shmctl shmget shmread shutdown socketpair
1317             symlink sysopen sysread sysseek system syswrite truncate umask
1318             unlink
1319             >
1320             )
1321             },
1322             );
1323              
1324             sub _is_fatal {
1325 10     10   14 my ($elem) = @_;
1326              
1327 10         29 my $top = $elem->top();
1328 10 50       145 return if not $top->isa('PPI::Document');
1329              
1330 10         26 my $includes = $top->find('PPI::Statement::Include');
1331 10 100       7359 return if not $includes;
1332              
1333 8         17 for my $include (@{$includes}) {
  8         21  
1334 8 50       35 next if 'use' ne $include->type();
1335              
1336 8 100       206 if ('Fatal' eq $include->module()) {
    100          
    50          
1337 2         38 my @args = parse_arg_list($include->schild(1));
1338 2         6 foreach my $arg (@args) {
1339 2 50 33     19 return $TRUE if $arg->[0]->isa('PPI::Token::Quote') && $elem eq $arg->[0]->string();
1340             }
1341             }
1342             elsif ('Fatal::Exception' eq $include->module()) {
1343 2         69 my @args = parse_arg_list($include->schild(1));
1344 2         4 shift @args; # skip exception class name
1345 2         8 foreach my $arg (@args) {
1346 2 50 33     21 return $TRUE if $arg->[0]->isa('PPI::Token::Quote') && $elem eq $arg->[0]->string();
1347             }
1348             }
1349             elsif ('autodie' eq $include->pragma()) {
1350 4         211 return _is_covered_by_autodie($elem, $include);
1351             }
1352             }
1353              
1354 0         0 return;
1355             }
1356              
1357             sub _is_covered_by_autodie {
1358 4     4   7 my ($elem, $include) = @_;
1359              
1360 4         12 my $autodie = $include->schild(1);
1361 4         42 my @args = parse_arg_list($autodie);
1362 4         11 my $first_arg = first_arg($autodie);
1363              
1364             # The first argument to any `use` pragma could be a version number.
1365             # If so, then we just discard it. We only want the arguments after it.
1366 4 50 33     36 if ($first_arg and $first_arg->isa('PPI::Token::Number')){ shift @args };
  0         0  
1367              
1368 4 100       12 if (@args) {
1369 3         6 foreach my $arg (@args) {
1370             my $builtins =
1371             $AUTODIE_PARAMETER_TO_AFFECTED_BUILTINS_MAP{
1372 4         29 $arg->[0]->string
1373             };
1374              
1375 4 100 66     65 return $TRUE if $builtins and $builtins->{$elem->content()};
1376             }
1377             }
1378             else {
1379             my $builtins =
1380 1         7 $AUTODIE_PARAMETER_TO_AFFECTED_BUILTINS_MAP{':default'};
1381              
1382 1 50 33     11 return $TRUE if $builtins and $builtins->{$elem->content()};
1383             }
1384              
1385 1         12 return;
1386             }
1387              
1388             1;
1389              
1390             __END__
1391              
1392             =pod
1393              
1394             =head1 NAME
1395              
1396             Perl::ToPerl6::Utils - General utility subroutines and constants for Perl::ToPerl6 and derivative distributions.
1397              
1398              
1399             =head1 DESCRIPTION
1400              
1401             This module provides several static subs and variables that are useful
1402             for developing L<Perl::ToPerl6::Transformer|Perl::ToPerl6::Transformer>
1403             subclasses. Unless you are writing Transformer modules, you probably don't
1404             care about this package.
1405              
1406              
1407             =head1 INTERFACE SUPPORT
1408              
1409             This is considered to be a public module. Any changes to its
1410             interface will go through a deprecation cycle.
1411              
1412              
1413             =head1 IMPORTABLE SUBS
1414              
1415             =over
1416              
1417             =item C<find_keywords( $doc, $keyword )>
1418              
1419             B<DEPRECATED:> Since version 0.11, every Transformer is evaluated at each
1420             element of the document. So you shouldn't need to go looking for a
1421             particular keyword. If you I<do> want to use this, please import it
1422             via the C<:deprecated> tag, rather than directly, to mark the module
1423             as needing updating.
1424              
1425             Given a L<PPI::Document|PPI::Document> as C<$doc>, returns a reference
1426             to an array containing all the L<PPI::Token::Word|PPI::Token::Word>
1427             elements that match C<$keyword>. This can be used to find any
1428             built-in function, method call, bareword, or reserved keyword. It
1429             will not match variables, subroutine names, literal strings, numbers,
1430             or symbols. If the document doesn't contain any matches, returns
1431             undef.
1432              
1433             =item C<is_assignment_operator( $element )>
1434              
1435             Given a L<PPI::Token::Operator|PPI::Token::Operator> or a string,
1436             returns true if that token represents one of the assignment operators
1437             (e.g. C<= &&= ||= //= += -=> etc.).
1438              
1439             =item C<is_perl_global( $element )>
1440              
1441             Given a L<PPI::Token::Symbol|PPI::Token::Symbol> or a string, returns
1442             true if that token represents one of the global variables provided by
1443             the L<English|English> module, or one of the builtin global variables
1444             like C<%SIG>, C<%ENV>, or C<@ARGV>. The sigil on the symbol is
1445             ignored, so things like C<$ARGV> or C<$ENV> will still return true.
1446              
1447              
1448             =item C<is_perl_builtin( $element )>
1449              
1450             Given a L<PPI::Token::Word|PPI::Token::Word>,
1451             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1452             that token represents a call to any of the builtin functions defined
1453             in Perl 5.8.8.
1454              
1455              
1456             =item C<is_perl_bareword( $element )>
1457              
1458             Given a L<PPI::Token::Word|PPI::Token::Word>,
1459             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1460             that token represents a bareword (e.g. "if", "else", "sub", "package")
1461             defined in Perl 5.8.8.
1462              
1463              
1464             =item C<is_perl_filehandle( $element )>
1465              
1466             Given a L<PPI::Token::Word|PPI::Token::Word>, or string, returns true
1467             if that token represents one of the global filehandles (e.g. C<STDIN>,
1468             C<STDERR>, C<STDOUT>, C<ARGV>) that are defined in Perl 5.8.8. Note
1469             that this function will return false if given a filehandle that is
1470             represented as a typeglob (e.g. C<*STDIN>)
1471              
1472              
1473             =item C<is_perl_builtin_with_list_context( $element )>
1474              
1475             Given a L<PPI::Token::Word|PPI::Token::Word>,
1476             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1477             that token represents a call to any of the builtin functions defined
1478             in Perl 5.8.8 that provide a list context to the following tokens.
1479              
1480              
1481             =item C<is_perl_builtin_with_multiple_arguments( $element )>
1482              
1483             Given a L<PPI::Token::Word|PPI::Token::Word>,
1484             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1485             that token represents a call to any of the builtin functions defined
1486             in Perl 5.8.8 that B<can> take multiple arguments.
1487              
1488              
1489             =item C<is_perl_builtin_with_no_arguments( $element )>
1490              
1491             Given a L<PPI::Token::Word|PPI::Token::Word>,
1492             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1493             that token represents a call to any of the builtin functions defined
1494             in Perl 5.8.8 that B<cannot> take any arguments.
1495              
1496              
1497             =item C<is_perl_builtin_with_one_argument( $element )>
1498              
1499             Given a L<PPI::Token::Word|PPI::Token::Word>,
1500             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1501             that token represents a call to any of the builtin functions defined
1502             in Perl 5.8.8 that takes B<one and only one> argument.
1503              
1504              
1505             =item C<is_perl_builtin_with_optional_argument( $element )>
1506              
1507             Given a L<PPI::Token::Word|PPI::Token::Word>,
1508             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1509             that token represents a call to any of the builtin functions defined
1510             in Perl 5.8.8 that takes B<no more than one> argument.
1511              
1512             The sets of values for which
1513             C<is_perl_builtin_with_multiple_arguments()>,
1514             C<is_perl_builtin_with_no_arguments()>,
1515             C<is_perl_builtin_with_one_argument()>, and
1516             C<is_perl_builtin_with_optional_argument()> return true are disjoint
1517             and their union is precisely the set of values that
1518             C<is_perl_builtin()> will return true for.
1519              
1520              
1521             =item C<is_perl_builtin_with_zero_and_or_one_arguments( $element )>
1522              
1523             Given a L<PPI::Token::Word|PPI::Token::Word>,
1524             L<PPI::Statement::Sub|PPI::Statement::Sub>, or string, returns true if
1525             that token represents a call to any of the builtin functions defined
1526             in Perl 5.8.8 that takes no and/or one argument.
1527              
1528             Returns true if any of C<is_perl_builtin_with_no_arguments()>,
1529             C<is_perl_builtin_with_one_argument()>, and
1530             C<is_perl_builtin_with_optional_argument()> returns true.
1531              
1532              
1533             =item C<is_qualified_name( $name )>
1534              
1535             Given a string, L<PPI::Token::Word|PPI::Token::Word>, or
1536             L<PPI::Token::Symbol|PPI::Token::Symbol>, answers whether it has a
1537             module component, i.e. contains "::".
1538              
1539              
1540             =item C<precedence_of( $element )>
1541              
1542             Given a L<PPI::Token::Operator|PPI::Token::Operator> or a string,
1543             returns the precedence of the operator, where 1 is the highest
1544             precedence. Returns undef if the precedence can't be determined
1545             (which is usually because it is not an operator).
1546              
1547              
1548             =item C<is_hash_key( $element )>
1549              
1550             Given a L<PPI::Element|PPI::Element>, returns true if the element is a
1551             literal hash key. PPI doesn't distinguish between regular barewords
1552             (like keywords or subroutine calls) and barewords in hash subscripts
1553             (which are considered literal). So this subroutine is useful if your
1554             Transformer is searching for L<PPI::Token::Word|PPI::Token::Word> elements
1555             and you want to filter out the hash subscript variety. In both of the
1556             following examples, "foo" is considered a hash key:
1557              
1558             $hash1{foo} = 1;
1559             %hash2 = (foo => 1);
1560              
1561             But if the bareword is followed by an argument list, then perl treats
1562             it as a function call. So in these examples, "foo" is B<not>
1563             considered a hash key:
1564              
1565             $hash1{ foo() } = 1;
1566             &hash2 = (foo() => 1);
1567              
1568              
1569             =item C<is_included_module_name( $element )>
1570              
1571             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1572             element is the name of a module that is being included via C<use>,
1573             C<require>, or C<no>.
1574              
1575              
1576             =item C<is_integer( $value )>
1577              
1578             Answers whether the parameter, as a string, looks like an integral
1579             value.
1580              
1581              
1582             =item C<is_class_name( $element )>
1583              
1584             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1585             element that immediately follows this element is the dereference
1586             operator "->". When a bareword has a "->" on the B<right> side, it
1587             usually means that it is the name of the class (from which a method is
1588             being called).
1589              
1590              
1591             =item C<is_label_pointer( $element )>
1592              
1593             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1594             element is the label in a C<next>, C<last>, C<redo>, or C<goto>
1595             statement. Note this is not the same thing as the label declaration.
1596              
1597              
1598             =item C<is_method_call( $element )>
1599              
1600             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1601             element that immediately precedes this element is the dereference
1602             operator "->". When a bareword has a "->" on the B<left> side, it
1603             usually means that it is the name of a method (that is being called
1604             from a class).
1605              
1606              
1607             =item C<is_package_declaration( $element )>
1608              
1609             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1610             element is the name of a package that is being declared.
1611              
1612              
1613             =item C<is_subroutine_name( $element )>
1614              
1615             Given a L<PPI::Token::Word|PPI::Token::Word>, returns true if the
1616             element is the name of a subroutine declaration. This is useful for
1617             distinguishing barewords and from function calls from subroutine
1618             declarations.
1619              
1620              
1621             =item C<is_function_call( $element )>
1622              
1623             Given a L<PPI::Token::Word|PPI::Token::Word> returns true if the
1624             element appears to be call to a static function. Specifically, this
1625             function returns true if C<is_hash_key>, C<is_method_call>,
1626             C<is_subroutine_name>, C<is_included_module_name>,
1627             C<is_package_declaration>, C<is_perl_bareword>, C<is_perl_filehandle>,
1628             C<is_label_pointer> and C<is_subroutine_name> all return false for the
1629             given element.
1630              
1631              
1632             =item C<first_arg( $element )>
1633              
1634             Given a L<PPI::Element|PPI::Element> that is presumed to be a function
1635             call (which is usually a L<PPI::Token::Word|PPI::Token::Word>), return
1636             the first argument. This is similar of C<parse_arg_list()> and
1637             follows the same logic. Note that for the code:
1638              
1639             int($x + 0.5)
1640              
1641             this function will return just the C<$x>, not the whole expression.
1642             This is different from the behavior of C<parse_arg_list()>. Another
1643             caveat is:
1644              
1645             int(($x + $y) + 0.5)
1646              
1647             which returns C<($x + $y)> as a
1648             L<PPI::Structure::List|PPI::Structure::List> instance.
1649              
1650              
1651             =item C<parse_arg_list( $element )>
1652              
1653             Given a L<PPI::Element|PPI::Element> that is presumed to be a function
1654             call (which is usually a L<PPI::Token::Word|PPI::Token::Word>), splits
1655             the argument expressions into arrays of tokens. Returns a list
1656             containing references to each of those arrays. This is useful because
1657             parentheses are optional when calling a function, and PPI parses them
1658             very differently. So this method is a poor-man's parse tree of PPI
1659             nodes. It's not bullet-proof because it doesn't respect precedence.
1660             In general, I don't like the way this function works, so don't count
1661             on it to be stable (or even present).
1662              
1663              
1664             =item C<split_nodes_on_comma( @nodes )>
1665              
1666             This has the same return type as C<parse_arg_list()> but expects to be
1667             passed the nodes that represent the interior of a list, like:
1668              
1669             'foo', 1, 2, 'bar'
1670              
1671              
1672             =item C<is_script( $document )>
1673              
1674             B<This subroutine is deprecated and will be removed in a future release.> You
1675             should use the L<Perl::ToPerl6::Document/"is_program()"> method instead.
1676              
1677              
1678             =item C<is_in_void_context( $token )>
1679              
1680             Given a L<PPI::Token|PPI::Token>, answer whether it appears to be in a
1681             void context.
1682              
1683              
1684             =item C<transformer_long_name( $transformer_name )>
1685              
1686             Given a transformer class name in long or short form, return the long form.
1687              
1688              
1689             =item C<transformer_short_name( $transformer_name )>
1690              
1691             Given a transformer class name in long or short form, return the short
1692             form.
1693              
1694              
1695             =item C<all_perl_files( @directories )>
1696              
1697             Given a list of directories, recursively searches through all the
1698             directories (depth first) and returns a list of paths for all the
1699             files that are Perl code files. Any administrative files for CVS or
1700             Subversion are skipped, as are things that look like temporary or
1701             backup files.
1702              
1703             A Perl code file is:
1704              
1705             =over
1706              
1707             =item * Any file that ends in F<.PL>, F<.pl>, F<.pm>, or F<.t>
1708              
1709             =item * Any file that has a first line with a shebang containing 'perl'
1710              
1711             =back
1712              
1713              
1714             =item C<severity_to_number( $severity )>
1715              
1716             If C<$severity> is given as an integer, this function returns
1717             C<$severity> but normalized to lie between C<$SEVERITY_LOWEST> and
1718             C<$SEVERITY_HIGHEST>. If C<$severity> is given as a string, this
1719             function returns the corresponding severity number. If the string
1720             doesn't have a corresponding number, this function will throw an
1721             exception.
1722              
1723              
1724             =item C<is_valid_numeric_verbosity( $severity )>
1725              
1726             Answers whether the argument has a translation to a Transformation format.
1727              
1728              
1729             =item C<verbosity_to_format( $verbosity_level )>
1730              
1731             Given a verbosity level between 1 and 10, returns the corresponding
1732             predefined format string. These formats are suitable for passing to
1733             the C<set_format> method in
1734             L<Perl::ToPerl6::Transformation|Perl::ToPerl6::Transformation>. See the
1735             L<perlmogrify|perlmogrify> documentation for a listing of the predefined
1736             formats.
1737              
1738              
1739             =item C<hashify( @list )>
1740              
1741             Given C<@list>, return a hash where C<@list> is in the keys and each
1742             value is 1. Duplicate values in C<@list> are silently squished.
1743              
1744              
1745             =item C<interpolate( $literal )>
1746              
1747             Given a C<$literal> string that may contain control characters (e.g..
1748             '\t' '\n'), this function does a double interpolation on the string
1749             and returns it as if it had been declared in double quotes. For
1750             example:
1751              
1752             'foo \t bar \n' ...becomes... "foo \t bar \n"
1753              
1754              
1755             =item C<shebang_line( $document )>
1756              
1757             Given a L<PPI::Document|PPI::Document>, test if it starts with C<#!>.
1758             If so, return that line. Otherwise return undef.
1759              
1760              
1761             =item C<words_from_string( $str )>
1762              
1763             Given config string I<$str>, return all the words from the string.
1764             This is safer than splitting on whitespace.
1765              
1766              
1767             =item C<is_unchecked_call( $element )>
1768              
1769             Given a L<PPI::Element|PPI::Element>, test to see if it contains a
1770             function call whose return value is not checked.
1771              
1772              
1773             =back
1774              
1775              
1776             =head1 IMPORTABLE VARIABLES
1777              
1778             =over
1779              
1780             =item C<$COMMA>
1781              
1782             =item C<$FATCOMMA>
1783              
1784             =item C<$COLON>
1785              
1786             =item C<$SCOLON>
1787              
1788             =item C<$QUOTE>
1789              
1790             =item C<$DQUOTE>
1791              
1792             =item C<$BACKTICK>
1793              
1794             =item C<$PERIOD>
1795              
1796             =item C<$PIPE>
1797              
1798             =item C<$EMPTY>
1799              
1800             =item C<$EQUAL>
1801              
1802             =item C<$SPACE>
1803              
1804             =item C<$SLASH>
1805              
1806             =item C<$BSLASH>
1807              
1808             =item C<$LEFT_PAREN>
1809              
1810             =item C<$RIGHT_PAREN>
1811              
1812             These character constants give clear names to commonly-used strings
1813             that can be hard to read when surrounded by quotes and other
1814             punctuation. Can be imported in one go via the C<:characters> tag.
1815              
1816             =item C<$SEVERITY_HIGHEST>
1817              
1818             =item C<$SEVERITY_HIGH>
1819              
1820             =item C<$SEVERITY_MEDIUM>
1821              
1822             =item C<$SEVERITY_LOW>
1823              
1824             =item C<$SEVERITY_LOWEST>
1825              
1826             These numeric constants define the relative severity of violating each
1827             L<Perl::ToPerl6::Transformer|Perl::ToPerl6::Transformer>. The C<get_severity> and
1828             C<default_severity> methods of every Transformer subclass must return one
1829             of these values. Can be imported via the C<:severities> tag.
1830              
1831             =item C<$DEFAULT_VERBOSITY>
1832              
1833             The default numeric verbosity.
1834              
1835             =item C<$DEFAULT_VERBOSITY_WITH_FILE_NAME>
1836              
1837             The numeric verbosity that corresponds to the format indicated by
1838             C<$DEFAULT_VERBOSITY>, but with the file name prefixed to it.
1839              
1840             =item C<$TRUE>
1841              
1842             =item C<$FALSE>
1843              
1844             These are simple booleans. 1 and 0 respectively. Be mindful of using
1845             these with string equality. C<$FALSE ne $EMPTY>. Can be imported via
1846             the C<:booleans> tag.
1847              
1848              
1849             =back
1850              
1851              
1852             =head1 IMPORT TAGS
1853              
1854             The following groups of functions and constants are available as
1855             parameters to a C<use Perl::ToPerl6::Util> statement.
1856              
1857             =over
1858              
1859             =item C<:all>
1860              
1861             The lot.
1862              
1863              
1864             =item C<:booleans>
1865              
1866             Includes:
1867             C<$TRUE>, C<$FALSE>
1868              
1869              
1870             =item C<:severities>
1871              
1872             Includes:
1873             C<$SEVERITY_HIGHEST>,
1874             C<$SEVERITY_HIGH>,
1875             C<$SEVERITY_MEDIUM>,
1876             C<$SEVERITY_LOW>,
1877             C<$SEVERITY_LOWEST>,
1878             C<@SEVERITY_NAMES>
1879              
1880              
1881             =item C<:characters>
1882              
1883             Includes:
1884             C<$COLON>,
1885             C<$COMMA>,
1886             C<$DQUOTE>,
1887             C<$EMPTY>,
1888             C<$FATCOMMA>,
1889             C<$PERIOD>,
1890             C<$PIPE>,
1891             C<$QUOTE>,
1892             C<$BACKTICK>,
1893             C<$SCOLON>,
1894             C<$SPACE>,
1895             C<$SLASH>,
1896             C<$BSLASH>
1897             C<$LEFT_PAREN>
1898             C<$RIGHT_PAREN>
1899              
1900              
1901             =item C<:classification>
1902              
1903             Includes:
1904             C<is_function_call>,
1905             C<is_hash_key>,
1906             C<is_included_module_name>,
1907             C<is_integer>,
1908             C<is_method_call>,
1909             C<is_package_declaration>,
1910             C<is_perl_builtin>,
1911             C<is_perl_global>,
1912             C<is_perl_builtin_with_list_context>
1913             C<is_perl_builtin_with_multiple_arguments>
1914             C<is_perl_builtin_with_no_arguments>
1915             C<is_perl_builtin_with_one_argument>
1916             C<is_perl_builtin_with_optional_argument>
1917             C<is_perl_builtin_with_zero_and_or_one_arguments>
1918             C<is_script>,
1919             C<is_subroutine_name>,
1920             C<is_unchecked_call>
1921             C<is_valid_numeric_verbosity>
1922              
1923             See also L<Perl::ToPerl6::Utils::PPI|Perl::ToPerl6::Utils::PPI>.
1924              
1925              
1926             =item C<:data_conversion>
1927              
1928             Generic manipulation, not having anything specific to do with
1929             Perl::ToPerl6.
1930              
1931             Includes:
1932             C<hashify>,
1933             C<words_from_string>,
1934             C<interpolate>
1935              
1936              
1937             =item C<:ppi>
1938              
1939             Things for dealing with L<PPI|PPI>, other than classification.
1940              
1941             Includes:
1942             C<first_arg>,
1943             C<parse_arg_list>
1944              
1945             See also L<Perl::ToPerl6::Utils::PPI|Perl::ToPerl6::Utils::PPI>.
1946              
1947              
1948             =item C<:internal_lookup>
1949              
1950             Translations between internal representations.
1951              
1952             Includes:
1953             C<severity_to_number>,
1954             C<verbosity_to_format>
1955              
1956              
1957             =item C<:language>
1958              
1959             Information about Perl not programmatically available elsewhere.
1960              
1961             Includes:
1962             C<precedence_of>
1963              
1964              
1965             =item C<:deprecated>
1966              
1967             Not surprisingly, things that are deprecated. It is preferred to use
1968             this tag to get to these functions, rather than the function names
1969             themselves, so as to mark any module using them as needing cleanup.
1970              
1971             Includes:
1972             C<find_keywords>
1973              
1974              
1975             =back
1976              
1977              
1978             =head1 SEE ALSO
1979              
1980             L<Perl::ToPerl6::Utils::Constants|Perl::ToPerl6::Utils::Constants>,
1981             L<Perl::ToPerl6::Utils::McCabe|Perl::ToPerl6::Utils::McCabe>,
1982             L<Perl::ToPerl6::Utils::PPI|Perl::ToPerl6::Utils::PPI>,
1983              
1984              
1985             =head1 AUTHOR
1986              
1987             Jeffrey Ryan Thalhammer <jeff@imaginative-software.com>
1988              
1989              
1990             =head1 COPYRIGHT
1991              
1992             Copyright (c) 2005-2011 Imaginative Software Systems. All rights reserved.
1993              
1994             This program is free software; you can redistribute it and/or modify
1995             it under the same terms as Perl itself. The full text of this license
1996             can be found in the LICENSE file included with this module.
1997              
1998             =cut
1999              
2000             # Local Variables:
2001             # mode: cperl
2002             # cperl-indent-level: 4
2003             # fill-column: 78
2004             # indent-tabs-mode: nil
2005             # c-indentation-style: bsd
2006             # End:
2007             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :