@@ -1691,6 +1691,19 @@ static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int
16911691 }
16921692 zend_ast_export_ex (str , ast , priority , indent );
16931693}
1694+ static ZEND_COLD void zend_ast_export_ns_name_or_expression (smart_str * str , zend_ast * ast , int priority , int indent )
1695+ {
1696+ switch (ast -> kind ) {
1697+ case ZEND_AST_ZVAL :
1698+ case ZEND_AST_VAR :
1699+ zend_ast_export_ns_name (str , ast , priority , indent );
1700+ break ;
1701+ default :
1702+ smart_str_appendc (str , '(' );
1703+ zend_ast_export_ex (str , ast , priority , indent );
1704+ smart_str_appendc (str , ')' );
1705+ }
1706+ }
16941707
16951708static ZEND_COLD bool zend_ast_valid_var_name (const char * s , size_t len )
16961709{
@@ -2529,25 +2542,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25292542 zend_ast_export_var (str , ast -> child [1 ], indent );
25302543 break ;
25312544 case ZEND_AST_STATIC_PROP :
2532- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2545+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25332546 smart_str_appends (str , "::$" );
25342547 zend_ast_export_var (str , ast -> child [1 ], indent );
25352548 break ;
25362549 case ZEND_AST_CALL : {
2537- zend_ast * left = ast -> child [0 ];
2538- switch (left -> kind ) {
2539- /* ZEND_AST_ZVAL is a regular function call. */
2540- case ZEND_AST_ZVAL :
2541- /* ZEND_AST_VAR ($foo()) is unambiguous without parens. */
2542- case ZEND_AST_VAR :
2543- zend_ast_export_ns_name (str , left , 0 , indent );
2544- break ;
2545- default :
2546- smart_str_appendc (str , '(' );
2547- zend_ast_export_ex (str , left , 0 , indent );
2548- smart_str_appendc (str , ')' );
2549- break ;
2550- }
2550+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25512551 smart_str_appendc (str , '(' );
25522552 zend_ast_export_ex (str , ast -> child [1 ], 0 , indent );
25532553 smart_str_appendc (str , ')' );
@@ -2559,7 +2559,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25592559 goto simple_list ;
25602560 }
25612561 case ZEND_AST_CLASS_CONST :
2562- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2562+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25632563 smart_str_appends (str , "::" );
25642564 zend_ast_export_name (str , ast -> child [1 ], 0 , indent );
25652565 break ;
@@ -2576,7 +2576,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25762576 default : ZEND_UNREACHABLE ();
25772577 }
25782578 } else {
2579- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2579+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25802580 }
25812581 smart_str_appends (str , "::class" );
25822582 break ;
@@ -2655,7 +2655,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
26552655 }
26562656 zend_ast_export_class_no_header (str , decl , indent );
26572657 } else {
2658- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2658+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
26592659 smart_str_appendc (str , '(' );
26602660 zend_ast_export_ex (str , ast -> child [1 ], 0 , indent );
26612661 smart_str_appendc (str , ')' );
@@ -2664,7 +2664,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
26642664 case ZEND_AST_INSTANCEOF :
26652665 zend_ast_export_ex (str , ast -> child [0 ], 0 , indent );
26662666 smart_str_appends (str , " instanceof " );
2667- zend_ast_export_ns_name (str , ast -> child [1 ], 0 , indent );
2667+ zend_ast_export_ns_name_or_expression (str , ast -> child [1 ], 0 , indent );
26682668 break ;
26692669 case ZEND_AST_YIELD :
26702670 if (priority > 70 ) smart_str_appendc (str , '(' );
@@ -2857,7 +2857,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
28572857 smart_str_appendc (str , ')' );
28582858 break ;
28592859 case ZEND_AST_STATIC_CALL :
2860- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2860+ if (zend_ast_is_parent_hook_call (ast )) {
2861+ zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2862+ } else {
2863+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
2864+ }
2865+
28612866 smart_str_appends (str , "::" );
28622867 zend_ast_export_var (str , ast -> child [1 ], indent );
28632868 smart_str_appendc (str , '(' );
@@ -3088,3 +3093,22 @@ zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast)
30883093 ZEND_UNREACHABLE ();
30893094 return NULL ;
30903095}
3096+
3097+ bool zend_ast_is_parent_hook_call (const zend_ast * ast )
3098+ {
3099+ ZEND_ASSERT (ast -> kind == ZEND_AST_STATIC_CALL );
3100+
3101+ const zend_ast * class_ast = ast -> child [0 ];
3102+ zend_ast * method_ast = ast -> child [1 ];
3103+
3104+ return class_ast -> kind == ZEND_AST_STATIC_PROP
3105+ && !(class_ast -> attr & ZEND_PARENTHESIZED_STATIC_PROP )
3106+ && class_ast -> child [0 ]-> kind == ZEND_AST_ZVAL
3107+ && Z_TYPE_P (zend_ast_get_zval (class_ast -> child [0 ])) == IS_STRING
3108+ && zend_get_class_fetch_type (zend_ast_get_str (class_ast -> child [0 ])) == ZEND_FETCH_CLASS_PARENT
3109+ && class_ast -> child [1 ]-> kind == ZEND_AST_ZVAL
3110+ && method_ast -> kind == ZEND_AST_ZVAL
3111+ && Z_TYPE_P (zend_ast_get_zval (method_ast )) == IS_STRING
3112+ && (zend_string_equals_literal_ci (zend_ast_get_str (method_ast ), "get" )
3113+ || zend_string_equals_literal_ci (zend_ast_get_str (method_ast ), "set" ));
3114+ }
0 commit comments