line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# [[[ HEADER ]]] |
2
|
|
|
|
|
|
|
package RPerl::Parser; |
3
|
3
|
|
|
3
|
|
1054
|
use strict; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
71
|
|
4
|
3
|
|
|
3
|
|
13
|
use warnings; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
59
|
|
5
|
3
|
|
|
3
|
|
14
|
use RPerl::AfterSubclass; |
|
3
|
|
|
|
|
4
|
|
|
3
|
|
|
|
|
370
|
|
6
|
|
|
|
|
|
|
our $VERSION = 0.009_000; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
# [[[ OO INHERITANCE ]]] |
9
|
|
|
|
|
|
|
#use RPerl::CompileUnit::Module::Class; |
10
|
|
|
|
|
|
|
#use parent qw(RPerl::CompileUnit::Module::Class); |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# [[[ CRITICS ]]] |
13
|
|
|
|
|
|
|
## no critic qw(ProhibitUselessNoCritic ProhibitMagicNumbers RequireCheckedSyscalls) # USER DEFAULT 1: allow numeric values & print operator |
14
|
|
|
|
|
|
|
## no critic qw(ProhibitConstantPragma ProhibitMagicNumbers) # USER DEFAULT 3: allow constants |
15
|
|
|
|
|
|
|
## no critic qw(ProhibitPostfixControls) # SYSTEM SPECIAL 6: PERL CRITIC FILED ISSUE #639, not postfix foreach or if |
16
|
|
|
|
|
|
|
## no critic qw(ProhibitBacktickOperators) ## SYSTEM SPECIAL 11: allow system command execution |
17
|
|
|
|
|
|
|
## no critic qw(RequireCarping) # SYSTEM SPECIAL 13: allow die instead of croak |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
# [[[ INCLUDES ]]] |
20
|
3
|
|
|
3
|
|
996
|
use Perl::Critic; |
|
3
|
|
|
|
|
2077453
|
|
|
3
|
|
|
|
|
132
|
|
21
|
3
|
|
|
3
|
|
3003
|
use RPerl::Grammar; |
|
3
|
|
|
|
|
10
|
|
|
3
|
|
|
|
|
176
|
|
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
# [[[ CONSTANTS ]]] |
24
|
3
|
|
|
3
|
|
30
|
use constant MAX_SINGLE_ERROR_LINE_LENGTH => my integer $TYPED_MAX_SINGLE_ERROR_LINE_LENGTH = 120; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
4519
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
# [[[ SUBROUTINES ]]] |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
# Parse from Human-Readable RPerl Source Code File to Eyapp-Parsed RPerl AST Object |
29
|
|
|
|
|
|
|
sub rperl_to_ast__parse { |
30
|
2244
|
|
|
2244
|
|
5157
|
{ my object $RETURN_TYPE }; |
|
2244
|
|
|
|
|
4505
|
|
31
|
2244
|
|
|
|
|
5649
|
( my string $rperl_source__file_name) = @ARG; |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
# [[[ PARSE PHASE 0: CHECK PERL SYNTAX ]]] |
34
|
|
|
|
|
|
|
# [[[ PARSE PHASE 0: CHECK PERL SYNTAX ]]] |
35
|
|
|
|
|
|
|
# [[[ PARSE PHASE 0: CHECK PERL SYNTAX ]]] |
36
|
|
|
|
|
|
|
|
37
|
2244
|
|
|
|
|
47731
|
rperl_source__check_syntax($rperl_source__file_name); |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# [[[ PARSE PHASE 1: CRITICIZE PERL SYNTAX ]]] |
40
|
|
|
|
|
|
|
# [[[ PARSE PHASE 1: CRITICIZE PERL SYNTAX ]]] |
41
|
|
|
|
|
|
|
# [[[ PARSE PHASE 1: CRITICIZE PERL SYNTAX ]]] |
42
|
|
|
|
|
|
|
|
43
|
1916
|
|
|
|
|
156178
|
rperl_source__criticize($rperl_source__file_name); |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
# [[[ PARSE PHASE 2: PARSE RPERL SYNTAX ]]] |
46
|
|
|
|
|
|
|
# [[[ PARSE PHASE 2: PARSE RPERL SYNTAX ]]] |
47
|
|
|
|
|
|
|
# [[[ PARSE PHASE 2: PARSE RPERL SYNTAX ]]] |
48
|
|
|
|
|
|
|
|
49
|
1744
|
|
|
|
|
76284
|
return ( rperl_source__parse($rperl_source__file_name) ); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# Check Perl Syntax Using Perl Interpreter |
53
|
|
|
|
|
|
|
sub rperl_source__check_syntax { |
54
|
2244
|
|
|
2244
|
|
4898
|
{ my void $RETURN_TYPE }; |
|
2244
|
|
|
|
|
5326
|
|
55
|
2244
|
|
|
|
|
5399
|
( my string $rperl_source__file_name) = @ARG; |
56
|
|
|
|
|
|
|
|
57
|
2244
|
|
|
|
|
12212
|
RPerl::verbose('PARSE PHASE 0: Check Perl syntax... '); |
58
|
|
|
|
|
|
|
|
59
|
2244
|
50
|
|
|
|
13429
|
my string $nul = $OSNAME eq 'MSWin32' ? 'NUL' : '/dev/null'; |
60
|
2244
|
|
|
|
|
9461
|
my string $rperl_source__perl_syntax_command |
61
|
|
|
|
|
|
|
# DEV NOTE: inclusion of '-Mstrict' alters propagation of error messages through eval() to die() |
62
|
|
|
|
|
|
|
= $EXECUTABLE_NAME . q{ -Iblib/lib -M"warnings FATAL=>q(all)" -Mstrict -cw } |
63
|
|
|
|
|
|
|
# = $EXECUTABLE_NAME . q{ -Iblib/lib -M"warnings FATAL=>q(all)" -cw } |
64
|
|
|
|
|
|
|
. $rperl_source__file_name; |
65
|
2244
|
|
|
|
|
9168
|
my string $rperl_source__perl_syntax_command__no_output |
66
|
|
|
|
|
|
|
= $rperl_source__perl_syntax_command . ' > '.$nul.' 2> '.$nul; |
67
|
2244
|
|
|
|
|
6049
|
my string $rperl_source__perl_syntax_command__all_output |
68
|
|
|
|
|
|
|
= $rperl_source__perl_syntax_command . ' 2>&1'; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
#my string $rperl_source__perl_syntax_command = q{perl -Iblib/lib -cw } . $rperl_source__file_name; |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$rperl_source__perl_syntax_command =\n$rperl_source__perl_syntax_command\n"); |
73
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$rperl_source__perl_syntax_command__no_output =\n$rperl_source__perl_syntax_command__no_output\n\n"); |
74
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$rperl_source__perl_syntax_command__all_output =\n$rperl_source__perl_syntax_command__all_output\n\n"); |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
#my integer $rperl_source__perl_syntax_retval = system $rperl_source__perl_syntax_command; |
77
|
2244
|
|
|
|
|
505521422
|
my integer $rperl_source__perl_syntax_retval |
78
|
|
|
|
|
|
|
= system $rperl_source__perl_syntax_command__no_output; # don't want any messages printed here |
79
|
|
|
|
|
|
|
|
80
|
|
|
|
|
|
|
#my string $rperl_source__perl_syntax_retstring = `echo HOWDY`; |
81
|
|
|
|
|
|
|
#my string $rperl_source__perl_syntax_retstring = `$rperl_source__perl_syntax_command`; |
82
|
2244
|
|
|
|
|
499640380
|
my string $rperl_source__perl_syntax_retstring |
83
|
|
|
|
|
|
|
= `$rperl_source__perl_syntax_command__all_output`; |
84
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$rperl_source__perl_syntax_retval = $rperl_source__perl_syntax_retval\n"); |
86
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$rperl_source__perl_syntax_retstring =\n$rperl_source__perl_syntax_retstring\n"); |
87
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$OS_ERROR = $OS_ERROR\n"); # $OS_ERROR seems to contain random error messages that I can't trace? |
88
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__check_syntax(), have \$? = $?\n"); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
# NEED ADD ERROR CHECKING: ECOPAPL00 FILE DOES NOT EXIST, ECOPAPL01 FILE IS EMPTY |
91
|
|
|
|
|
|
|
|
92
|
2244
|
100
|
|
|
|
45260
|
if ( $rperl_source__perl_syntax_retval != 0 ) { |
93
|
324
|
|
|
|
|
4666
|
my $error_pretty = "\n\n" |
94
|
|
|
|
|
|
|
. 'ERROR ECOPAPL02, RPERL PARSER, PERL SYNTAX ERROR' . "\n" |
95
|
|
|
|
|
|
|
. 'Failed normal Perl strictures-and-fatal-warnings syntax check with the following information:' . "\n\n" |
96
|
|
|
|
|
|
|
. ' File Name: ' . $rperl_source__file_name . "\n" |
97
|
|
|
|
|
|
|
. ' Return Value: ' . ( $rperl_source__perl_syntax_retval >> 8 ) . "\n" |
98
|
|
|
|
|
|
|
. ' Error Message(s): '; |
99
|
324
|
100
|
|
|
|
2754
|
if ( (length $rperl_source__perl_syntax_retstring) < MAX_SINGLE_ERROR_LINE_LENGTH() ) { |
100
|
51
|
|
|
|
|
395
|
$error_pretty .= $rperl_source__perl_syntax_retstring . "\n\n"; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
else { |
103
|
273
|
|
|
|
|
2024
|
$error_pretty .= "\n\n" . $rperl_source__perl_syntax_retstring . "\n\n"; |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
324
|
|
|
|
|
14804
|
die $error_pretty; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
1920
|
|
|
|
|
7194
|
my string_arrayref $rperl_source__perl_syntax_retstring_lines; |
110
|
1920
|
|
|
|
|
14387
|
@{$rperl_source__perl_syntax_retstring_lines} = split /\n/xms, |
|
1920
|
|
|
|
|
31639
|
|
111
|
|
|
|
|
|
|
$rperl_source__perl_syntax_retstring; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# RPerl::diag('in rperl_source__check_syntax(), have $rperl_source__perl_syntax_retstring_lines = ' . "\n" . Dumper($rperl_source__perl_syntax_retstring_lines) . "\n"); |
114
|
1920
|
|
|
|
|
12119
|
my string_arrayref $rperl_source__perl_syntax_retstring_warnings = []; |
115
|
1920
|
|
|
|
|
4941
|
foreach my string $rperl_source__perl_syntax_retstring_line ( |
116
|
1920
|
|
|
|
|
11501
|
@{$rperl_source__perl_syntax_retstring_lines} ) |
117
|
|
|
|
|
|
|
{ |
118
|
1924
|
100
|
33
|
|
|
86229
|
if (( $rperl_source__perl_syntax_retstring_line !~ m/WARNING\sW/xms ) # RPerl Warning |
|
|
|
33
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
|
66
|
|
|
|
|
119
|
|
|
|
|
|
|
and |
120
|
|
|
|
|
|
|
( $rperl_source__perl_syntax_retstring_line !~ m/ERROR\sE/xms ) # RPerl Error |
121
|
|
|
|
|
|
|
and |
122
|
|
|
|
|
|
|
( $rperl_source__perl_syntax_retstring_line !~ m/\[\[\[\ BEGIN\s/xms ) # RPerl Non-Error Debug Info |
123
|
|
|
|
|
|
|
and |
124
|
|
|
|
|
|
|
( $rperl_source__perl_syntax_retstring_line !~ m/\[\[\[\ END\s/xms ) # RPerl Non-Error Debug Info |
125
|
|
|
|
|
|
|
and |
126
|
|
|
|
|
|
|
( $rperl_source__perl_syntax_retstring_line !~ m/syntax\sOK/xms ) # Perl Non-Error |
127
|
|
|
|
|
|
|
) |
128
|
|
|
|
|
|
|
{ |
129
|
4
|
|
|
|
|
26
|
push @{$rperl_source__perl_syntax_retstring_warnings}, |
|
4
|
|
|
|
|
42
|
|
130
|
|
|
|
|
|
|
$rperl_source__perl_syntax_retstring_line; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
|
134
|
1920
|
100
|
|
|
|
6231
|
if ( ( scalar @{$rperl_source__perl_syntax_retstring_warnings} ) != 0 ) { |
|
1920
|
|
|
|
|
8360
|
|
135
|
4
|
|
|
|
|
51
|
my $error_pretty = "\n" |
136
|
|
|
|
|
|
|
. 'ERROR ECOPAPL03, RPERL PARSER, PERL SYNTAX WARNING' . "\n" |
137
|
|
|
|
|
|
|
. 'Failed normal Perl strictures-and-fatal-warnings syntax check with the following information:' . "\n\n" |
138
|
|
|
|
|
|
|
. ' File Name: ' . $rperl_source__file_name . "\n" |
139
|
|
|
|
|
|
|
. ' Warning Message(s): '; |
140
|
|
|
|
|
|
|
|
141
|
4
|
100
|
66
|
|
|
19
|
if ( ( ( scalar @{$rperl_source__perl_syntax_retstring_warnings} ) == 1 ) |
|
4
|
|
|
|
|
80
|
|
142
|
|
|
|
|
|
|
and ( (length $rperl_source__perl_syntax_retstring_warnings->[0]) < MAX_SINGLE_ERROR_LINE_LENGTH() ) ) { |
143
|
2
|
|
|
|
|
22
|
$error_pretty .= $rperl_source__perl_syntax_retstring_warnings->[0] . "\n\n"; |
144
|
|
|
|
|
|
|
} |
145
|
|
|
|
|
|
|
else { |
146
|
2
|
|
|
|
|
16
|
$error_pretty .= "\n\n" . ( join "\n", @{$rperl_source__perl_syntax_retstring_warnings} ) . "\n\n"; |
|
2
|
|
|
|
|
25
|
|
147
|
|
|
|
|
|
|
} |
148
|
4
|
|
|
|
|
149
|
die $error_pretty; |
149
|
|
|
|
|
|
|
} |
150
|
|
|
|
|
|
|
|
151
|
1916
|
|
|
|
|
40190
|
RPerl::verbose(' done.' . "\n"); |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
# Criticize Perl Syntax Using Perl::Critic |
155
|
|
|
|
|
|
|
sub rperl_source__criticize { |
156
|
1916
|
|
|
1916
|
|
5474
|
{ my void $RETURN_TYPE }; |
|
1916
|
|
|
|
|
5734
|
|
157
|
1916
|
|
|
|
|
6068
|
( my string $rperl_source__file_name) = @ARG; |
158
|
|
|
|
|
|
|
|
159
|
1916
|
|
|
|
|
7991
|
RPerl::verbose('PARSE PHASE 1: Criticize Perl syntax... '); |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
# pre-critic error, begin check to ensure file ends with newline character or all-whitespace line |
162
|
1916
|
50
|
|
|
|
70041
|
if ( not -f $rperl_source__file_name ) { |
163
|
0
|
|
|
|
|
0
|
die 'ERROR ECOPAPC10, RPERL PARSER, PERL CRITIC VIOLATION: File not found, ' . q{'} . $rperl_source__file_name . q{'} . ', dying' . "\n"; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
|
166
|
1916
|
50
|
|
|
|
202163
|
open my filehandleref $FILE_HANDLE, '<', $rperl_source__file_name |
167
|
|
|
|
|
|
|
or die 'ERROR ECOPAPC11, RPERL PARSER, PERL CRITIC VIOLATION: Cannot open file ' . q{'} . $rperl_source__file_name . q{'} . ' for reading, ' . $OS_ERROR . ', dying' . "\n"; |
168
|
|
|
|
|
|
|
|
169
|
1916
|
|
|
|
|
8645
|
my string $file_line = undef; |
170
|
1916
|
|
|
|
|
6276
|
my string $file_line_last = undef; |
171
|
|
|
|
|
|
|
|
172
|
1916
|
|
|
|
|
33523
|
while ( $file_line = <$FILE_HANDLE> ) { |
173
|
|
|
|
|
|
|
# RPerl::diag('in rperl_source__criticize(), top of while loop, have $file_line = ' . q{'} . $file_line . q{'} . "\n"); |
174
|
45039
|
|
|
|
|
97634
|
$file_line_last = $file_line; |
175
|
|
|
|
|
|
|
} |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
# RPerl::diag('in rperl_source__criticize(), have last $file_line = ' . q{'} . $file_line . q{'} . "\n"); |
178
|
|
|
|
|
|
|
# RPerl::diag('in rperl_source__criticize(), have $file_line_last = ' . q{'} . $file_line_last . q{'} . "\n"); |
179
|
|
|
|
|
|
|
|
180
|
1916
|
50
|
|
|
|
16394
|
close $FILE_HANDLE or die 'ERROR ECOPAPC12, RPERL PARSER, PERL CRITIC VIOLATION: Cannot close file ' . q{'} . $rperl_source__file_name . q{'} . ' after reading, ' . $OS_ERROR . ', dying' . "\n"; |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# DEV NOTE: the last line of all RPerl input files must either end with a newline character or be all-whitespace characters, |
183
|
|
|
|
|
|
|
# in order to avoid false positives triggered by Perl::Critic |
184
|
1916
|
100
|
66
|
|
|
14546
|
if (((substr $file_line_last, -1, 1) ne "\n") and ( $file_line_last !~ m/^\s+$/xms )) { |
185
|
1
|
|
|
|
|
50
|
die 'ERROR ECOPAPC13, RPERL PARSER, PERL CRITIC VIOLATION: RPerl source code input file ' . q{'} . $rperl_source__file_name . q{'} . ' does not end with newline character or line of all-whitespace characters, dying' . "\n"; |
186
|
|
|
|
|
|
|
} |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
# DEV NOTE: disable RequireTidyCode because perltidy may not be stable |
189
|
|
|
|
|
|
|
# my object $rperl_source__critic = Perl::Critic->new( -severity => 'brutal' ); |
190
|
|
|
|
|
|
|
# my object $rperl_source__critic = Perl::Critic->new( -exclude => ['RequireTidyCode'] -severity => 'brutal' ); # DEV NOTE: Perl::Critic's own docs-recommended syntax throws a violation |
191
|
1915
|
|
|
|
|
55977
|
my object $rperl_source__critic = Perl::Critic->new( |
192
|
|
|
|
|
|
|
# DEV NOTE: disable RequireTidyCode because Perl::Tidy is not perfect and may complain even if the code is tidy; |
193
|
|
|
|
|
|
|
# disable PodSpelling because calling the external spellchecker can cause errors such as aspell's "No word lists can be found for the language FOO"; |
194
|
|
|
|
|
|
|
# disable RequireExplicitPackage because 'use RPerl;' comes before package name(s), and Grammar.eyp will catch any other violations |
195
|
|
|
|
|
|
|
# NEED REMOVE HARD-CODED TEMPORARY WORK-AROUND: https://github.com/autinitysystems/Perl-Critic-Policy-Documentation-RequirePod/issues/1 |
196
|
|
|
|
|
|
|
# NEED REMOVE HARD-CODED TEMPORARY WORK-AROUND: https://github.com/petdance/perl-critic-bangs/issues/16 |
197
|
|
|
|
|
|
|
# disable RequirePod because it is not part of Perl::Critic & wrongly includes itself in themes 'core' & 'php' & 'maintenance' |
198
|
|
|
|
|
|
|
# disable all non-core additional policies which may be installed, such as Perlsecret, etc. |
199
|
|
|
|
|
|
|
'-exclude' => ['RequireTidyCode', 'PodSpelling', 'RequireExplicitPackage', 'RequirePod', 'ProhibitBitwiseOperators'], |
200
|
|
|
|
|
|
|
'-severity' => 'brutal', |
201
|
|
|
|
|
|
|
'-theme' => 'core' |
202
|
|
|
|
|
|
|
); |
203
|
|
|
|
|
|
|
my @rperl_source__critic_violations |
204
|
1915
|
|
|
|
|
939222349
|
= $rperl_source__critic->critique($rperl_source__file_name); |
205
|
|
|
|
|
|
|
|
206
|
1915
|
|
|
|
|
159196802
|
my integer $rperl_source__critic_num_violations |
207
|
|
|
|
|
|
|
= scalar @rperl_source__critic_violations; |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__criticize(), have \$rperl_source__critic_num_violations = $rperl_source__critic_num_violations\n"); |
210
|
|
|
|
|
|
|
# my string $rperl_source__critic_dumperified_violations = Dumper( \@rperl_source__critic_violations ); |
211
|
|
|
|
|
|
|
#RPerl::diag("in rperl_source__criticize(), have Dumper(\\\@rperl_source__critic_violations) =\n" . $rperl_source__critic_dumperified_violations . "\n"); |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# NEED ADD ERROR CHECKING: ECOPAPC00 FILE DOES NOT EXIST, ECOPAPC01 FILE IS EMPTY; or would that be redundant with ECOPAPL0x error checking when added above? |
214
|
|
|
|
|
|
|
|
215
|
1915
|
100
|
|
|
|
11190
|
if ( $rperl_source__critic_num_violations > 0 ) { |
216
|
171
|
|
|
|
|
505
|
my string $violation_pretty = q{}; |
217
|
171
|
|
|
|
|
987
|
foreach my object $violation (@rperl_source__critic_violations) { |
218
|
192
|
|
|
|
|
1178
|
$violation_pretty .= ' File Name: ' . $rperl_source__file_name . "\n"; |
219
|
192
|
|
|
|
|
869
|
$violation_pretty .= ' Line number: ' . $violation->{_location}->[0] . "\n"; |
220
|
192
|
|
|
|
|
645
|
$violation_pretty .= ' Policy: ' . $violation->{_policy} . "\n"; |
221
|
192
|
|
|
|
|
658
|
$violation_pretty .= ' Description: ' . $violation->{_description} . "\n"; |
222
|
192
|
100
|
|
|
|
972
|
if ( ref( $violation->{_explanation} ) eq 'ARRAY' ) { |
223
|
148
|
|
|
|
|
386
|
$violation_pretty .= ' Explanation: See Perl Best Practices page(s) ' . join( ', ', @{ $violation->{_explanation} } ) . "\n\n"; |
|
148
|
|
|
|
|
976
|
|
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
else { |
226
|
44
|
|
|
|
|
187
|
$violation_pretty .= ' Explanation: ' . $violation->{_explanation} . "\n\n"; |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
} |
229
|
171
|
|
|
|
|
196999
|
die "\n" |
230
|
|
|
|
|
|
|
. 'ERROR ECOPAPC02, RPERL PARSER, PERL CRITIC VIOLATION' |
231
|
|
|
|
|
|
|
. "\n" |
232
|
|
|
|
|
|
|
. 'Failed Perl::Critic brutal review with the following information:' |
233
|
|
|
|
|
|
|
. "\n\n" |
234
|
|
|
|
|
|
|
. $violation_pretty; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
else { |
237
|
1744
|
|
|
|
|
12276
|
RPerl::verbose(' done.' . "\n"); |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
} |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# Die On RPerl Grammar Error |
242
|
|
|
|
|
|
|
sub rperl_grammar_error { |
243
|
396
|
|
|
396
|
|
841
|
{ my void $RETURN_TYPE }; |
|
396
|
|
|
|
|
780
|
|
244
|
396
|
|
|
|
|
1154
|
( my array $argument ) = @ARG; |
245
|
|
|
|
|
|
|
|
246
|
396
|
|
|
|
|
1605
|
my string $value = $argument->YYCurval; |
247
|
396
|
100
|
|
|
|
4384
|
if ( not( defined $value ) ) { |
248
|
96
|
|
|
|
|
283
|
$value = '<<< NO TOKEN FOUND >>>'; |
249
|
|
|
|
|
|
|
} |
250
|
396
|
|
|
|
|
1082
|
my string $helpful_hint = q{}; |
251
|
396
|
100
|
|
|
|
2297
|
if ( $value =~ /\d/xms ) { |
252
|
14
|
|
|
|
|
40
|
$helpful_hint |
253
|
|
|
|
|
|
|
= q{ Helpful Hint: Possible case of PBP RequireNumberSeparators (see below)} . "\n" |
254
|
|
|
|
|
|
|
. q{ Policy: Perl::Critic::Policy::ValuesAndExpressions::RequireNumberSeparators} . "\n" |
255
|
|
|
|
|
|
|
. q{ Description: Long number not separated with underscores} . "\n" |
256
|
|
|
|
|
|
|
. q{ Explanation: See Perl Best Practices page(s) 59} . "\n"; |
257
|
|
|
|
|
|
|
} |
258
|
|
|
|
|
|
|
|
259
|
396
|
|
|
|
|
909
|
my integer $line_number = $argument->{TOKENLINE}; |
260
|
396
|
|
|
|
|
842
|
my string $rperl_source__file_name = $argument->{rperl_source__file_name}; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
# die( "\n" . 'ERROR ECOPARP00, RPERL PARSER, SYNTAX ERROR; have $argument =' . "\n" . Dumper($argument) . "\n" ); |
263
|
|
|
|
|
|
|
# die( "\n" . 'ERROR ECOPARP00, RPERL PARSER, SYNTAX ERROR; have $argument->{rperl_source__file_name} = ' . $argument->{rperl_source__file_name} . "\n" ); |
264
|
|
|
|
|
|
|
|
265
|
396
|
|
|
|
|
1132
|
my $current_state_num = $argument->{STACK}[-1][0]; |
266
|
396
|
|
|
|
|
857
|
my $current_state = $argument->{STATES}[$current_state_num]; |
267
|
396
|
|
|
|
|
686
|
my $expected_tokens = q{}; |
268
|
396
|
|
|
|
|
604
|
my number $is_first_expected = 1; |
269
|
|
|
|
|
|
|
|
270
|
396
|
|
|
|
|
761
|
foreach my $expected_token ( sort keys %{ $current_state->{ACTIONS} } ) { |
|
396
|
|
|
|
|
6627
|
|
271
|
6752
|
100
|
|
|
|
8932
|
if ($is_first_expected) { |
272
|
396
|
|
|
|
|
776
|
$is_first_expected = 0; |
273
|
396
|
|
|
|
|
1277
|
$expected_tokens .= $expected_token . "\n"; |
274
|
|
|
|
|
|
|
} |
275
|
|
|
|
|
|
|
else { |
276
|
6356
|
|
|
|
|
9065
|
$expected_tokens |
277
|
|
|
|
|
|
|
.= q{ } . $expected_token . "\n"; |
278
|
|
|
|
|
|
|
} |
279
|
|
|
|
|
|
|
} |
280
|
|
|
|
|
|
|
|
281
|
396
|
|
|
|
|
682015
|
die "\n" |
282
|
|
|
|
|
|
|
. 'ERROR ECOPARP00, RPERL PARSER, RPERL SYNTAX ERROR' . "\n" |
283
|
|
|
|
|
|
|
. 'Failed RPerl grammar syntax check with the following information:' |
284
|
|
|
|
|
|
|
. "\n\n" |
285
|
|
|
|
|
|
|
. ' File Name: ' . $rperl_source__file_name . "\n" |
286
|
|
|
|
|
|
|
. ' Line Number: ' . $line_number . "\n" |
287
|
|
|
|
|
|
|
. ' Unexpected Token: ' . $value . "\n" |
288
|
|
|
|
|
|
|
. ' Expected Token(s): ' . $expected_tokens |
289
|
|
|
|
|
|
|
. $helpful_hint . "\n"; |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
# Parse RPerl Syntax Using Eyapp Grammar |
293
|
|
|
|
|
|
|
sub rperl_source__parse { |
294
|
1744
|
|
|
1744
|
|
4571
|
{ my void $RETURN_TYPE }; |
|
1744
|
|
|
|
|
4137
|
|
295
|
1744
|
|
|
|
|
4864
|
( my string $rperl_source__file_name) = @ARG; |
296
|
|
|
|
|
|
|
|
297
|
1744
|
|
|
|
|
6773
|
RPerl::verbose('PARSE PHASE 2: Parse RPerl syntax... '); |
298
|
|
|
|
|
|
|
|
299
|
1744
|
|
|
|
|
28486
|
my object $eyapp_parser = RPerl::Grammar->new(); |
300
|
1744
|
|
|
|
|
6467
|
$eyapp_parser->{rperl_source__file_name} = $rperl_source__file_name; |
301
|
1744
|
|
|
|
|
8023
|
$eyapp_parser->YYSlurpFile($rperl_source__file_name); |
302
|
1744
|
|
|
|
|
392483
|
my object $rperl_ast = $eyapp_parser->YYParse( |
303
|
|
|
|
|
|
|
yydebug => 0x00, # disable eyapp DBG DEBUGGING |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# yydebug => 0xFF, # full eyapp DBG DEBUGGING, USE FOR DEBUGGING GRAMMAR |
306
|
|
|
|
|
|
|
yyerror => \&rperl_grammar_error |
307
|
|
|
|
|
|
|
); |
308
|
|
|
|
|
|
|
|
309
|
1348
|
|
|
|
|
125598
|
RPerl::verbose(' done.' . "\n"); |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
# RPerl::diag("in rperl_source__parse(), have \$rperl_ast->str() =\n" . $rperl_ast->str() . "\n\n"); |
312
|
|
|
|
|
|
|
# RPerl::diag("in rperl_source__parse(), have \$rperl_ast =\n" . rperl_ast__dump($rperl_ast) . "\n\n"); |
313
|
|
|
|
|
|
|
# die 'TMP DEBUG'; |
314
|
|
|
|
|
|
|
|
315
|
1348
|
|
|
|
|
2409190
|
return ($rperl_ast); |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# condense AST dump, replace all instances of RPerl rule(s) with more meaningful RPerl class(es) |
319
|
|
|
|
|
|
|
sub rperl_ast__dump { |
320
|
5
|
|
|
5
|
|
12
|
{ my string $RETURN_TYPE }; |
|
5
|
|
|
|
|
18
|
|
321
|
5
|
|
|
|
|
16
|
( my object $rperl_ast) = @ARG; |
322
|
5
|
|
|
|
|
20
|
$Data::Dumper::Indent = 1; # do not attempt to align hash values based on hash key length |
323
|
5
|
|
|
|
|
46
|
my string $rperl_ast_dumped = Dumper($rperl_ast); |
324
|
5
|
|
|
|
|
657
|
$Data::Dumper::Indent = 2; # restore default |
325
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
# $rperl_ast_dumped =~ s/\ \ /\ \ \ \ /gxms; # set tabs from 2 to 4 spaces |
327
|
5
|
|
|
|
|
46
|
$rperl_ast_dumped =~ s/[ ]{2}/ /gxms; # set tabs from 2 to 4 spaces |
328
|
5
|
|
|
|
|
19
|
my string $replacee; |
329
|
|
|
|
|
|
|
my string $replacer; |
330
|
5
|
|
|
|
|
12
|
foreach my string $rule ( sort keys %{$RPerl::Grammar::RULES} ) { |
|
5
|
|
|
|
|
414
|
|
331
|
840
|
|
|
|
|
1312
|
$replacee = q{'} . $rule . q{'}; |
332
|
|
|
|
|
|
|
$replacer |
333
|
840
|
|
|
|
|
1329
|
= q{'} . $rule . ' ISA ' . $RPerl::Grammar::RULES->{$rule} . q{'}; |
334
|
840
|
|
|
|
|
4274
|
$rperl_ast_dumped =~ s/$replacee/$replacer/gxms; |
335
|
|
|
|
|
|
|
} |
336
|
5
|
|
|
|
|
75
|
return $rperl_ast_dumped; |
337
|
|
|
|
|
|
|
} |
338
|
|
|
|
|
|
|
|
339
|
|
|
|
|
|
|
# replace all instances of RPerl rule(s) with more meaningful RPerl class(es) |
340
|
|
|
|
|
|
|
sub rperl_rule__replace { |
341
|
2
|
|
|
2
|
|
6
|
{ my string $RETURN_TYPE }; |
|
2
|
|
|
|
|
6
|
|
342
|
2
|
|
|
|
|
7
|
( my string $rperl_rule_string) = @ARG; |
343
|
2
|
|
|
|
|
5
|
my string $replacer; |
344
|
2
|
|
|
|
|
6
|
foreach my string $rule ( sort keys %{$RPerl::Grammar::RULES} ) { |
|
2
|
|
|
|
|
181
|
|
345
|
336
|
100
|
|
|
|
612
|
if ( $RPerl::Grammar::RULES->{$rule} ne 'RPerl::NonGenerator' ) { |
346
|
|
|
|
|
|
|
$replacer |
347
|
|
|
|
|
|
|
= q{(} |
348
|
|
|
|
|
|
|
. $rule . ' ISA ' |
349
|
256
|
|
|
|
|
447
|
. $RPerl::Grammar::RULES->{$rule} . q{)}; |
350
|
256
|
|
|
|
|
517
|
$replacer =~ s/RPerl:://gxms; |
351
|
256
|
|
|
|
|
1486
|
$rperl_rule_string =~ s/$rule/$replacer/gxms; |
352
|
|
|
|
|
|
|
} |
353
|
|
|
|
|
|
|
} |
354
|
2
|
|
|
|
|
68
|
return $rperl_rule_string; |
355
|
|
|
|
|
|
|
} |
356
|
|
|
|
|
|
|
|
357
|
|
|
|
|
|
|
1; # end of class |