@@ -87,13 +87,45 @@ private static function _phpparser_stmtlist_to_ast_node(array $parserNodes, ?int
8787 return $ stmts ;
8888 }
8989
90+ /**
91+ * @param PHPParser\Node[] $exprs
92+ */
93+ private static function _phpparser_expr_list_to_expr_list (array $ exprs , int $ lineno ) : \ast \Node {
94+ $ children = [];
95+ foreach ($ exprs as $ expr ) {
96+ $ childNode = self ::_phpparser_node_to_ast_node ($ expr );
97+ if (is_array ($ childNode )) {
98+ // Echo_ returns multiple children.
99+ foreach ($ childNode as $ childNodePart ) {
100+ $ children [] = $ childNodePart ;
101+ }
102+ } else if (!is_null ($ childNode )) {
103+ $ children [] = $ childNode ;
104+ }
105+ }
106+ foreach ($ exprs as $ parserNode ) {
107+ $ childNodeLine = sl ($ parserNode );
108+ if ($ childNodeLine > 0 ) {
109+ $ lineno = $ childNodeLine ;
110+ break ;
111+ }
112+ }
113+ return astnode (
114+ \ast \AST_EXPR_LIST ,
115+ 0 ,
116+ $ children ,
117+ $ lineno
118+ );
119+ }
120+
90121 /**
91122 * @param PhpParser\Node $n - The node from PHP-Parser
92123 * @return \ast\Node|\ast\Node[]|string|int|float|bool|null - whatever \ast\parse_code would return as the equivalent.
93124 * @suppress PhanUndeclaredProperty
94125 */
95126 private static final function _phpparser_node_to_ast_node ($ n ) {
96127 if (!($ n instanceof PhpParser \Node)) {
128+ debug_print_backtrace (DEBUG_BACKTRACE_IGNORE_ARGS );
97129 throw new \InvalidArgumentException ("Invalid type for node: " . (is_object ($ n ) ? get_class ($ n ) : gettype ($ n )));
98130 }
99131
@@ -137,7 +169,16 @@ private static function _init_handle_map() : array {
137169 return self ::_ast_node_assign (
138170 self ::_phpparser_node_to_ast_node ($ n ->var ),
139171 self ::_phpparser_node_to_ast_node ($ n ->expr ),
140- $ startLine
172+ $ startLine ,
173+ false
174+ );
175+ },
176+ 'PhpParser\Node\Expr\AssignRef ' => function (PhpParser \Node \Expr \AssignRef $ n , int $ startLine ) : ?\ast \Node {
177+ return self ::_ast_node_assign (
178+ self ::_phpparser_node_to_ast_node ($ n ->var ),
179+ self ::_phpparser_node_to_ast_node ($ n ->expr ),
180+ $ startLine ,
181+ true
141182 );
142183 },
143184 'PhpParser\Node\Expr\AssignOp\BitwiseAnd ' => function (PhpParser \Node \Expr \AssignOp \BitwiseAnd $ n , int $ startLine ) : \ast \Node {
@@ -303,12 +344,18 @@ private static function _init_handle_map() : array {
303344 'PhpParser\Node\Expr\ClassConstFetch ' => function (PhpParser \Node \Expr \ClassConstFetch $ n , int $ startLine ) : ?\ast \Node {
304345 return self ::_phpparser_classconstfetch_to_ast_classconstfetch ($ n , $ startLine );
305346 },
347+ 'PhpParser\Node\Expr\Clone_ ' => function (PhpParser \Node \Expr \Clone_ $ n , int $ startLine ) : \ast \Node {
348+ return astnode (\ast \AST_CLONE , 0 , ['expr ' => self ::_phpparser_node_to_ast_node ($ n ->expr )], $ startLine );
349+ },
306350 'PhpParser\Node\Expr\ConstFetch ' => function (PhpParser \Node \Expr \ConstFetch $ n , int $ startLine ) : \ast \Node {
307351 return astnode (\ast \AST_CONST , 0 , ['name ' => self ::_phpparser_node_to_ast_node ($ n ->name )], $ startLine );
308352 },
309353 'PhpParser\Node\Expr\ErrorSuppress ' => function (PhpParser \Node \Expr \ErrorSuppress $ n , int $ startLine ) : \ast \Node {
310354 return self ::_ast_node_unary_op (\ast \flags \UNARY_SILENCE , self ::_phpparser_node_to_ast_node ($ n ->expr ), $ startLine );
311355 },
356+ 'PhpParser\Node\Expr\Empty_ ' => function (PhpParser \Node \Expr \Empty_ $ n , int $ startLine ) : \ast \Node {
357+ return astnode (\ast \AST_EMPTY , 0 , ['expr ' => self ::_phpparser_node_to_ast_node ($ n ->expr )], $ startLine );
358+ },
312359 'PhpParser\Node\Expr\Eval_ ' => function (PhpParser \Node \Expr \Eval_ $ n , int $ startLine ) : \ast \Node {
313360 return self ::_ast_node_eval (
314361 self ::_phpparser_node_to_ast_node ($ n ->expr ),
@@ -382,6 +429,18 @@ private static function _init_handle_map() : array {
382429 'args ' => self ::_phpparser_arg_list_to_ast_arg_list ($ n ->args , $ startLine ),
383430 ], $ startLine );
384431 },
432+ 'PhpParser\Node\Expr\PreInc ' => function (PhpParser \Node \Expr \PreInc $ n , int $ startLine ) : \ast \Node {
433+ return astnode (\ast \AST_PRE_INC , 0 , ['var ' => self ::_phpparser_node_to_ast_node ($ n ->var )], $ startLine );
434+ },
435+ 'PhpParser\Node\Expr\PreDec ' => function (PhpParser \Node \Expr \PreDec $ n , int $ startLine ) : \ast \Node {
436+ return astnode (\ast \AST_PRE_DEC , 0 , ['var ' => self ::_phpparser_node_to_ast_node ($ n ->var )], $ startLine );
437+ },
438+ 'PhpParser\Node\Expr\PostInc ' => function (PhpParser \Node \Expr \PostInc $ n , int $ startLine ) : \ast \Node {
439+ return astnode (\ast \AST_POST_INC , 0 , ['var ' => self ::_phpparser_node_to_ast_node ($ n ->var )], $ startLine );
440+ },
441+ 'PhpParser\Node\Expr\PostDec ' => function (PhpParser \Node \Expr \PostDec $ n , int $ startLine ) : \ast \Node {
442+ return astnode (\ast \AST_POST_DEC , 0 , ['var ' => self ::_phpparser_node_to_ast_node ($ n ->var )], $ startLine );
443+ },
385444 'PhpParser\Node\Expr\Print_ ' => function (PhpParser \Node \Expr \Print_ $ n , int $ startLine ) : \ast \Node {
386445 return astnode (
387446 \ast \AST_PRINT ,
@@ -433,6 +492,17 @@ private static function _init_handle_map() : array {
433492 'PhpParser\Node\Expr\Variable ' => function (PhpParser \Node \Expr \Variable $ n , int $ startLine ) : ?\ast \Node {
434493 return self ::_ast_node_variable ($ n ->name , $ startLine );
435494 },
495+ 'PhpParser\Node\Expr\Yield_ ' => function (PhpParser \Node \Expr \Yield_ $ n , int $ startLine ) : ?\ast \Node {
496+ return astnode (
497+ \ast \AST_YIELD ,
498+ 0 ,
499+ [
500+ 'value ' => $ n ->value !== null ? self ::_phpparser_node_to_ast_node ($ n ->value ) : null ,
501+ 'key ' => $ n ->key !== null ? self ::_phpparser_node_to_ast_node ($ n ->key ) : null ,
502+ ],
503+ $ startLine
504+ );
505+ },
436506 'PhpParser\Node\Name ' => function (PhpParser \Node \Name $ n , int $ startLine ) : \ast \Node {
437507 return self ::_ast_node_name (
438508 self ::_phpparser_name_to_string ($ n ),
@@ -477,6 +547,9 @@ private static function _init_handle_map() : array {
477547 'PhpParser\Node\Scalar\EncapsedStringPart ' => function (PhpParser \Node \Scalar \EncapsedStringPart $ n , int $ startLine ) : string {
478548 return $ n ->value ;
479549 },
550+ 'PhpParser\Node\Scalar\DNumber ' => function (PhpParser \Node \Scalar \DNumber $ n , int $ startLine ) : float {
551+ return (float )$ n ->value ;
552+ },
480553 'PhpParser\Node\Scalar\LNumber ' => function (PhpParser \Node \Scalar \LNumber $ n , int $ startLine ) : int {
481554 return (int )$ n ->value ;
482555 },
@@ -563,6 +636,13 @@ private static function _init_handle_map() : array {
563636 $ startLine
564637 );
565638 },
639+ 'PhpParser\Node\Stmt\Do_ ' => function (PhpParser \Node \Stmt \Do_ $ n , int $ startLine ) : \ast \Node {
640+ return self ::_ast_node_do_while (
641+ self ::_phpparser_node_to_ast_node ($ n ->cond ),
642+ self ::_phpparser_stmtlist_to_ast_node ($ n ->stmts , $ startLine ),
643+ $ startLine
644+ );
645+ },
566646 /**
567647 * @return \ast\Node|\ast\Node[]
568648 */
@@ -647,18 +727,27 @@ private static function _init_handle_map() : array {
647727 self ::_extract_phpdoc_comment ($ n ->getAttribute ('comments ' ))
648728 );
649729 },
650- /**
651- * @suppress PhanDeprecatedProperty TODO: figure out alternative
652- */
730+ 'PhpParser\Node\Stmt\For_ ' => function (PhpParser \Node \Stmt \For_ $ n , int $ startLine ) : \ast \Node {
731+ return astnode (
732+ \ast \AST_FOR ,
733+ 0 ,
734+ [
735+ 'init ' => \count ($ n ->init ) > 0 ? self ::_phpparser_expr_list_to_expr_list ($ n ->init , $ startLine ) : null ,
736+ 'cond ' => \count ($ n ->cond ) > 0 ? self ::_phpparser_expr_list_to_expr_list ($ n ->cond , $ startLine ) : null ,
737+ 'loop ' => \count ($ n ->loop ) > 0 ? self ::_phpparser_expr_list_to_expr_list ($ n ->loop , $ startLine ) : null ,
738+ 'stmts ' => self ::_phpparser_stmtlist_to_ast_node ($ n ->stmts ?? [], $ startLine ),
739+ ],
740+ $ startLine
741+ );
742+ },
653743 'PhpParser\Node\Stmt\GroupUse ' => function (PhpParser \Node \Stmt \GroupUse $ n , int $ startLine ) : \ast \Node {
654744 return self ::_ast_stmt_group_use (
655745 $ n ->type ,
656- implode ( '\\' , $ n ->prefix -> parts ?? [] ),
746+ self :: _phpparser_name_to_string ( $ n ->prefix ),
657747 self ::_phpparser_use_list_to_ast_use_list ($ n ->uses ),
658748 $ startLine
659749 );
660750 },
661- /** @suppress PhanDeprecatedProperty */
662751 'PhpParser\Node\Stmt\Namespace_ ' => function (PhpParser \Node \Stmt \Namespace_ $ n , int $ startLine ) : \ast \Node {
663752 $ nodeDumper = new \PhpParser \NodeDumper ([
664753 'dumpComments ' => true ,
@@ -668,7 +757,7 @@ private static function _init_handle_map() : array {
668757 \ast \AST_NAMESPACE ,
669758 0 ,
670759 [
671- 'name ' => implode ( '\\' , $ n ->name -> parts ?? [] ),
760+ 'name ' => self :: _phpparser_name_to_string ( $ n ->name ),
672761 'stmts ' => isset ($ n ->stmts ) ? self ::_phpparser_stmtlist_to_ast_node ($ n ->stmts , $ startLine ) : null ,
673762 ],
674763 $ startLine
@@ -682,7 +771,7 @@ private static function _init_handle_map() : array {
682771 return self ::_phpparser_property_to_ast_node ($ n , $ startLine );
683772 },
684773 'PhpParser\Node\Stmt\Return_ ' => function (PhpParser \Node \Stmt \Return_ $ n , int $ startLine ) : \ast \Node {
685- return self ::_ast_stmt_return (self ::_phpparser_node_to_ast_node ($ n ->expr ), $ startLine );
774+ return self ::_ast_stmt_return ($ n -> expr !== null ? self ::_phpparser_node_to_ast_node ($ n ->expr ) : null , $ startLine );
686775 },
687776 /** @return \ast\Node|\ast\Node[] */
688777 'PhpParser\Node\Stmt\Static_ ' => function (PhpParser \Node \Stmt \Static_ $ n , int $ startLine ) {
@@ -760,6 +849,14 @@ private static function _init_handle_map() : array {
760849 $ startLine
761850 );
762851 },
852+ /** @return \ast\Node|\ast\Node[] */
853+ 'PhpParser\Node\Stmt\Unset_ ' => function (PhpParser \Node \Stmt \Unset_ $ n , int $ startLine ) {
854+ $ stmts = [];
855+ foreach ($ n ->vars as $ var ) {
856+ $ stmts [] = astnode (\ast \AST_UNSET , 0 , ['var ' => self ::_phpparser_node_to_ast_node ($ var )], sl ($ var ) ?: $ startLine );
857+ }
858+ return \count ($ stmts ) === 1 ? $ stmts [0 ] : $ stmts ;
859+ },
763860 'PhpParser\Node\Stmt\Use_ ' => function (PhpParser \Node \Stmt \Use_ $ n , int $ startLine ) : \ast \Node {
764861 return self ::_ast_stmt_use (
765862 $ n ->type ,
@@ -839,18 +936,30 @@ private static function _phpparser_name_list_to_ast_name_list(array $types, int
839936 }
840937
841938 private static function _ast_node_while ($ cond , $ stmts , int $ startLine ) : \ast \Node {
842- $ node = new \ast \Node ();
843- $ node ->kind = \ast \AST_WHILE ;
844- $ node ->lineno = $ startLine ;
845- $ node ->flags = 0 ;
846- $ node ->children = [
847- 'cond ' => $ cond ,
848- 'stmts ' => $ stmts ,
849- ];
850- return $ node ;
939+ return astnode (
940+ \ast \AST_WHILE ,
941+ 0 ,
942+ [
943+ 'cond ' => $ cond ,
944+ 'stmts ' => $ stmts ,
945+ ],
946+ $ startLine
947+ );
948+ }
949+
950+ private static function _ast_node_do_while ($ cond , $ stmts , int $ startLine ) : \ast \Node {
951+ return astnode (
952+ \ast \AST_DO_WHILE ,
953+ 0 ,
954+ [
955+ 'stmts ' => $ stmts ,
956+ 'cond ' => $ cond ,
957+ ],
958+ $ startLine
959+ );
851960 }
852961
853- private static function _ast_node_assign ($ var , $ expr , int $ line ) : ?\ast \Node {
962+ private static function _ast_node_assign ($ var , $ expr , int $ line, bool $ ref ) : ?\ast \Node {
854963 if ($ expr === null ) {
855964 if (self ::$ should_add_placeholders ) {
856965 $ expr = '__INCOMPLETE_EXPR__ ' ;
@@ -859,7 +968,7 @@ private static function _ast_node_assign($var, $expr, int $line) : ?\ast\Node {
859968 }
860969 }
861970 $ node = new \ast \Node ();
862- $ node ->kind = \ast \AST_ASSIGN ;
971+ $ node ->kind = $ ref ? \ ast \ AST_ASSIGN_REF : \ast \AST_ASSIGN ;
863972 $ node ->flags = 0 ;
864973 $ node ->children = [
865974 'var ' => $ var ,
@@ -954,10 +1063,10 @@ private static function _phpparser_type_to_ast_node($type, int $line) {
9541063 * @param bool $byRef
9551064 * @param ?\ast\Node $type
9561065 */
957- private static function _ast_node_param (bool $ byRef , $ variadic , $ type , $ name , $ default , int $ line ) : \ast \Node {
1066+ private static function _ast_node_param (bool $ byRef , bool $ variadic , $ type , $ name , $ default , int $ line ) : \ast \Node {
9581067 $ node = new \ast \Node ;
9591068 $ node ->kind = \ast \AST_PARAM ;
960- $ node ->flags = $ byRef ? \ast \flags \PARAM_REF : 0 ;
1069+ $ node ->flags = ( $ byRef ? \ast \flags \PARAM_REF : 0 ) | ( $ variadic ? \ ast \ flags \ PARAM_VARIADIC : 0 ) ;
9611070 $ node ->lineno = $ line ;
9621071 $ node ->children = [
9631072 'type ' => $ type ,
0 commit comments