File Coverage

blib/lib/Perl/Critic/Policy/ValuesAndExpressions/ProhibitListsInMultiConstants.pm
Criterion Covered Total %
statement 40 41 97.5
branch 19 24 79.1
condition n/a
subroutine 10 11 90.9
pod 4 4 100.0
total 73 80 91.2


line stmt bran cond sub pod time code
1             package Perl::Critic::Policy::ValuesAndExpressions::ProhibitListsInMultiConstants;
2 2     2   257158 use strict;
  2         15  
  2         61  
3 2     2   13 use warnings;
  2         4  
  2         55  
4 2     2   12 use parent qw[ Perl::Critic::Policy ];
  2         4  
  2         18  
5 2     2   33471 use Perl::Critic::Utils qw[ :severities :classification ];
  2         6  
  2         115  
6              
7             use constant { # PPI search return values
8 2         874 MATCH => 1,
9             NO_MATCH => 0,
10             NO_DESCEND => undef,
11 2     2   678 };
  2         5  
12              
13 2     2 1 28 sub default_severity { return $SEVERITY_HIGH }
14 0     0 1 0 sub default_themes { return qw[ bugs ] }
15 4     4 1 77597 sub applies_to { return 'PPI::Statement::Include' }
16              
17             sub violates {
18 5     5 1 101 my ($self, $elem, $doc) = @_;
19 5 50       18 return if not $elem->pragma;
20 5 50       183 return if $elem->module ne 'constant';
21              
22 5         118 my ($hash) = $elem->arguments;
23 5 50       199 return if not $hash;
24 5 100       27 return if not $hash->isa('PPI::Structure::Constructor');
25 3 50       16 return if $hash->braces ne '{}';
26              
27             my $lists_ref = $hash->find(sub {
28 66     66   1325 my $el = $_[1];
29              
30 66 100       199 if ($el->isa('PPI::Structure::List')) {
31 3 100       27 return _is_function_arg($el) ? NO_DESCEND : MATCH;
32             }
33 63 100       179 return MATCH if $el->isa('PPI::Token::QuoteLike::Words');
34              
35             # descend only into top-level expressions
36 62 100       191 return NO_DESCEND if not $el->isa('PPI::Statement::Expression');
37 4 50       19 return NO_DESCEND if $el->parent->isa('PPI::Statement::Expression');
38              
39 4         36 return NO_MATCH;
40 3         53 });
41 3 100       45 return if not $lists_ref;
42              
43             my @violations = map {
44 1         4 $self->violation('List inside a multiple constant declaration',
  2         425  
45             'Use a separate constant declaration to use a list', $_)
46             } @$lists_ref;
47 1         259 return @violations;
48             }
49              
50             sub _is_function_arg {
51 3     3   19 my ($elem) = @_;
52 3         19 my $prev = $elem->sprevious_sibling;
53 3 100       133 return if not $prev->isa('PPI::Token::Word');
54 2         9 return is_function_call($prev);
55             }
56              
57             1;
58             __END__
59             =pod
60              
61             =head1 NAME
62              
63             Perl::Critic::Policy::ValuesAndExpressions::ProhibitListsInMultiConstants - use a single-constant declaration for lists
64              
65             =head1 AFFILIATION
66              
67             This policy as a part of the L<Perl::Critic::PolicyBundle::SNEZ> distribution.
68              
69             =head1 DESCRIPTION
70              
71             Constants can be lists, however, this can only work if a single constant
72             is declared at a time.
73              
74             ## this is fine
75             use constant MULTI => ('one', 'two', 'three');
76             use constant SINGLE => 1;
77             #
78             # produces two constants:
79             # SINGLE = 1
80             # MULTI = ('one', 'two', 'three')
81              
82             ## this is not
83             use constant {
84             MULTI => ('one', 'two', 'three'),
85             SINGLE => 1,
86             };
87             #
88             # produces three constants:
89             # SINGLE = 1
90             # MULTI = 'one'
91             # two = 'three'
92              
93             This policy detects raw lists in the hashref form of constant declaration.
94              
95             =head1 CONFIGURATION
96              
97             This Policy is not configurable except for the standard options.
98              
99             =head1 COPYRIGHT
100              
101             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
102              
103             =cut