Completed
Push — master ( 1cf077...8206b4 )
by Povilas
01:34
created

DetectorVisitor::hasSign()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
rs 10
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
namespace Povils\PHPMND\Visitor;
4
5
use PhpParser\Node;
6
use PhpParser\Node\Const_;
7
use PhpParser\Node\Expr\UnaryMinus;
8
use PhpParser\Node\Expr\UnaryPlus;
9
use PhpParser\Node\Scalar;
10
use PhpParser\Node\Scalar\DNumber;
11
use PhpParser\Node\Scalar\LNumber;
12
use PhpParser\Node\Scalar\String_;
13
use PhpParser\NodeTraverser;
14
use PhpParser\NodeVisitorAbstract;
15
use Povils\PHPMND\Console\Option;
16
use Povils\PHPMND\Extension\ArrayAwareExtension;
17
use Povils\PHPMND\Extension\Extension;
18
use Povils\PHPMND\Extension\FunctionAwareExtension;
19
use Povils\PHPMND\FileReport;
20
21
/**
22
 * Class DetectorVisitor
23
 *
24
 * @package Povils\PHPMND
25
 */
26
class DetectorVisitor extends NodeVisitorAbstract
27
{
28
    /**
29
     * @var FileReport
30
     */
31
    private $fileReport;
32
33
    /**
34
     * @var Option
35
     */
36
    private $option;
37
38
    /**
39
     * @param FileReport $fileReport
40
     * @param Option $option
41
     */
42
    public function __construct(FileReport $fileReport, Option $option)
43
    {
44
        $this->fileReport = $fileReport;
45
        $this->option = $option;
46
    }
47
48
    /**
49
     * @inheritdoc
50
     */
51
    public function enterNode(Node $node)
52
    {
53
        if ($node instanceof Const_) {
54
            return NodeTraverser::DONT_TRAVERSE_CHILDREN;
55
        }
56
57
        if ($this->isNumber($node) || $this->isString($node)) {
58
            /** @var LNumber|DNumber|String_ $scalar */
59
            $scalar = $node;
60
            if ($this->hasSign($node)) {
61
                $node = $node->getAttribute('parent');
62
                if ($this->isMinus($node)) {
63
                    $scalar->value = -$scalar->value;
64
                }
65
            }
66
            foreach ($this->option->getExtensions() as $extension) {
67
                $extension->setOption($this->option);
68
                if ($extension->extend($node)) {
69
                    $this->fileReport->addEntry($scalar->getLine(), $scalar->value);
70
71
                    return null;
72
                }
73
            }
74
        }
75
76
        return null;
77
    }
78
79
    /**
80
     * @param Node $node
81
     *
82
     * @return bool
83
     */
84
    private function isNumber(Node $node)
85
    {
86
        $isNumber = (
87
            $node instanceof LNumber ||
88
            $node instanceof DNumber ||
89
            $this->isValidNumeric($node)
90
        );
91
92
        return $isNumber && false === $this->ignoreNumber($node);
93
    }
94
95
    /**
96
     * @param Node $node
97
     *
98
     * @return bool
99
     */
100
    private function isString(Node $node)
101
    {
102
        return $this->option->includeStrings() && $node instanceof String_ && false === $this->ignoreString($node);
103
    }
104
105
    /**
106
     * @param LNumber|DNumber|Node $node
107
     *
108
     * @return bool
109
     */
110
    private function ignoreNumber(Node $node)
111
    {
112
        return in_array($node->value, $this->option->getIgnoreNumbers(), true);
113
    }
114
115
    /**
116
     * @param String_|Node $node
117
     *
118
     * @return bool
119
     */
120
    private function ignoreString(Node $node)
121
    {
122
        return in_array($node->value, $this->option->getIgnoreStrings(), true);
123
    }
124
125
    /**
126
     * @param Node $node
127
     *
128
     * @return bool
129
     */
130
    private function hasSign(Node $node)
131
    {
132
        return $node->getAttribute('parent') instanceof UnaryMinus || $node->getAttribute('parent') instanceof UnaryPlus;
133
    }
134
135
    /**
136
     * @param Node $node
137
     *
138
     * @return bool
139
     */
140
    private function isMinus(Node $node)
141
    {
142
        return $node instanceof UnaryMinus;
143
    }
144
145
    /**
146
     * @param Node $node
147
     * @return bool
148
     */
149
    private function isValidNumeric(Node $node)
150
    {
151
        return $this->option->includeNumericStrings() &&
152
        isset($node->value) &&
0 ignored issues
show
Bug introduced by
Accessing value on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
153
        is_numeric($node->value) &&
0 ignored issues
show
Bug introduced by
Accessing value on the interface PhpParser\Node suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
154
        false === $this->ignoreString($node);
155
    }
156
}
157