Passed
Pull Request — master (#18)
by Andru
03:44
created

AbstractNode   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 1

Test Coverage

Coverage 88.68%

Importance

Changes 0
Metric Value
dl 0
loc 251
ccs 47
cts 53
cp 0.8868
rs 10
c 0
b 0
f 0
wmc 22
lcom 2
cbo 1

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A __call() 0 9 2
A getParent() 0 7 2
A getChild() 0 7 1
A findChildrenOfType() 0 10 2
A isInstanceOf() 0 5 1
A getImage() 0 4 1
A getName() 0 4 1
A getBeginLine() 0 4 1
A getEndLine() 0 4 1
A getFileName() 0 4 1
A getNode() 0 4 1
A getType() 0 5 1
A getMetric() 0 7 2
A setMetrics() 0 6 2
hasSuppressWarningsAnnotationFor() 0 1 ?
getFullQualifiedName() 0 1 ?
getParentName() 0 1 ?
getNamespaceName() 0 1 ?
A getFirstChildOfType() 0 8 2
1
<?php
2
/**
3
 * This file is part of PHP Mess Detector.
4
 *
5
 * Copyright (c) Manuel Pichler <[email protected]>.
6
 * All rights reserved.
7
 *
8
 * Licensed under BSD License
9
 * For full copyright and license information, please see the LICENSE file.
10
 * Redistributions of files must retain the above copyright notice.
11
 *
12
 * @author Manuel Pichler <[email protected]>
13
 * @copyright Manuel Pichler. All rights reserved.
14
 * @license https://opensource.org/licenses/bsd-license.php BSD License
15
 * @link http://phpmd.org/
16
 */
17
18
namespace PHPMD;
19
20
use PHPMD\Node\ASTNode;
21
22
/**
23
 * This is an abstract base class for PHPMD code nodes, it is just a wrapper
24
 * around PDepend's object model.
25
 */
26
abstract class AbstractNode
27
{
28
    /**
29
     *
30
     * @var \PDepend\Source\AST\ASTArtifact|\PDepend\Source\AST\ASTNode $node
31
     */
32
    private $node = null;
33
34
    /**
35
     * The collected metrics for this node.
36
     *
37
     * @var array(string=>mixed) $_metrics
0 ignored issues
show
Documentation introduced by
The doc-type array(string=>mixed) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
38
     */
39
    private $metrics = null;
40
41
    /**
42
     * Constructs a new PHPMD node.
43
     *
44
     * @param \PDepend\Source\AST\ASTArtifact|\PDepend\Source\AST\ASTNode $node
45
     */
46 50
    public function __construct($node)
47
    {
48 50
        $this->node = $node;
49 50
    }
50
51
    /**
52
     * The magic call method is used to pipe requests from rules direct
53
     * to the underlying PDepend ast node.
54
     *
55
     * @param string $name
56
     * @param array $args
57
     * @return mixed
58
     * @throws \BadMethodCallException When the underlying PDepend node
59
     *         does not contain a method named <b>$name</b>.
60
     */
61 34
    public function __call($name, array $args)
62
    {
63 34
        if (method_exists($this->getNode(), $name)) {
64 34
            return call_user_func_array(array($this->getNode(), $name), $args);
65
        }
66
        throw new \BadMethodCallException(
67
            sprintf('Invalid method %s() called.', $name)
68
        );
69
    }
70
71
    /**
72
     * Returns the parent of this node or <b>null</b> when no parent node
73
     * exists.
74
     *
75
     * @return ASTNode
76
     */
77 9
    public function getParent()
78
    {
79 9
        if (($node = $this->node->getParent()) === null) {
0 ignored issues
show
Bug introduced by
The method getParent does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
80
            return null;
81
        }
82 9
        return new ASTNode($node, $this->getFileName());
83
    }
84
85
    /**
86
     * Returns a child node at the given index.
87
     *
88
     * @param integer $index The child offset.
89
     * @return \PHPMD\Node\ASTNode
90
     */
91 11
    public function getChild($index)
92
    {
93 11
        return new ASTNode(
94 11
            $this->node->getChild($index),
0 ignored issues
show
Bug introduced by
The method getChild does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
95 11
            $this->getFileName()
96
        );
97
    }
98
99
    /**
100
     * Returns the first child of the given type or <b>null</b> when this node
101
     * has no child of the given type.
102
     *
103
     * @param string $type The searched child type.
104
     * @return \PHPMD\AbstractNode
105
     */
106 9
    public function getFirstChildOfType($type)
107
    {
108 9
        $node = $this->node->getFirstChildOfType('PDepend\Source\AST\AST' . $type);
0 ignored issues
show
Bug introduced by
The method getFirstChildOfType does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
109 9
        if ($node === null) {
110 2
            return null;
111
        }
112 7
        return new ASTNode($node, $this->getFileName());
113
    }
114
115
    /**
116
     * Searches recursive for all children of this node that are of the given
117
     * type.
118
     *
119
     * @param string $type The searched child type.
120
     * @return \PHPMD\AbstractNode[]
121
     */
122 48
    public function findChildrenOfType($type)
123
    {
124 48
        $children = $this->node->findChildrenOfType('PDepend\Source\AST\AST' . $type);
0 ignored issues
show
Bug introduced by
The method findChildrenOfType does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
125
126 48
        $nodes = array();
127 48
        foreach ($children as $child) {
128 44
            $nodes[] = new ASTNode($child, $this->getFileName());
129
        }
130 48
        return $nodes;
131
    }
132
133
    /**
134
     * Tests if this node represents the the given type.
135
     *
136
     * @param string $type The expected node type.
137
     * @return boolean
138
     */
139 2
    public function isInstanceOf($type)
140
    {
141 2
        $class = 'PDepend\Source\AST\AST' . $type;
142 2
        return ($this->node instanceof $class);
143
    }
144
145
    /**
146
     * Returns the image of the underlying node.
147
     *
148
     * @return string
149
     */
150 2
    public function getImage()
151
    {
152 2
        return $this->node->getName();
0 ignored issues
show
Bug introduced by
The method getName does only exist in PDepend\Source\AST\ASTArtifact, but not in PDepend\Source\AST\ASTNode.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
153
    }
154
155
    /**
156
     * Returns the source name for this node, maybe a class or interface name,
157
     * or a package, method, function name.
158
     *
159
     * @return string
160
     */
161 15
    public function getName()
162
    {
163 15
        return $this->node->getName();
0 ignored issues
show
Bug introduced by
The method getName does only exist in PDepend\Source\AST\ASTArtifact, but not in PDepend\Source\AST\ASTNode.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
164
    }
165
166
    /**
167
     * Returns the begin line for this node in the php source code file.
168
     *
169
     * @return integer
170
     */
171 6
    public function getBeginLine()
172
    {
173 6
        return $this->node->getStartLine();
0 ignored issues
show
Bug introduced by
The method getStartLine does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
174
    }
175
176
    /**
177
     * Returns the end line for this node in the php source code file.
178
     *
179
     * @return integer
180
     */
181
    public function getEndLine()
182
    {
183
        return $this->node->getEndLine();
0 ignored issues
show
Bug introduced by
The method getEndLine does only exist in PDepend\Source\AST\ASTNode, but not in PDepend\Source\AST\ASTArtifact.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
184
    }
185
186
    /**
187
     * Returns the name of the declaring source file.
188
     *
189
     * @return string
190
     */
191 47
    public function getFileName()
192
    {
193 47
        return (string) $this->node->getCompilationUnit()->getFileName();
194
    }
195
196
    /**
197
     * Returns the wrapped PDepend node instance.
198
     *
199
     * @return \PDepend\Source\AST\ASTArtifact
200
     */
201 44
    public function getNode()
202
    {
203 44
        return $this->node;
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->node; of type PDepend\Source\AST\ASTAr...pend\Source\AST\ASTNode adds the type PDepend\Source\AST\ASTNode to the return on line 203 which is incompatible with the return type documented by PHPMD\AbstractNode::getNode of type PDepend\Source\AST\ASTArtifact.
Loading history...
204
    }
205
206
    /**
207
     * Returns a textual representation/name for the concrete node type.
208
     *
209
     * @return string
210
     */
211 3
    public function getType()
212
    {
213 3
        $type = explode('\\', get_class($this));
214 3
        return preg_replace('(node$)', '', strtolower(array_pop($type)));
215
    }
216
217
    /**
218
     * This method will return the metric value for the given identifier or
219
     * <b>null</b> when no such metric exists.
220
     *
221
     * @param string $name The metric name or abbreviation.
222
     * @return mixed
223
     */
224 3
    public function getMetric($name)
225
    {
226 3
        if (isset($this->metrics[$name])) {
227 3
            return $this->metrics[$name];
228
        }
229
        return null;
230
    }
231
232
    /**
233
     * This method will set the metrics for this node.
234
     *
235
     * @param array(string=>mixed) $metrics The collected node metrics.
0 ignored issues
show
Documentation introduced by
The doc-type array(string=>mixed) could not be parsed: Expected "|" or "end of type", but got "(" at position 5. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
236
     * @return void
237
     */
238 6
    public function setMetrics(array $metrics)
239
    {
240 6
        if ($this->metrics === null) {
241 6
            $this->metrics = $metrics;
242
        }
243 6
    }
244
245
    /**
246
     * Checks if this node has a suppressed annotation for the given rule
247
     * instance.
248
     *
249
     * @param \PHPMD\Rule $rule
250
     * @return boolean
251
     */
252
    abstract public function hasSuppressWarningsAnnotationFor(Rule $rule);
253
254
    /**
255
     * Returns the full qualified name of a class, an interface, a method or
256
     * a function.
257
     *
258
     * @return string
259
     */
260
    abstract public function getFullQualifiedName();
261
262
    /**
263
     * Returns the name of the parent type or <b>null</b> when this node has no
264
     * parent type.
265
     *
266
     * @return string
267
     */
268
    abstract public function getParentName();
269
270
    /**
271
     * Returns the name of the parent package.
272
     *
273
     * @return string
274
     */
275
    abstract public function getNamespaceName();
276
}
277