GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#837)
by E
07:31 queued 05:03
created

ReflectionClass::getOwnInterfaceNames()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 4
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace ApiGen\Parser\Reflection;
4
5
use ApiGen\Contracts\Parser\Reflection\ClassReflectionInterface;
6
use ApiGen\Contracts\Parser\Reflection\ConstantReflectionInterface;
7
use ApiGen\Contracts\Parser\Reflection\Extractors\ClassTraitElementsExtractorInterface;
8
use ApiGen\Contracts\Parser\Reflection\Extractors\ParentClassElementsExtractorInterface;
9
use ApiGen\Contracts\Parser\Reflection\MethodReflectionInterface;
10
use ApiGen\Contracts\Parser\Reflection\PropertyReflectionInterface;
11
use ApiGen\Contracts\Parser\Reflection\TokenReflection\ReflectionFactoryInterface;
12
use ApiGen\Parser\Reflection\Extractors\ClassTraitElementsExtractor;
13
use ApiGen\Parser\Reflection\Extractors\ParentClassElementsExtractor;
14
use InvalidArgumentException;
15
use TokenReflection\IReflectionClass;
16
17
final class ReflectionClass extends AbstractReflectionElement implements ClassReflectionInterface
18
{
19
    /**
20
     * @var ClassReflectionInterface[]
21
     */
22
    private $parentClasses;
23
24
    /**
25
     * @var PropertyReflectionInterface[]
26
     */
27
    private $properties;
28
29
    /**
30
     * @var PropertyReflectionInterface[]
31
     */
32
    private $ownProperties;
33
34
    /**
35
     * @var ConstantReflectionInterface[]
36
     */
37
    private $constants;
38
39
    /**
40
     * @var ConstantReflectionInterface[]
41
     */
42
    private $ownConstants;
43
44
    /**
45
     * @var MethodReflectionInterface[]
46
     */
47
    private $methods;
48
49
    /**
50
     * @var MethodReflectionInterface[]
51
     */
52
    private $ownMethods;
53
54
    /**
55
     * @var ClassTraitElementsExtractorInterface
56
     */
57
    private $classTraitElementExtractor;
58
59
    /**
60
     * @var ParentClassElementsExtractorInterface
61
     */
62
    private $parentClassElementExtractor;
63
64
    /**
65
     * @param mixed $reflectionClass
66
     */
67 127
    public function __construct($reflectionClass)
68
    {
69 127
        parent::__construct($reflectionClass);
70 127
        $this->classTraitElementExtractor = new ClassTraitElementsExtractor($this, $reflectionClass);
71 127
        $this->parentClassElementExtractor = new ParentClassElementsExtractor($this);
72 127
    }
73
74 6
    public function getShortName(): string
75
    {
76 6
        return $this->reflection->getShortName();
77
    }
78
79 2
    public function isAbstract(): bool
80
    {
81 2
        return $this->reflection->isAbstract();
82
    }
83
84 2
    public function isFinal(): bool
85
    {
86 2
        return $this->reflection->isFinal();
87
    }
88
89 8
    public function isInterface(): bool
90
    {
91 8
        return $this->reflection->isInterface();
92
    }
93
94 6
    public function isException(): bool
95
    {
96 6
        return $this->reflection->isException();
97
    }
98
99 3
    public function isSubclassOf(string $class): bool
100
    {
101 3
        return $this->reflection->isSubclassOf($class);
102
    }
103
104
    /**
105
     * @return MethodReflectionInterface[]
106
     */
107 29
    public function getMethods(): array
108
    {
109 29
        if ($this->methods === null) {
110 29
            $this->methods = $this->getOwnMethods();
111
112 29
            foreach ($this->getOwnTraits() as $trait) {
113 5
                if (!$trait instanceof ReflectionClass) {
114 5
                    continue;
115
                }
116
117 5
                foreach ($trait->getOwnMethods() as $method) {
118 5
                    if (isset($this->methods[$method->getName()])) {
119
                        continue;
120
                    }
121
122 5
                    if (! $this->isDocumented() || $method->isDocumented()) {
123 5
                        $this->methods[$method->getName()] = $method;
124
                    }
125
                }
126
            }
127
128 29
            if ($this->getParentClassName() !== null) {
129 5
                foreach ($this->getParentClass()->getMethods() as $parentMethod) {
130 5
                    if (!isset($this->methods[$parentMethod->getName()])) {
131 5
                        $this->methods[$parentMethod->getName()] = $parentMethod;
132
                    }
133
                }
134
            }
135
136 29
            foreach ($this->getOwnInterfaces() as $interface) {
137 5
                foreach ($interface->getMethods() as $parentMethod) {
138 5
                    if (!isset($this->methods[$parentMethod->getName()])) {
139 5
                        $this->methods[$parentMethod->getName()] = $parentMethod;
140
                    }
141
                }
142
            }
143
144
            $this->methods = array_filter($this->methods, function (ReflectionMethod $method) {
145 28
                return $method->configuration->getVisibilityLevel() === $this->getVisibilityLevel();
146 29
            });
147
        }
148
149 29
        return $this->methods;
150
    }
151
152
    /**
153
     * @return MethodReflectionInterface[]
154
     */
155 126
    public function getOwnMethods(): array
156
    {
157 126
        if ($this->ownMethods === null) {
158 126
            $this->ownMethods = [];
159
160 126
            foreach ($this->reflection->getOwnMethods($this->getVisibilityLevel()) as $method) {
161 108
                $apiMethod = $this->reflectionFactory->createFromReflection($method);
162 108
                if (! $this->isDocumented() || $apiMethod->isDocumented()) {
163 108
                    $this->ownMethods[$method->getName()] = $apiMethod;
164
                }
165
            }
166
        }
167
168 126
        return $this->ownMethods;
169
    }
170
171
    /**
172
     * @return MethodReflectionInterface[]
173
     */
174 1
    public function getTraitMethods(): array
175
    {
176 1
        return $this->classTraitElementExtractor->getTraitMethods();
177
    }
178
179 25
    public function getMethod(string $name): MethodReflectionInterface
180
    {
181 25
        if ($this->hasMethod($name)) {
182 24
            return $this->methods[$name];
183
        }
184
185 1
        throw new InvalidArgumentException(sprintf(
186 1
            'Method %s does not exist in class %s',
187
            $name,
188 1
            $this->reflection->getName()
189
        ));
190
    }
191
192
    /**
193
     * @return PropertyReflectionInterface[]
194
     */
195 18
    public function getProperties(): array
196
    {
197 18
        if ($this->properties === null) {
198 18
            $this->properties = $this->getOwnProperties();
199 18
            foreach ($this->reflection->getProperties($this->getVisibilityLevel()) as $property) {
200
                /** @var ReflectionElement $property */
201 18
                if (isset($this->properties[$property->getName()])) {
202 18
                    continue;
203
                }
204
205 4
                $apiProperty = $this->reflectionFactory->createFromReflection($property);
206 4
                if (! $this->isDocumented() || $apiProperty->isDocumented()) {
207 4
                    $this->properties[$property->getName()] = $apiProperty;
208
                }
209
            }
210
        }
211
212 18
        return $this->properties;
213
    }
214
215
    /**
216
     * @return PropertyReflectionInterface[]
217
     */
218 126
    public function getOwnProperties(): array
219
    {
220 126
        if ($this->ownProperties === null) {
221 126
            $this->ownProperties = [];
222 126
            foreach ($this->reflection->getOwnProperties($this->getVisibilityLevel()) as $property) {
223 107
                $apiProperty = $this->reflectionFactory->createFromReflection($property);
224 107
                if (! $this->isDocumented() || $apiProperty->isDocumented()) {
225
                    /** @var ReflectionElement $property */
226 107
                    $this->ownProperties[$property->getName()] = $apiProperty;
227
                }
228
            }
229
        }
230
231 126
        return $this->ownProperties;
232
    }
233
234
    /**
235
     * @return PropertyReflectionInterface[]
236
     */
237 1
    public function getTraitProperties(): array
238
    {
239 1
        return $this->classTraitElementExtractor->getTraitProperties();
240
    }
241
242 16
    public function getProperty(string $name): PropertyReflectionInterface
243
    {
244 16
        if ($this->hasProperty($name)) {
245 15
            return $this->properties[$name];
246
        }
247
248 1
        throw new InvalidArgumentException(sprintf(
249 1
            'Property %s does not exist in class %s',
250
            $name,
251 1
            $this->reflection->getName()
252
        ));
253
    }
254
255
    /**
256
     * @return ConstantReflectionInterface[]
257
     */
258 20
    public function getConstants(): array
259
    {
260 20
        if ($this->constants === null) {
261 20
            $this->constants = [];
262 20
            foreach ($this->reflection->getConstantReflections() as $constant) {
263 18
                $apiConstant = $this->reflectionFactory->createFromReflection($constant);
264 18
                if (! $this->isDocumented() || $apiConstant->isDocumented()) {
265
                    /** @var ReflectionElement $constant */
266 18
                    $this->constants[$constant->getName()] = $apiConstant;
267
                }
268
            }
269
        }
270
271 20
        return $this->constants;
272
    }
273
274
    /**
275
     * @return ConstantReflectionInterface[]
276
     */
277 7
    public function getOwnConstants(): array
278
    {
279 7
        if ($this->ownConstants === null) {
280 7
            $this->ownConstants = [];
281 7
            $className = $this->reflection->getName();
282 7
            foreach ($this->getConstants() as $constantName => $constant) {
283 5
                if ($className === $constant->getDeclaringClassName()) {
284 5
                    $this->ownConstants[$constantName] = $constant;
285
                }
286
            }
287
        }
288
289 7
        return $this->ownConstants;
290
    }
291
292 11
    public function getConstant(string $name): ConstantReflectionInterface
293
    {
294 11
        if (isset($this->getConstants()[$name])) {
295 10
            return $this->getConstants()[$name];
296
        }
297
298 1
        throw new InvalidArgumentException(sprintf(
299 1
            'Constant %s does not exist in class %s',
300
            $name,
301 1
            $this->reflection->getName()
302
        ));
303
    }
304
305 1
    public function hasConstant(string $name): bool
306
    {
307 1
        return isset($this->getConstants()[$name]);
308
    }
309
310 1
    public function hasOwnConstant(string $name): bool
311
    {
312 1
        return isset($this->getOwnConstants()[$name]);
313
    }
314
315 2
    public function getOwnConstant(string $name): ConstantReflectionInterface
316
    {
317 2
        if (isset($this->getOwnConstants()[$name])) {
318 1
            return $this->getOwnConstants()[$name];
319
        }
320
321 1
        throw new InvalidArgumentException(sprintf(
322 1
            'Constant %s does not exist in class %s',
323
            $name,
324 1
            $this->reflection->getName()
325
        ));
326
    }
327
328 7
    public function getParentClass(): ?ClassReflectionInterface
329
    {
330 7
        $parentClassName = $this->reflection->getParentClassName();
331
332 7
        if ($parentClassName) {
333 6
            return $this->getParsedClasses()[$parentClassName];
334
        }
335
336 1
        return null;
337
    }
338
339 32
    public function getParentClassName(): ?string
340
    {
341 32
        return $this->reflection->getParentClassName();
342
    }
343
344
    /**
345
     * @return ClassReflectionInterface[]
346
     */
347 5
    public function getParentClasses(): array
348
    {
349 5
        if ($this->parentClasses === null) {
350
            $this->parentClasses = array_map(function (IReflectionClass $class) {
351 4
                return $this->getParsedClasses()[$class->getName()];
352 5
            }, $this->reflection->getParentClasses());
353
        }
354
355 5
        return $this->parentClasses;
356
    }
357
358 3
    public function implementsInterface(string $interface): bool
359
    {
360 3
        return $this->reflection->implementsInterface($interface);
361
    }
362
363
    /**
364
     * @return ClassReflectionInterface[]
365
     */
366 4
    public function getInterfaces(): array
367
    {
368
        return array_map(function (IReflectionClass $class) {
369 3
            return $this->getParsedClasses()[$class->getName()];
370 4
        }, $this->reflection->getInterfaces());
371
    }
372
373
    /**
374
     * @return ClassReflectionInterface[]
375
     */
376 30
    public function getOwnInterfaces(): array
377
    {
378
        return array_map(function (IReflectionClass $class) {
379 6
            return $this->getParsedClasses()[$class->getName()];
380 30
        }, $this->reflection->getOwnInterfaces());
381
    }
382
383
    /**
384
     * @return string[]
385
     */
386 5
    public function getOwnInterfaceNames(): array
387
    {
388 5
        return $this->reflection->getOwnInterfaceNames();
389
    }
390
391
    /**
392
     * @return ClassReflectionInterface[]
393
     */
394 3
    public function getTraits(): array
395
    {
396
        return array_map(function (IReflectionClass $class) {
397 2
            if (! isset($this->getParsedClasses()[$class->getName()])) {
398 2
                return $class->getName();
399
            } else {
400 2
                return $this->getParsedClasses()[$class->getName()];
401
            }
402 3
        }, $this->reflection->getTraits());
403
    }
404
405
    /**
406
     * @return string[]
407
     */
408 1
    public function getTraitNames(): array
409
    {
410 1
        return $this->reflection->getTraitNames();
411
    }
412
413
    /**
414
     * @return string[]
415
     */
416 3
    public function getOwnTraitNames(): array
417
    {
418 3
        return $this->reflection->getOwnTraitNames();
419
    }
420
421
    /**
422
     * @return string[]
423
     */
424 1
    public function getTraitAliases(): array
425
    {
426 1
        return $this->reflection->getTraitAliases();
427
    }
428
429
    /**
430
     * @return ClassReflectionInterface[]
431
     */
432 30
    public function getOwnTraits(): array
433
    {
434
        return array_map(function (IReflectionClass $class) {
435 6
            if (! isset($this->getParsedClasses()[$class->getName()])) {
436 6
                return $class->getName();
437
            } else {
438 6
                return $this->getParsedClasses()[$class->getName()];
439
            }
440 30
        }, $this->reflection->getOwnTraits());
441
    }
442
443 8
    public function isTrait(): bool
444
    {
445 8
        return $this->reflection->isTrait();
446
    }
447
448 3
    public function usesTrait(string $trait): bool
449
    {
450 3
        return $this->reflection->usesTrait($trait);
451
    }
452
453
    /**
454
     * @return ClassReflectionInterface[]
455
     */
456 2
    public function getDirectSubClasses(): array
457
    {
458 2
        $subClasses = [];
459 2
        foreach ($this->getParsedClasses() as $class) {
460 2
            if ($class->isDocumented() && $this->getName() === $class->getParentClassName()) {
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
461 1
                $subClasses[] = $class;
462
            }
463
        }
464
465 2
        uksort($subClasses, 'strcasecmp');
466 2
        return $subClasses;
467
    }
468
469
    /**
470
     * @return ClassReflectionInterface[]
471
     */
472 2
    public function getIndirectSubClasses(): array
473
    {
474 2
        $subClasses = [];
475 2
        foreach ($this->getParsedClasses() as $class) {
476 2
            if ($class->isDocumented() && $this->getName() !== $class->getParentClassName()
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
477 2
                && $class->isSubclassOf($this->getName())
0 ignored issues
show
Bug introduced by
Consider using $this->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
478
            ) {
479
                $subClasses[] = $class;
480
            }
481
        }
482
483 2
        uksort($subClasses, 'strcasecmp');
484 2
        return $subClasses;
485
    }
486
487
    /**
488
     * @return ClassReflectionInterface[]
489
     */
490 2
    public function getDirectImplementers(): array
491
    {
492 2
        if (! $this->isInterface()) {
493 1
            return [];
494
        }
495
496 1
        return $this->parserStorage->getDirectImplementersOfInterface($this);
497
    }
498
499
    /**
500
     * @return ClassReflectionInterface[]
501
     */
502 2
    public function getIndirectImplementers(): array
503
    {
504 2
        if (! $this->isInterface()) {
505 1
            return [];
506
        }
507
508 1
        return $this->parserStorage->getIndirectImplementersOfInterface($this);
509
    }
510
511
    /**
512
     * @return ClassReflectionInterface[]
513
     */
514 2
    public function getDirectUsers(): array
515
    {
516 2
        if (! $this->isTrait()) {
517 1
            return [];
518
        }
519
520 1
        return $this->classTraitElementExtractor->getDirectUsers();
521
    }
522
523
    /**
524
     * @return ClassReflectionInterface[]
525
     */
526 2
    public function getIndirectUsers(): array
527
    {
528 2
        if (! $this->isTrait()) {
529 1
            return [];
530
        }
531
532 1
        return $this->classTraitElementExtractor->getIndirectUsers();
533
    }
534
535
    /**
536
     * @return MethodReflectionInterface[]
537
     */
538 2
    public function getInheritedMethods(): array
539
    {
540 2
        return $this->parentClassElementExtractor->getInheritedMethods();
541
    }
542
543
    /**
544
     * @return MethodReflectionInterface[]
545
     */
546 2
    public function getUsedMethods(): array
547
    {
548 2
        $usedMethods = $this->classTraitElementExtractor->getUsedMethods();
549 2
        return $this->sortUsedMethods($usedMethods);
550
    }
551
552
    /**
553
     * @return ConstantReflectionInterface[]
554
     */
555 2
    public function getInheritedConstants(): array
556
    {
557 2
        return $this->parentClassElementExtractor->getInheritedConstants();
558
    }
559
560
    /**
561
     * @return PropertyReflectionInterface[]
562
     */
563 2
    public function getInheritedProperties(): array
564
    {
565 2
        return $this->parentClassElementExtractor->getInheritedProperties();
566
    }
567
568
    /**
569
     * @return PropertyReflectionInterface[]
570
     */
571 2
    public function getUsedProperties(): array
572
    {
573 2
        return $this->classTraitElementExtractor->getUsedProperties();
574
    }
575
576 17
    public function hasProperty(string $name): bool
577
    {
578 17
        if ($this->properties === null) {
579 17
            $this->getProperties();
580
        }
581
582 17
        return isset($this->properties[$name]);
583
    }
584
585 26
    public function hasMethod(string $name): bool
586
    {
587 26
        return isset($this->getMethods()[$name]);
588
    }
589
590 126
    public function getVisibilityLevel(): int
591
    {
592 126
        return $this->configuration->getVisibilityLevel();
593
    }
594
595 2
    public function getReflectionFactory(): ReflectionFactoryInterface
596
    {
597 2
        return $this->reflectionFactory;
598
    }
599
600
    /**
601
     * @param mixed[] $usedMethods
602
     * @return mixed[]
603
     */
604 2
    private function sortUsedMethods(array $usedMethods): array
605
    {
606
        array_walk($usedMethods, function (&$methods) {
607 1
            ksort($methods);
608 1
            array_walk($methods, function (&$aliasedMethods) {
609 1
                if (! isset($aliasedMethods['aliases'])) {
610
                    $aliasedMethods['aliases'] = [];
611
                }
612
613 1
                ksort($aliasedMethods['aliases']);
614 1
            });
615 2
        });
616
617 2
        return $usedMethods;
618
    }
619
}
620