Completed
Push — master ( 3c2b8e...8f2461 )
by Дмитрий
07:09
created

VariableVariableUsage   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 138
ccs 41
cts 41
cp 1
rs 10
c 0
b 0
f 0
wmc 20
lcom 1
cbo 7

8 Methods

Rating   Name   Duplication   Size   Complexity  
A pass() 0 15 3
A analyzeAssign() 0 10 2
A analyzeList() 0 15 4
A analyzeArrayDimFetch() 0 18 5
A analyzePropertyFetch() 0 9 2
A analyzeVar() 0 10 2
A notice() 0 4 1
A getRegister() 0 6 1
1
<?php
2
/**
3
 * @author Kévin Gomez https://github.com/K-Phoen <[email protected]>
4
 */
5
6
namespace PHPSA\Analyzer\Pass\Expression;
7
8
use PhpParser\Node\Expr;
9
use PHPSA\Analyzer\Helper\DefaultMetadataPassTrait;
10
use PHPSA\Analyzer\Pass;
11
use PHPSA\Context;
12
13
class VariableVariableUsage implements Pass\AnalyzerPassInterface
14
{
15
    use DefaultMetadataPassTrait;
16
17
    const DESCRIPTION = 'Discourages the use of variable variables.';
18
19
    /**
20
     * @param Expr\Assign $expr
21
     * @param Context $context
22
     * @return bool
23
     */
24 39
    public function pass(Expr\Assign $expr, Context $context)
25
    {
26
        // $(this->)something[] = …
27 39
        if ($expr->var instanceof Expr\ArrayDimFetch) {
28 2
            return $this->analyzeArrayDimFetch($expr->var, $context);
29
        }
30
31
        // $this->something = …
32 39
        if ($expr->var instanceof Expr\PropertyFetch) {
33 2
            return $this->analyzePropertyFetch($expr->var, $context);
34
        }
35
36
        // $something = …
37 39
        return $this->analyzeAssign($expr, $context);
38
    }
39
40
    /**
41
     * @param Expr\Assign $expr
42
     * @param Context $context
43
     * @return bool
44
     */
45 39
    private function analyzeAssign(Expr\Assign $expr, Context $context)
46
    {
47
        // list($a, $b) = …
48 39
        if ($expr->var instanceof Expr\List_) {
49 1
            return $this->analyzeList($expr->var, $context);
50
        }
51
52
        // $a = ... or class::$a =
53 39
        return $this->analyzeVar($expr->var, $context);
54
    }
55
56
    /**
57
     * @param Expr\List_ $expr
58
     * @param Context $context
59
     * @return bool
60
     */
61 1
    private function analyzeList(Expr\List_ $expr, Context $context)
62
    {
63 1
        $result = false;
64
65 1
        foreach ($expr->items as $var) {
66
            // list($a, ) = …
67 1
            if ($var === null) {
68 1
                continue;
69
            }
70
71 1
            $result = $this->analyzeVar($var->value, $context) || $result;
72
        }
73
74 1
        return $result;
75
    }
76
77
    /**
78
     * @param Expr\ArrayDimFetch $expr
79
     * @param Context $context
80
     * @return bool
81
     */
82 2
    private function analyzeArrayDimFetch(Expr\ArrayDimFetch $expr, Context $context)
83
    {
84 2
        $result = false;
85
86
        // $array[] = …
87 2
        if ($expr->var instanceof Expr\Variable) {
88 2
            $result = $this->analyzeVar($expr->var, $context);
89 1
        } elseif ($expr->var instanceof Expr\PropertyFetch) {
90
            // $this->array[] = …
91 1
            $result = $this->analyzePropertyFetch($expr->var, $context);
92
        }
93
94 2
        if ($expr->dim instanceof Expr\Variable) {
95 1
            $result = $this->analyzeVar($expr->dim, $context) || $result;
96
        }
97
98 2
        return $result;
99
    }
100
101
    /**
102
     * @param Expr\PropertyFetch $expr
103
     * @param Context $context
104
     * @return bool
105
     */
106 2
    private function analyzePropertyFetch(Expr\PropertyFetch $expr, Context $context)
107
    {
108 2
        if ($expr->name instanceof Expr\Variable) {
109 1
            $this->notice($context, $expr->name);
110 1
            return true;
111
        }
112
113 2
        return false;
114
    }
115
116
117
    /**
118
     * @param Expr\Variable|Expr\StaticPropertyFetch $var
119
     * @param Context $context
120
     */
121 39
    private function analyzeVar(Expr $var, Context $context)
122
    {
123 39
        if (!$var->name instanceof Expr\Variable) {
124 39
            return false;
125
        }
126
127 1
        $this->notice($context, $var);
128
129 1
        return true;
130
    }
131
132
    /**
133
     * @param Context $context
134
     * @param Expr $expr
135
     */
136 1
    private function notice(Context $context, Expr $expr)
137
    {
138 1
        $context->notice('variable.dynamic_assignment', 'Dynamic assignment is greatly discouraged.', $expr);
139 1
    }
140
141
    /**
142
     * @return array
143
     */
144 2
    public function getRegister()
145
    {
146
        return [
147 2
            Expr\Assign::class
148
        ];
149
    }
150
}
151