File Coverage

blib/lib/Perl/ToPerl6/Transformer/CompoundStatements/FormatLoops.pm
Criterion Covered Total %
statement 22 41 53.6
branch 1 10 10.0
condition 0 3 0.0
subroutine 11 14 78.5
pod 3 5 60.0
total 37 73 50.6


line stmt bran cond sub pod time code
1             package Perl::ToPerl6::Transformer::CompoundStatements::FormatLoops;
2              
3 17     17   11383 use 5.006001;
  17         52  
4 17     17   76 use strict;
  17         26  
  17         354  
5 17     17   67 use warnings;
  17         24  
  17         411  
6 17     17   68 use Readonly;
  17         24  
  17         853  
7              
8 17     17   88 use Perl::ToPerl6::Utils qw{ :characters :severities };
  17         25  
  17         993  
9              
10 17     17   4722 use base 'Perl::ToPerl6::Transformer';
  17         25  
  17         7710  
11              
12             our $VERSION = '0.03';
13              
14             #-----------------------------------------------------------------------------
15              
16             Readonly::Scalar my $DESC => q{Transform 'if()' to 'if ()'};
17             Readonly::Scalar my $EXPL =>
18             q{if(), elsif() and unless() need whitespace in order to not be interpreted as function calls};
19              
20             #-----------------------------------------------------------------------------
21              
22 40     40 0 1507 sub supported_parameters { return () }
23 29     29 1 110 sub default_severity { return $SEVERITY_HIGHEST }
24 25     25 1 85 sub default_themes { return qw(core bugs) }
25              
26             #-----------------------------------------------------------------------------
27              
28             my %conditional = (
29             for => 'loop',
30             foreach => 'loop',
31             );
32              
33             sub _structure_has_semicolon {
34 0     0   0 my ($elem) = @_;
35 0         0 $elem = $elem->child(1);
36 0         0 while ( $elem ) {
37 0 0       0 return 1 if $elem->isa('PPI::Token::Structure');
38 0         0 $elem = $elem->next_sibling;
39             }
40 0         0 return;
41             }
42              
43             sub _is_c_style {
44 0     0   0 my ($elem) = @_;
45 0         0 $elem = $elem->child(1);
46 0         0 while ( $elem->next_sibling ) {
47 0 0       0 return 1 if $elem->isa('PPI::Statement::Null');
48 0 0 0     0 return 1 if $elem->isa('PPI::Statement') and
49             _structure_has_semicolon($elem);
50 0         0 $elem = $elem->next_sibling;
51             }
52 0         0 return;
53             }
54              
55             #
56             # There's a tradeoff at work here.
57             #
58             # While the PPI::Structure::For object is the correct type to look for
59             # (specifically, it accurately matches the 'for ( ) ...' construct)
60             # it matches the '(...)' element, not the structure containing the emtire 'for'
61             # block.
62             #
63             # So we search for the PPI::Structure::For object, and when the time comes
64             # to transform the object, we just move our "pointer" up to the parent,
65             # which contains the entire 'for () {}' construct.
66             #
67              
68             sub applies_to {
69             return sub {
70 61 50   61   759 $_[1]->isa('PPI::Structure::For') and
71             _is_c_style($_[1])
72             }
73 4     4 1 29 }
74              
75             #-----------------------------------------------------------------------------
76              
77             # Note to reader: (after moving $elem up one layer) the structure looks like
78             #
79             # $elem (PPI::Statement::Compound)
80             # \
81             # \ 0 1 # count by child()
82             # \0 1 # count by schild()
83             # +----+
84             # | |
85             # for ( )
86             #
87             # After changing child(0):
88             #
89             # $elem (PPI::Statement::Compound)
90             # \
91             # \ 0 1 # count by child()
92             # \0 1 # count by schild()
93             # +----+
94             # | |
95             # loop ( )
96             #
97             # After inserting ' ' after schild(0):
98             #
99             # $elem (PPI::Statement::Compound)
100             # \
101             # \ 0 1 2 # count by child()
102             # \0 1 # count by schild()
103             # +----+----+
104             # | | |
105             # loop ' ' ( )
106              
107             sub transform {
108 0     0 0   my ($self, $elem, $doc) = @_;
109 0           $elem = $elem->parent;
110              
111 0           $elem->schild(0)->set_content('loop');
112              
113 0 0         if ( !$elem->child(1)->isa('PPI::Token::Whitespace') ) {
114 0           $elem->schild(0)->insert_after(
115             PPI::Token::Whitespace->new(' ')
116             );
117             }
118              
119 0           return $self->transformation( $DESC, $EXPL, $elem );
120             }
121              
122             1;
123              
124             #-----------------------------------------------------------------------------
125              
126             __END__
127              
128             =pod
129              
130             =head1 NAME
131              
132             Perl::ToPerl6::Transformer::CompoundStatements::FormatLoops - Format for(;;) loops
133              
134              
135             =head1 AFFILIATION
136              
137             This Transformer is part of the core L<Perl::ToPerl6|Perl::ToPerl6>
138             distribution.
139              
140              
141             =head1 DESCRIPTION
142              
143             Perl6 changes C-style C<for> loops to use the name C<loop>:
144              
145             for(@a) --> for (@a)
146             for($i=0;$i<1;$i++) --> loop ($i=0;$i<1;$i++)
147              
148             =head1 CONFIGURATION
149              
150             This Transformer is not configurable except for the standard options.
151              
152             =head1 AUTHOR
153              
154             Jeffrey Goff <drforr@pobox.com>
155              
156             =head1 COPYRIGHT
157              
158             Copyright (c) 2015 Jeffrey Goff
159              
160             This program is free software; you can redistribute it and/or modify
161             it under the same terms as Perl itself.
162              
163             =cut
164              
165             ##############################################################################
166             # Local Variables:
167             # mode: cperl
168             # cperl-indent-level: 4
169             # fill-column: 78
170             # indent-tabs-mode: nil
171             # c-indentation-style: bsd
172             # End:
173             # ex: set ts=8 sts=4 sw=4 tw=78 ft=perl expandtab shiftround :