File Coverage

blib/lib/Perl/ToPerl6/Utils.pm
Criterion Covered Total %
statement 62 348 17.8
branch 4 248 1.6
condition 0 78 0.0
subroutine 21 63 33.3
pod 39 39 100.0
total 126 776 16.2


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