Completed
Push — master ( 253768...f248bf )
by Alexander
02:29
created

ReflectionClass::collectInterfacesFromClassNode()   C

Complexity

Conditions 7
Paths 8

Size

Total Lines 22
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 22
ccs 18
cts 18
cp 1
rs 6.9811
cc 7
eloc 15
nc 8
nop 1
crap 7
1
<?php
2
/**
3
 * Parser Reflection API
4
 *
5
 * @copyright Copyright 2015, Lisachenko Alexander <[email protected]>
6
 *
7
 * This source file is subject to the license that is bundled
8
 * with this source code in the file LICENSE.
9
 */
10
11
namespace Go\ParserReflection;
12
13
use Go\ParserReflection\Traits\ReflectionClassLikeTrait;
14
use PhpParser\Node\Name;
15
use PhpParser\Node\Name\FullyQualified;
16
use PhpParser\Node\Stmt\ClassLike;
17
use PhpParser\Node\Stmt\Interface_;
18
use PhpParser\Node\Stmt\TraitUse;
19
use ReflectionClass as InternalReflectionClass;
20
21
/**
22
 * AST-based reflection class
23
 */
24
class ReflectionClass extends InternalReflectionClass
25
{
26
    use ReflectionClassLikeTrait;
27
28
    /**
29
     * Initializes reflection instance
30
     *
31
     * @param string|object $argument Class name or instance of object
32
     * @param ClassLike $classLikeNode AST node for class
33
     */
34 17
    public function __construct($argument, ClassLike $classLikeNode = null)
35
    {
36 17
        $fullClassName       = is_object($argument) ? get_class($argument) : $argument;
37 17
        $namespaceParts      = explode('\\', $fullClassName);
38 17
        $this->className     = array_pop($namespaceParts);
39 17
        $this->namespaceName = join('\\', $namespaceParts);
40
41 17
        $this->classLikeNode = $classLikeNode ?: ReflectionEngine::parseClass($fullClassName);
42 17
    }
43
44
    /**
45
     * Parses interfaces from the concrete class node
46
     *
47
     * @param ClassLike $classLikeNode Class-like node
48
     *
49
     * @return array|\ReflectionClass[] List of reflections of interfaces
50
     */
51 9
    public static function collectInterfacesFromClassNode(ClassLike $classLikeNode)
52
    {
53 9
        $interfaces = [];
54
55 9
        $isInterface    = $classLikeNode instanceof Interface_;
56 9
        $interfaceField = $isInterface ? 'extends' : 'implements';
57 9
        $hasInterfaces  = in_array($interfaceField, $classLikeNode->getSubNodeNames());
58 9
        $implementsList = $hasInterfaces ? $classLikeNode->$interfaceField : array();
59 9
        if ($implementsList) {
60 1
            foreach ($implementsList as $implementNode) {
61 1
                if ($implementNode instanceof FullyQualified) {
62 1
                    $implementName  = $implementNode->toString();
63 1
                    $interface      = interface_exists($implementName, false)
64 1
                        ? new parent($implementName)
65 1
                        : new static($implementName);
66 1
                    $interfaces[$implementName] = $interface;
67 1
                }
68 1
            }
69 1
        }
70
71 9
        return $interfaces;
72
    }
73
74
    /**
75
     * Parses traits from the concrete class node
76
     *
77
     * @param ClassLike $classLikeNode Class-like node
78
     *
79
     * @return array|\ReflectionClass[] List of reflections of traits
80
     */
81 2
    public static function collectTraitsFromClassNode(ClassLike $classLikeNode)
82
    {
83 2
        $traits = [];
84
85 2
        if ($classLikeNode->stmts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $classLikeNode->stmts of type PhpParser\Node[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
86 2
            foreach ($classLikeNode->stmts as $classLevelNode) {
87 2
                if ($classLevelNode instanceof TraitUse) {
88 1
                    foreach ($classLevelNode->traits as $classTraitName) {
89 1
                        if ($classTraitName instanceof FullyQualified) {
90 1
                            $traitName  = $classTraitName->toString();
91 1
                            $trait      = trait_exists($traitName, false)
92 1
                                ? new parent($traitName)
93 1
                                : new static($traitName);
94 1
                            $traits[$traitName] = $trait;
95 1
                        }
96 1
                    }
97 1
                }
98 2
            }
99 2
        }
100
101 2
        return $traits;
102
    }
103
104
    /**
105
     * Implementation of internal reflection initialization
106
     *
107
     * @return void
108
     */
109 4
    protected function __initialize()
110
    {
111 4
        parent::__construct($this->getName());
112 4
    }
113
}
114