ClassDescriptor   B
last analyzed

Complexity

Total Complexity 46

Size/Duplication

Total Lines 338
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 92.56%

Importance

Changes 0
Metric Value
dl 0
loc 338
ccs 112
cts 121
cp 0.9256
rs 8.72
c 0
b 0
f 0
wmc 46
lcom 1
cbo 6

24 Methods

Rating   Name   Duplication   Size   Complexity  
A getUsedTraits() 0 4 1
A __construct() 0 10 1
A setParent() 0 4 1
A getParent() 0 4 1
A setInterfaces() 0 4 1
A getInterfaces() 0 4 1
A setFinal() 0 4 1
A isFinal() 0 4 1
A setAbstract() 0 4 1
A isAbstract() 0 4 1
A setConstants() 0 4 1
A getConstants() 0 4 1
A getInheritedConstants() 0 10 3
A setMethods() 0 4 1
A getMethods() 0 4 1
A getInheritedMethods() 0 20 5
A getMagicMethods() 0 31 4
A setProperties() 0 4 1
A getProperties() 0 4 1
A getInheritedProperties() 0 20 5
A getMagicProperties() 0 29 4
B setPackage() 0 25 7
A setUsedTraits() 0 4 1
A getInheritedElement() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like ClassDescriptor often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ClassDescriptor, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of phpDocumentor.
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @author    Mike van Riel <[email protected]>
11
 * @copyright 2010-2018 Mike van Riel / Naenius (http://www.naenius.com)
12
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
13
 * @link      http://phpdoc.org
14
 */
15
16
namespace phpDocumentor\Descriptor;
17
18
use phpDocumentor\Descriptor\Tag\BaseTypes\TypedVariableAbstract;
19
20
/**
21
 * Descriptor representing a Class.
22
 */
23
class ClassDescriptor extends DescriptorAbstract implements Interfaces\ClassInterface
24
{
25
    /** @var ClassDescriptor|null $extends Reference to an instance of the superclass for this class, if any. */
26
    protected $parent;
27
28
    /** @var Collection $implements References to interfaces that are implemented by this class. */
29
    protected $implements;
30
31
    /** @var boolean $abstract Whether this is an abstract class. */
32
    protected $abstract = false;
33
34
    /** @var boolean $final Whether this class is marked as final and can't be subclassed. */
35
    protected $final = false;
36
37
    /** @var Collection $constants References to constants defined in this class. */
38
    protected $constants;
39
40
    /** @var Collection $properties References to properties defined in this class. */
41
    protected $properties;
42
43
    /** @var Collection $methods References to methods defined in this class. */
44
    protected $methods;
45
46
    /** @var Collection $usedTraits References to traits consumed by this class */
47
    protected $usedTraits;
48
49
    /**
50
     * Initializes the all properties representing a collection with a new Collection object.
51
     */
52 1
    public function __construct()
53
    {
54 1
        parent::__construct();
55
56 1
        $this->setInterfaces(new Collection());
57 1
        $this->setUsedTraits(new Collection());
58 1
        $this->setConstants(new Collection());
59 1
        $this->setProperties(new Collection());
60 1
        $this->setMethods(new Collection());
61 1
    }
62
63
    /**
64
     * {@inheritDoc}
65
     */
66 2
    public function setParent($parents)
67
    {
68 2
        $this->parent = $parents;
0 ignored issues
show
Documentation Bug introduced by Mike van Riel
It seems like $parents of type object<phpDocumentor\Des...tor\DescriptorAbstract> is incompatible with the declared type object<phpDocumentor\Des...r\ClassDescriptor>|null of property $parent.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
69 2
    }
70
71
    /**
72
     * {@inheritDoc}
73
     */
74 1
    public function getParent()
75
    {
76 1
        return $this->parent;
77
    }
78
79
    /**
80
     * {@inheritDoc}
81
     */
82 1
    public function setInterfaces(Collection $implements)
83
    {
84 1
        $this->implements = $implements;
85 1
    }
86
87
    /**
88
     * {@inheritDoc}
89
     */
90 1
    public function getInterfaces()
91
    {
92 1
        return $this->implements;
93
    }
94
95
    /**
96
     * {@inheritDoc}
97
     */
98 1
    public function setFinal($final)
99
    {
100 1
        $this->final = $final;
101 1
    }
102
103
    /**
104
     * {@inheritDoc}
105
     */
106 1
    public function isFinal()
107
    {
108 1
        return $this->final;
109
    }
110
111
    /**
112
     * {@inheritDoc}
113
     */
114 1
    public function setAbstract($abstract)
115
    {
116 1
        $this->abstract = $abstract;
117 1
    }
118
119
    /**
120
     * {@inheritDoc}
121
     */
122 1
    public function isAbstract()
123
    {
124 1
        return $this->abstract;
125
    }
126
127
    /**
128
     * {@inheritDoc}
129
     */
130 1
    public function setConstants(Collection $constants)
131
    {
132 1
        $this->constants = $constants;
133 1
    }
134
135
    /**
136
     * {@inheritDoc}
137
     */
138 1
    public function getConstants()
139
    {
140 1
        return $this->constants;
141
    }
142
143
    /**
144
     * {@inheritDoc}
145
     */
146 2
    public function getInheritedConstants()
147
    {
148 2
        if (!$this->getParent() || (!$this->getParent() instanceof self)) {
149 1
            return new Collection();
150
        }
151
152 1
        $inheritedConstants = clone $this->getParent()->getConstants();
153
154 1
        return $inheritedConstants->merge($this->getParent()->getInheritedConstants());
0 ignored issues
show
Documentation introduced by Mike van Riel
$this->getParent()->getInheritedConstants() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
155
    }
156
157
    /**
158
     * {@inheritDoc}
159
     */
160 1
    public function setMethods(Collection $methods)
161
    {
162 1
        $this->methods = $methods;
163 1
    }
164
165
    /**
166
     * {@inheritDoc}
167
     */
168 1
    public function getMethods()
169
    {
170 1
        return $this->methods;
171
    }
172
173
    /**
174
     * {@inheritDoc}
175
     */
176 4
    public function getInheritedMethods()
177
    {
178 4
        $inheritedMethods = new Collection();
179
180 4
        foreach ($this->getUsedTraits() as $trait) {
181 2
            if (!$trait instanceof TraitDescriptor) {
182 1
                continue;
183
            }
184
185 1
            $inheritedMethods = $inheritedMethods->merge(clone $trait->getMethods());
0 ignored issues
show
Documentation introduced by Mike van Riel
clone $trait->getMethods() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
186
        }
187
188 4
        if (!$this->getParent() || (!$this->getParent() instanceof self)) {
189 3
            return $inheritedMethods;
190
        }
191
192 1
        $inheritedMethods = $inheritedMethods->merge(clone $this->getParent()->getMethods());
0 ignored issues
show
Documentation introduced by Mike van Riel
clone $this->getParent()->getMethods() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
193
194 1
        return $inheritedMethods->merge($this->getParent()->getInheritedMethods());
0 ignored issues
show
Documentation introduced by Mike van Riel
$this->getParent()->getInheritedMethods() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
195
    }
196
197
    /**
198
     * @return Collection
199
     */
200 2
    public function getMagicMethods()
201
    {
202
        /** @var Collection $methodTags */
203 2
        $methodTags = clone $this->getTags()->get('method', new Collection());
204
205 2
        $methods = new Collection();
206
207
        /** @var Tag\MethodDescriptor $methodTag */
208 2
        foreach ($methodTags as $methodTag) {
209 2
            $method = new MethodDescriptor();
210 2
            $method->setName($methodTag->getMethodName());
211 2
            $method->setDescription($methodTag->getDescription());
212 2
            $method->setStatic($methodTag->isStatic());
213 2
            $method->setParent($this);
214
215 2
            $returnTags = $method->getTags()->get('return', new Collection());
216 2
            $returnTags->add($methodTag->getResponse());
217
218 2
            foreach ($methodTag->getArguments() as $name => $argument) {
219
                $method->addArgument($name, $argument);
220
            }
221
222 2
            $methods->add($method);
223
        }
224
225 2
        if ($this->getParent() instanceof static) {
226 2
            $methods = $methods->merge($this->getParent()->getMagicMethods());
0 ignored issues
show
Documentation introduced by Mike van Riel
$this->getParent()->getMagicMethods() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
227
        }
228
229 2
        return $methods;
230
    }
231
232
    /**
233
     * {@inheritDoc}
234
     */
235 1
    public function setProperties(Collection $properties)
236
    {
237 1
        $this->properties = $properties;
238 1
    }
239
240
    /**
241
     * {@inheritDoc}
242
     */
243 1
    public function getProperties()
244
    {
245 1
        return $this->properties;
246
    }
247
248
    /**
249
     * {@inheritDoc}
250
     */
251 4
    public function getInheritedProperties()
252
    {
253 4
        $inheritedProperties = new Collection();
254
255 4
        foreach ($this->getUsedTraits() as $trait) {
256 2
            if (!$trait instanceof TraitDescriptor) {
257 1
                continue;
258
            }
259
260 1
            $inheritedProperties = $inheritedProperties->merge(clone $trait->getProperties());
0 ignored issues
show
Documentation introduced by Mike van Riel
clone $trait->getProperties() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
261
        }
262
263 4
        if (!$this->getParent() || (!$this->getParent() instanceof self)) {
264 3
            return $inheritedProperties;
265
        }
266
267 1
        $inheritedProperties = $inheritedProperties->merge(clone $this->getParent()->getProperties());
0 ignored issues
show
Documentation introduced by Mike van Riel
clone $this->getParent()->getProperties() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
268
269 1
        return $inheritedProperties->merge($this->getParent()->getInheritedProperties());
0 ignored issues
show
Documentation introduced by Mike van Riel
$this->getParent()->getInheritedProperties() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
270
    }
271
272
    /**
273
     * @return Collection
274
     */
275 1
    public function getMagicProperties()
276
    {
277
        /** @var Collection $propertyTags */
278 1
        $propertyTags = clone $this->getTags()->get('property', new Collection());
279 1
        $propertyTags = $propertyTags->merge($this->getTags()->get('property-read', new Collection()));
280 1
        $propertyTags = $propertyTags->merge($this->getTags()->get('property-write', new Collection()));
281
282 1
        $properties = new Collection();
283
284
        /** @var Tag\PropertyDescriptor $propertyTag */
285 1
        foreach ($propertyTags as $propertyTag) {
286 1
            if (! $propertyTag instanceof TypedVariableAbstract) {
287
                continue;
288
            }
289 1
            $property = new PropertyDescriptor();
290 1
            $property->setName(ltrim($propertyTag->getVariableName(), '$'));
291 1
            $property->setDescription($propertyTag->getDescription());
292 1
            $property->setType($propertyTag->getType());
293 1
            $property->setParent($this);
294
295 1
            $properties->add($property);
296
        }
297
298 1
        if ($this->getParent() instanceof self) {
299 1
            $properties = $properties->merge($this->getParent()->getMagicProperties());
0 ignored issues
show
Documentation introduced by Mike van Riel
$this->getParent()->getMagicProperties() is of type object<phpDocumentor\Descriptor\Collection>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
300
        }
301
302 1
        return $properties;
303
    }
304
305
    /**
306
     * @param PackageDescriptor $package
307
     */
308 1
    public function setPackage($package)
309
    {
310 1
        parent::setPackage($package);
311
312 1
        foreach ($this->getConstants() as $constant) {
313
            // TODO #840: Workaround; for some reason there are NULLs in the constants array.
314 1
            if ($constant) {
315 1
                $constant->setPackage($package);
316
            }
317
        }
318
319 1
        foreach ($this->getProperties() as $property) {
320
            // TODO #840: Workaround; for some reason there are NULLs in the properties array.
321 1
            if ($property) {
322 1
                $property->setPackage($package);
323
            }
324
        }
325
326 1
        foreach ($this->getMethods() as $method) {
327
            // TODO #840: Workaround; for some reason there are NULLs in the methods array.
328 1
            if ($method) {
329 1
                $method->setPackage($package);
330
            }
331
        }
332 1
    }
333
334
    /**
335
     * Sets a collection of all traits used by this class.
336
     *
337
     * @param Collection $usedTraits
338
     */
339
    public function setUsedTraits($usedTraits)
340
    {
341
        $this->usedTraits = $usedTraits;
342
    }
343
344
    /**
345
     * Returns the traits used by this class.
346
     *
347
     * Returned values may either be a string (when the Trait is not in this project) or a TraitDescriptor.
348
     *
349
     * @return Collection
350
     */
351
    public function getUsedTraits()
352
    {
353
        return $this->usedTraits;
354
    }
355
356
    public function getInheritedElement()
357
    {
358
        return $this->getParent();
359
    }
360
}
361