1 | <?php |
||
26 | class ReflectionEngine |
||
27 | { |
||
28 | /** |
||
29 | * @var null|LocatorInterface |
||
30 | */ |
||
31 | protected static $locator = null; |
||
32 | |||
33 | /** |
||
34 | * @var array|Node[] |
||
35 | */ |
||
36 | protected static $parsedFiles = array(); |
||
37 | |||
38 | /** |
||
39 | * @var null|Parser |
||
40 | */ |
||
41 | protected static $parser = null; |
||
42 | |||
43 | /** |
||
44 | * @var null|NodeTraverser |
||
45 | */ |
||
46 | protected static $traverser = null; |
||
47 | |||
48 | private function __construct() {} |
||
49 | |||
50 | public static function init(LocatorInterface $locator) |
||
51 | { |
||
52 | self::$parser = new Parser(new Lexer(['usedAttributes' => [ |
||
53 | 'comments', 'startLine', 'endLine', 'startTokenPos', 'endTokenPos', 'startFilePos', 'endFilePos' |
||
54 | ]])); |
||
55 | |||
56 | self::$traverser = $traverser = new NodeTraverser(); |
||
57 | $traverser->addVisitor(new NameResolver()); |
||
58 | |||
59 | self::$locator = $locator; |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Locates a file name for class |
||
64 | * |
||
65 | * @param string $fullClassName Full name of the class |
||
66 | * |
||
67 | * @return string |
||
68 | */ |
||
69 | 15 | public static function locateClassFile($fullClassName) |
|
70 | { |
||
71 | 15 | if (class_exists($fullClassName, false) |
|
72 | 1 | || interface_exists($fullClassName, false) |
|
73 | 1 | || trait_exists($fullClassName, false) |
|
74 | 15 | ) { |
|
75 | 15 | $refClass = new \ReflectionClass($fullClassName); |
|
76 | 15 | $classFileName = $refClass->getFileName(); |
|
77 | 15 | } else { |
|
78 | $classFileName = self::$locator->locateClass($fullClassName); |
||
79 | } |
||
80 | |||
81 | 15 | if (!$classFileName) { |
|
82 | throw new \InvalidArgumentException("Class $fullClassName was not found by locator"); |
||
83 | } |
||
84 | |||
85 | 15 | return $classFileName; |
|
86 | } |
||
87 | |||
88 | /** |
||
89 | * Tries to parse a class by name using LocatorInterface |
||
90 | * |
||
91 | * @param string $fullClassName Class name to load |
||
92 | * |
||
93 | * @return ClassLike |
||
94 | */ |
||
95 | 15 | public static function parseClass($fullClassName) |
|
119 | |||
120 | /** |
||
121 | * Parses class method |
||
122 | * |
||
123 | * @param string $fullClassName Name of the class |
||
124 | * @param string $methodName Name of the method |
||
125 | * |
||
126 | * @return ClassMethod |
||
127 | */ |
||
128 | 1 | public static function parseClassMethod($fullClassName, $methodName) |
|
129 | { |
||
130 | 1 | $class = self::parseClass($fullClassName); |
|
131 | 1 | $classNodes = $class->stmts; |
|
132 | |||
133 | 1 | foreach ($classNodes as $classLevelNode) { |
|
134 | 1 | if ($classLevelNode instanceof ClassMethod && $classLevelNode->name == $methodName) { |
|
135 | 1 | return $classLevelNode; |
|
136 | } |
||
137 | 1 | } |
|
138 | |||
139 | throw new \InvalidArgumentException("Method $methodName was not found in the $fullClassName"); |
||
140 | } |
||
141 | |||
142 | /** |
||
143 | * Parses class property |
||
144 | * |
||
145 | * @param string $fullClassName Name of the class |
||
146 | * @param string $propertyName Name of the property |
||
147 | * |
||
148 | * @return array Pair of [Property and PropertyProperty] nodes |
||
149 | */ |
||
150 | 2 | public static function parseClassProperty($fullClassName, $propertyName) |
|
167 | |||
168 | /** |
||
169 | * Parses a file and returns an AST for it |
||
170 | * |
||
171 | * @param string $fileName Name of the file |
||
172 | * |
||
173 | * @return Node[] |
||
174 | */ |
||
175 | 132 | public static function parseFile($fileName) |
|
189 | |||
190 | /** |
||
191 | * Parses a file namespace and returns an AST for it |
||
192 | * |
||
193 | * @param string $fileName Name of the file |
||
194 | * @param string $namespaceName Namespace name |
||
195 | * |
||
196 | * @return Namespace_ |
||
197 | */ |
||
198 | 22 | public static function parseFileNamespace($fileName, $namespaceName) |
|
210 | |||
211 | } |
||
212 |