1package Perl::Lint::Policy::Variables::ProhibitAugmentedAssignmentInDeclaration;
2use strict;
3use warnings;
4use Compiler::Lexer::Constants;
5use parent "Perl::Lint::Policy";
6
7use constant {
8    DESC => q{Augmented assignment operator '%s' used in declaration},
9    EXPL => q{Use simple assignment when initializing variables},
10    AUGMENTED_ASSIGNMENTS => {
11        '**=' => 1, '+='  => 1, '-='  => 1, '.='  => 1,
12        '*='  => 1, '/='  => 1, '%='  => 1, 'x='  => 1,
13        '&='  => 1, '|='  => 1, '^='  => 1, '<<=' => 1,
14        '>>=' => 1, '&&=' => 1, '||=' => 1, '//=' => 1,
15    },
16    VAR         => Compiler::Lexer::TokenType::T_Var,
17    LOCAL_VAR   => Compiler::Lexer::TokenType::T_LocalVar,
18    GLOBAL_VAR  => Compiler::Lexer::TokenType::T_GlobalVar,
19    SEMI_COLON  => Compiler::Lexer::TokenType::T_SemiColon,
20    ASSIGN      => Compiler::Lexer::TokenType::T_Assign,
21    DECL        => Compiler::Lexer::Kind::T_Decl,
22    KIND_ASSIGN => Compiler::Lexer::Kind::T_Assign,
23};
24
25sub evaluate {
26    my ($class, $file, $tokens) = @_;
27
28    my @violations;
29    my $token_num = scalar @$tokens;
30    for (my $i = 0; $i < $token_num; $i++) {
31        if ($tokens->[$i]->{kind} == DECL) {
32            $i++;
33            my $var_type = $tokens->[$i]->{type};
34            if ($var_type == VAR || $var_type == LOCAL_VAR || $var_type == GLOBAL_VAR) {
35                for ($i++; $i < $token_num; $i++) {
36                    my $token = $tokens->[$i];
37                    if (
38                        $token->{kind} == KIND_ASSIGN &&
39                        AUGMENTED_ASSIGNMENTS->{$token->{data}} # XXX Not good
40                    ) {
41                        push @violations, {
42                            filename => $file,
43                            line     => $token->{line},
44                            description => sprintf(DESC, $token->{data}),
45                            explanation => EXPL,
46                            policy => __PACKAGE__,
47                        };
48                        last;
49                    }
50                    elsif ($token->{type} == ASSIGN || $token->{type} == SEMI_COLON) {
51                        last;
52                    }
53                }
54            }
55        }
56    }
57    return \@violations;
58}
59
601;
61
62