forked from goaop/parser-reflection
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathReflectionClass.php
More file actions
129 lines (115 loc) · 4.25 KB
/
ReflectionClass.php
File metadata and controls
129 lines (115 loc) · 4.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php
/**
* Parser Reflection API
*
* @copyright Copyright 2015, Lisachenko Alexander <lisachenko.it@gmail.com>
*
* This source file is subject to the license that is bundled
* with this source code in the file LICENSE.
*/
namespace Go\ParserReflection;
use Go\ParserReflection\Traits\InternalPropertiesEmulationTrait;
use Go\ParserReflection\Traits\ReflectionClassLikeTrait;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\Stmt\ClassLike;
use PhpParser\Node\Stmt\Interface_;
use PhpParser\Node\Stmt\TraitUse;
use ReflectionClass as InternalReflectionClass;
/**
* AST-based reflection class
*/
class ReflectionClass extends InternalReflectionClass
{
use ReflectionClassLikeTrait, InternalPropertiesEmulationTrait;
/**
* Initializes reflection instance
*
* @param string|object $argument Class name or instance of object
* @param ClassLike $classLikeNode AST node for class
*/
public function __construct($argument, ClassLike $classLikeNode = null)
{
$fullClassName = is_object($argument) ? get_class($argument) : $argument;
$namespaceParts = explode('\\', $fullClassName);
$this->className = array_pop($namespaceParts);
// Let's unset original read-only property to have a control over it via __get
unset($this->name);
$this->namespaceName = join('\\', $namespaceParts);
$this->classLikeNode = $classLikeNode ?: ReflectionEngine::parseClass($fullClassName);
}
/**
* Parses interfaces from the concrete class node
*
* @param ClassLike $classLikeNode Class-like node
*
* @return array|\ReflectionClass[] List of reflections of interfaces
*/
public static function collectInterfacesFromClassNode(ClassLike $classLikeNode)
{
$interfaces = [];
$isInterface = $classLikeNode instanceof Interface_;
$interfaceField = $isInterface ? 'extends' : 'implements';
$hasInterfaces = in_array($interfaceField, $classLikeNode->getSubNodeNames());
$implementsList = $hasInterfaces ? $classLikeNode->$interfaceField : array();
if ($implementsList) {
foreach ($implementsList as $implementNode) {
if ($implementNode instanceof FullyQualified) {
$implementName = $implementNode->toString();
$interface = interface_exists($implementName, false)
? new parent($implementName)
: new static($implementName);
$interfaces[$implementName] = $interface;
}
}
}
return $interfaces;
}
/**
* Parses traits from the concrete class node
*
* @param ClassLike $classLikeNode Class-like node
* @param array $traitAdaptations List of method adaptations
*
* @return array|\ReflectionClass[] List of reflections of traits
*/
public static function collectTraitsFromClassNode(ClassLike $classLikeNode, array &$traitAdaptations)
{
$traits = [];
if (!empty($classLikeNode->stmts)) {
foreach ($classLikeNode->stmts as $classLevelNode) {
if ($classLevelNode instanceof TraitUse) {
foreach ($classLevelNode->traits as $classTraitName) {
if ($classTraitName instanceof FullyQualified) {
$traitName = $classTraitName->toString();
$trait = trait_exists($traitName, false)
? new parent($traitName)
: new static($traitName);
$traits[$traitName] = $trait;
}
}
$traitAdaptations = $classLevelNode->adaptations;
}
}
}
return $traits;
}
/**
* Emulating original behaviour of reflection
*/
public function ___debugInfo()
{
return array(
'name' => $this->getName()
);
}
/**
* Implementation of internal reflection initialization
*
* @return void
*/
protected function __initialize()
{
parent::__construct($this->getName());
}
}