@@ -97,21 +97,12 @@ protected function loadHandlers(): void
9797 }
9898 }
9999
100- /**
101- * @param string $code
102- * @param string $fileName
103- * @returns Script
104- */
105- public function parse ($ code , $ fileName )
100+ public function parse (string $ code , string $ fileName ): Script
106101 {
107102 return $ this ->parseAst ($ this ->astParser ->parse ($ code ), $ fileName );
108103 }
109104
110- /**
111- * @param array $ast PHP-Parser AST
112- * @param string $fileName
113- */
114- public function parseAst ($ ast , $ fileName ): Script
105+ protected function parseAst (array $ ast , string $ fileName ): Script
115106 {
116107 $ this ->fileName = $ fileName ;
117108 $ ast = $ this ->astTraverser ->traverse ($ ast );
@@ -213,49 +204,39 @@ public function parseNode(Node $node): void
213204 throw new RuntimeException ('Unknown Node Encountered : ' . $ type );
214205 }
215206
216- public function parseTypeList (array $ types ): array
207+ public function parseTypeList (? Node ... $ types ): array
217208 {
218- $ parsedTypes = [];
219- foreach ($ types as $ type ) {
220- $ parsedTypes [] = $ this ->parseTypeNode ($ type );
221- }
222-
223- return $ parsedTypes ;
209+ return array_map ([$ this , 'parseTypeNode ' ], $ types );
224210 }
225211
226212 public function parseTypeNode (?Node $ node ): Op \Type
227213 {
228214 if (is_null ($ node )) {
229215 return new Op \Type \Mixed_ ();
230216 }
231- if ($ node instanceof Node \Name) {
232- return new Op \Type \Literal (
233- $ node ->name ,
234- $ this ->mapAttributes ($ node ),
235- );
236- }
237- if ($ node instanceof Node \NullableType) {
238- return new Op \Type \Nullable (
239- $ this ->parseTypeNode ($ node ->type ),
240- $ this ->mapAttributes ($ node ),
241- );
242- }
243- if ($ node instanceof Node \UnionType) {
244- $ parsedTypes = [];
245- foreach ($ node ->types as $ type ) {
246- $ parsedTypes [] = $ this ->parseTypeNode ($ type );
247- }
248-
249- return new Op \Type \Union (
250- $ parsedTypes ,
251- $ this ->mapAttributes ($ node ),
252- );
253- }
254- if ($ node instanceof Node \Identifier) {
255- return new Op \Type \Literal (
256- $ node ->name ,
257- $ this ->mapAttributes ($ node ),
258- );
217+ switch ($ node ->getType ()) {
218+ case 'Name ' :
219+ case 'Name_FullyQualified ' :
220+ // This is safe since we always run name resolution ahead of time
221+ return new Op \Type \Literal (
222+ $ node ->name ,
223+ $ this ->mapAttributes ($ node ),
224+ );
225+ case 'NullableType ' :
226+ return new Op \Type \Nullable (
227+ $ this ->parseTypeNode ($ node ->type ),
228+ $ this ->mapAttributes ($ node ),
229+ );
230+ case 'UnionType ' :
231+ return new Op \Type \Union (
232+ $ this ->parseTypeList (...$ node ->types ),
233+ $ this ->mapAttributes ($ node ),
234+ );
235+ case 'Identifier ' :
236+ return new Op \Type \Literal (
237+ $ node ->name ,
238+ $ this ->mapAttributes ($ node ),
239+ );
259240 }
260241 throw new LogicException ("Unknown type node: " . $ node ->getType ());
261242 }
@@ -278,17 +259,16 @@ public function parseExprList(array $expr, $readWrite = self::MODE_NONE): array
278259 return $ vars ;
279260 }
280261
281- public function parseExprNode ($ expr )
262+ public function parseExprNode ($ expr ): ? Operand
282263 {
283264 if (null === $ expr ) {
284- return ;
265+ return null ;
285266 }
286267 if (is_scalar ($ expr )) {
287268 return new Literal ($ expr );
288269 }
289270 if (is_array ($ expr )) {
290271 $ list = $ this ->parseExprList ($ expr );
291-
292272 return end ($ list );
293273 }
294274 if ($ expr instanceof Node \Arg) {
@@ -297,28 +277,6 @@ public function parseExprNode($expr)
297277 if ($ expr instanceof Node \Identifier) {
298278 return new Literal ($ expr ->name );
299279 }
300- if ($ expr instanceof Expr \Variable) {
301- if (is_scalar ($ expr ->name )) {
302- if ($ expr ->name === 'this ' ) {
303- return new Operand \BoundVariable (
304- $ this ->parseExprNode ($ expr ->name ),
305- false ,
306- Operand \BoundVariable::SCOPE_OBJECT ,
307- $ this ->currentClass ,
308- );
309- }
310-
311- return new Variable ($ this ->parseExprNode ($ expr ->name ));
312- }
313-
314- // variable variable
315- $ this ->block ->children [] = $ op = new Op \Expr \VarVar (
316- $ this ->readVariable ($ this ->parseExprNode ($ expr ->name )),
317- $ this ->mapAttributes ($ expr )
318- );
319-
320- return $ op ->result ;
321- }
322280 if ($ expr instanceof Node \Name) {
323281 $ isReserved = in_array (strtolower ($ expr ->getLast ()), ['int ' , 'string ' , 'array ' , 'callable ' , 'float ' , 'bool ' ], true );
324282 if ($ isReserved ) {
@@ -328,15 +286,11 @@ public function parseExprNode($expr)
328286
329287 return new Literal ($ expr ->toString ());
330288 }
331- if ($ expr instanceof Node \Scalar) {
332- return $ this ->parseScalarNode ($ expr );
333- }
289+
334290 if ($ expr instanceof Node \InterpolatedStringPart) {
335291 return new Literal ($ expr ->value );
336292 }
337293
338- $ method = 'parse ' . $ expr ->getType ();
339-
340294 if (isset ($ this ->handlers [$ expr ->getType ()])) {
341295 return $ this ->handlers [$ expr ->getType ()]->handleExpr ($ expr );
342296 }
@@ -367,27 +321,7 @@ public function parseAttributeGroups(array $attrGroups)
367321 return array_map ([$ this , 'parseAttributeGroup ' ], $ attrGroups );
368322 }
369323
370- public function processAssertions (Operand $ op , Block $ if , Block $ else ): void
371- {
372- $ block = $ this ->block ;
373- foreach ($ op ->assertions as $ assert ) {
374- $ this ->block = $ if ;
375- array_unshift ($ this ->block ->children , new Op \Expr \Assertion (
376- $ this ->readVariable ($ assert ['var ' ]),
377- $ this ->writeVariable ($ assert ['var ' ]),
378- $ this ->readAssertion ($ assert ['assertion ' ]),
379- ));
380- $ this ->block = $ else ;
381- array_unshift ($ this ->block ->children , new Op \Expr \Assertion (
382- $ this ->readVariable ($ assert ['var ' ]),
383- $ this ->writeVariable ($ assert ['var ' ]),
384- new Assertion \NegatedAssertion ([$ this ->readAssertion ($ assert ['assertion ' ])]),
385- ));
386- }
387- $ this ->block = $ block ;
388- }
389-
390- protected function readAssertion (Assertion $ assert ): Assertion
324+ public function readAssertion (Assertion $ assert ): Assertion
391325 {
392326 if ($ assert ->value instanceof Operand) {
393327 return new $ assert ($ this ->readVariable ($ assert ->value ));
@@ -408,46 +342,6 @@ protected function throwUndefinedLabelError(): void
408342 }
409343
410344
411-
412-
413- private function parseScalarNode (Node \Scalar $ scalar ): Operand
414- {
415- switch ($ scalar ->getType ()) {
416- case 'Scalar_InterpolatedString ' :
417- case 'Scalar_Encapsed ' :
418- $ op = new Op \Expr \ConcatList ($ this ->parseExprList ($ scalar ->parts , self ::MODE_READ ), $ this ->mapAttributes ($ scalar ));
419- $ this ->block ->children [] = $ op ;
420-
421- return $ op ->result ;
422- case 'Scalar_Float ' :
423- case 'Scalar_Int ' :
424- case 'Scalar_LNumber ' :
425- case 'Scalar_String ' :
426- case 'Scalar_InterpolatedStringPart ' :
427- case 'Scalar_EncapsedStringPart ' :
428- return new Literal ($ scalar ->value );
429- case 'Scalar_MagicConst_Class ' :
430- // TODO
431- return new Literal ('__CLASS__ ' );
432- case 'Scalar_MagicConst_Dir ' :
433- return new Literal (dirname ($ this ->fileName ));
434- case 'Scalar_MagicConst_File ' :
435- return new Literal ($ this ->fileName );
436- case 'Scalar_MagicConst_Namespace ' :
437- // TODO
438- return new Literal ('__NAMESPACE__ ' );
439- case 'Scalar_MagicConst_Method ' :
440- // TODO
441- return new Literal ('__METHOD__ ' );
442- case 'Scalar_MagicConst_Function ' :
443- // TODO
444- return new Literal ('__FUNCTION__ ' );
445- default :
446- var_dump ($ scalar );
447- throw new RuntimeException ('Unknown how to deal with scalar type ' . $ scalar ->getType ());
448- }
449- }
450-
451345 public function parseParameterList (Func $ func , array $ params ): array
452346 {
453347 if (empty ($ params )) {
0 commit comments