Completed
Push — develop ( 722f70...af048b )
by Jaap
15:12 queued 05:04
created

ClassDescriptor   B

Complexity

Total Complexity 45

Size/Duplication

Total Lines 336
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
dl 0
loc 336
rs 8.3673
c 0
b 0
f 0
wmc 45
lcom 1
cbo 5

24 Methods

Rating   Name   Duplication   Size   Complexity  
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
B getInheritedMethods() 0 20 5
B getMagicMethods() 0 30 4
A setProperties() 0 4 1
A getProperties() 0 4 1
B getInheritedProperties() 0 20 5
B getMagicProperties() 0 26 3
C setPackage() 0 25 7
A setUsedTraits() 0 4 1
A getUsedTraits() 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
/**
3
 * phpDocumentor
4
 *
5
 * PHP Version 5.3
6
 *
7
 * @copyright 2010-2014 Mike van Riel / Naenius (http://www.naenius.com)
8
 * @license   http://www.opensource.org/licenses/mit-license.php MIT
9
 * @link      http://phpdoc.org
10
 */
11
12
namespace phpDocumentor\Descriptor;
13
14
/**
15
 * Descriptor representing a Class.
16
 */
17
class ClassDescriptor extends DescriptorAbstract implements Interfaces\ClassInterface
18
{
19
    /** @var ClassDescriptor|null $extends Reference to an instance of the superclass for this class, if any. */
20
    protected $parent;
21
22
    /** @var Collection $implements References to interfaces that are implemented by this class. */
23
    protected $implements;
24
25
    /** @var boolean $abstract Whether this is an abstract class. */
26
    protected $abstract = false;
27
28
    /** @var boolean $final Whether this class is marked as final and can't be subclassed. */
29
    protected $final = false;
30
31
    /** @var Collection $constants References to constants defined in this class. */
32
    protected $constants;
33
34
    /** @var Collection $properties References to properties defined in this class. */
35
    protected $properties;
36
37
    /** @var Collection $methods References to methods defined in this class. */
38
    protected $methods;
39
40
    /** @var Collection $usedTraits References to traits consumed by this class */
41
    protected $usedTraits = array();
42
43
    /**
44
     * Initializes the all properties representing a collection with a new Collection object.
45
     */
46
    public function __construct()
47
    {
48
        parent::__construct();
49
50
        $this->setInterfaces(new Collection());
51
        $this->setUsedTraits(new Collection());
52
        $this->setConstants(new Collection());
53
        $this->setProperties(new Collection());
54
        $this->setMethods(new Collection());
55
    }
56
57
    /**
58
     * {@inheritDoc}
59
     */
60
    public function setParent($parents)
61
    {
62
        $this->parent = $parents;
0 ignored issues
show
Documentation Bug introduced by
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...
63
    }
64
65
    /**
66
     * {@inheritDoc}
67
     */
68
    public function getParent()
69
    {
70
        return $this->parent;
71
    }
72
73
    /**
74
     * {@inheritDoc}
75
     */
76
    public function setInterfaces(Collection $implements)
77
    {
78
        $this->implements = $implements;
79
    }
80
81
    /**
82
     * {@inheritDoc}
83
     */
84
    public function getInterfaces()
85
    {
86
        return $this->implements;
87
    }
88
89
    /**
90
     * {@inheritDoc}
91
     */
92
    public function setFinal($final)
93
    {
94
        $this->final = $final;
95
    }
96
97
    /**
98
     * {@inheritDoc}
99
     */
100
    public function isFinal()
101
    {
102
        return $this->final;
103
    }
104
105
    /**
106
     * {@inheritDoc}
107
     */
108
    public function setAbstract($abstract)
109
    {
110
        $this->abstract = $abstract;
111
    }
112
113
    /**
114
     * {@inheritDoc}
115
     */
116
    public function isAbstract()
117
    {
118
        return $this->abstract;
119
    }
120
121
    /**
122
     * {@inheritDoc}
123
     */
124
    public function setConstants(Collection $constants)
125
    {
126
        $this->constants = $constants;
127
    }
128
129
    /**
130
     * {@inheritDoc}
131
     */
132
    public function getConstants()
133
    {
134
        return $this->constants;
135
    }
136
137
    /**
138
     * {@inheritDoc}
139
     */
140
    public function getInheritedConstants()
141
    {
142
        if (!$this->getParent() || (!$this->getParent() instanceof ClassDescriptor)) {
143
            return new Collection();
144
        }
145
146
        $inheritedConstants = clone $this->getParent()->getConstants();
147
148
        return $inheritedConstants->merge($this->getParent()->getInheritedConstants());
149
    }
150
151
    /**
152
     * {@inheritDoc}
153
     */
154
    public function setMethods(Collection $methods)
155
    {
156
        $this->methods = $methods;
157
    }
158
159
    /**
160
     * {@inheritDoc}
161
     */
162
    public function getMethods()
163
    {
164
        return $this->methods;
165
    }
166
167
    /**
168
     * {@inheritDoc}
169
     */
170
    public function getInheritedMethods()
171
    {
172
        $inheritedMethods = new Collection();
173
174
        foreach ($this->getUsedTraits() as $trait) {
175
            if (!$trait instanceof TraitDescriptor) {
176
                continue;
177
            }
178
179
            $inheritedMethods = $inheritedMethods->merge(clone $trait->getMethods());
180
        }
181
182
        if (!$this->getParent() || (!$this->getParent() instanceof ClassDescriptor)) {
183
            return $inheritedMethods;
184
        }
185
186
        $inheritedMethods = $inheritedMethods->merge(clone $this->getParent()->getMethods());
187
188
        return $inheritedMethods->merge($this->getParent()->getInheritedMethods());
189
    }
190
191
    /**
192
     * @return Collection
193
     */
194
    public function getMagicMethods()
195
    {
196
        /** @var Collection $methodTags */
197
        $methodTags = clone $this->getTags()->get('method', new Collection());
198
199
        $methods = new Collection();
200
201
        /** @var Tag\MethodDescriptor $methodTag */
202
        foreach ($methodTags as $methodTag) {
203
            $method = new MethodDescriptor();
204
            $method->setName($methodTag->getMethodName());
205
            $method->setDescription($methodTag->getDescription());
206
            $method->setParent($this);
207
208
            $returnTags = $method->getTags()->get('return', new Collection());
209
            $returnTags->add($methodTag->getResponse());
210
211
            foreach ($methodTag->getArguments() as $name => $argument) {
212
                $method->addArgument($name, $argument);
213
            }
214
215
            $methods->add($method);
216
        }
217
218
        if ($this->getParent() instanceof static) {
219
            $methods = $methods->merge($this->getParent()->getMagicMethods());
220
        }
221
222
        return $methods;
223
    }
224
225
    /**
226
     * {@inheritDoc}
227
     */
228
    public function setProperties(Collection $properties)
229
    {
230
        $this->properties = $properties;
231
    }
232
233
    /**
234
     * {@inheritDoc}
235
     */
236
    public function getProperties()
237
    {
238
        return $this->properties;
239
    }
240
241
    /**
242
     * {@inheritDoc}
243
     */
244
    public function getInheritedProperties()
245
    {
246
        $inheritedProperties = new Collection();
247
248
        foreach ($this->getUsedTraits() as $trait) {
249
            if (!$trait instanceof TraitDescriptor) {
250
                continue;
251
            }
252
253
            $inheritedProperties = $inheritedProperties->merge(clone $trait->getProperties());
254
        }
255
256
        if (!$this->getParent() || (!$this->getParent() instanceof ClassDescriptor)) {
257
            return $inheritedProperties;
258
        }
259
260
        $inheritedProperties = $inheritedProperties->merge(clone $this->getParent()->getProperties());
261
262
        return $inheritedProperties->merge($this->getParent()->getInheritedProperties());
263
    }
264
265
    /**
266
     * @return Collection
267
     */
268
    public function getMagicProperties()
269
    {
270
        /** @var Collection $propertyTags */
271
        $propertyTags = clone $this->getTags()->get('property', new Collection());
272
        $propertyTags = $propertyTags->merge($this->getTags()->get('property-read', new Collection()));
273
        $propertyTags = $propertyTags->merge($this->getTags()->get('property-write', new Collection()));
274
275
        $properties = new Collection();
276
277
        /** @var Tag\PropertyDescriptor $propertyTag */
278
        foreach ($propertyTags as $propertyTag) {
279
            $property = new PropertyDescriptor();
280
            $property->setName(ltrim($propertyTag->getVariableName(), '$'));
281
            $property->setDescription($propertyTag->getDescription());
282
            $property->setTypes($propertyTag->getTypes());
283
            $property->setParent($this);
284
285
            $properties->add($property);
286
        }
287
288
        if ($this->getParent() instanceof ClassDescriptor) {
289
            $properties = $properties->merge($this->getParent()->getMagicProperties());
290
        }
291
292
        return $properties;
293
    }
294
295
    /**
296
     * @param string $package
297
     */
298
    public function setPackage($package)
299
    {
300
        parent::setPackage($package);
0 ignored issues
show
Documentation introduced by
$package is of type string, but the function expects a object<phpDocumentor\Des...ptor\PackageDescriptor>.

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