@@ -1686,6 +1686,19 @@ static ZEND_COLD void zend_ast_export_ns_name(smart_str *str, zend_ast *ast, int
16861686 }
16871687 zend_ast_export_ex (str , ast , priority , indent );
16881688}
1689+ static ZEND_COLD void zend_ast_export_ns_name_or_expression (smart_str * str , zend_ast * ast , int priority , int indent )
1690+ {
1691+ switch (ast -> kind ) {
1692+ case ZEND_AST_ZVAL :
1693+ case ZEND_AST_VAR :
1694+ zend_ast_export_ns_name (str , ast , priority , indent );
1695+ break ;
1696+ default :
1697+ smart_str_appendc (str , '(' );
1698+ zend_ast_export_ex (str , ast , priority , indent );
1699+ smart_str_appendc (str , ')' );
1700+ }
1701+ }
16891702
16901703static ZEND_COLD bool zend_ast_valid_var_name (const char * s , size_t len )
16911704{
@@ -2523,25 +2536,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25232536 zend_ast_export_var (str , ast -> child [1 ], indent );
25242537 break ;
25252538 case ZEND_AST_STATIC_PROP :
2526- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2539+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25272540 smart_str_appends (str , "::$" );
25282541 zend_ast_export_var (str , ast -> child [1 ], indent );
25292542 break ;
25302543 case ZEND_AST_CALL : {
2531- zend_ast * left = ast -> child [0 ];
2532- switch (left -> kind ) {
2533- /* ZEND_AST_ZVAL is a regular function call. */
2534- case ZEND_AST_ZVAL :
2535- /* ZEND_AST_VAR ($foo()) is unambiguous without parens. */
2536- case ZEND_AST_VAR :
2537- zend_ast_export_ns_name (str , left , 0 , indent );
2538- break ;
2539- default :
2540- smart_str_appendc (str , '(' );
2541- zend_ast_export_ex (str , left , 0 , indent );
2542- smart_str_appendc (str , ')' );
2543- break ;
2544- }
2544+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25452545 smart_str_appendc (str , '(' );
25462546 zend_ast_export_ex (str , ast -> child [1 ], 0 , indent );
25472547 smart_str_appendc (str , ')' );
@@ -2553,7 +2553,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25532553 goto simple_list ;
25542554 }
25552555 case ZEND_AST_CLASS_CONST :
2556- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2556+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25572557 smart_str_appends (str , "::" );
25582558 zend_ast_export_name (str , ast -> child [1 ], 0 , indent );
25592559 break ;
@@ -2570,7 +2570,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
25702570 default : ZEND_UNREACHABLE ();
25712571 }
25722572 } else {
2573- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2573+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
25742574 }
25752575 smart_str_appends (str , "::class" );
25762576 break ;
@@ -2649,7 +2649,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
26492649 }
26502650 zend_ast_export_class_no_header (str , decl , indent );
26512651 } else {
2652- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2652+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
26532653 smart_str_appendc (str , '(' );
26542654 zend_ast_export_ex (str , ast -> child [1 ], 0 , indent );
26552655 smart_str_appendc (str , ')' );
@@ -2658,7 +2658,7 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
26582658 case ZEND_AST_INSTANCEOF :
26592659 zend_ast_export_ex (str , ast -> child [0 ], 0 , indent );
26602660 smart_str_appends (str , " instanceof " );
2661- zend_ast_export_ns_name (str , ast -> child [1 ], 0 , indent );
2661+ zend_ast_export_ns_name_or_expression (str , ast -> child [1 ], 0 , indent );
26622662 break ;
26632663 case ZEND_AST_YIELD :
26642664 if (priority > 70 ) smart_str_appendc (str , '(' );
@@ -2851,7 +2851,12 @@ static ZEND_COLD void zend_ast_export_ex(smart_str *str, zend_ast *ast, int prio
28512851 smart_str_appendc (str , ')' );
28522852 break ;
28532853 case ZEND_AST_STATIC_CALL :
2854- zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2854+ if (zend_ast_is_parent_hook_call (ast )) {
2855+ zend_ast_export_ns_name (str , ast -> child [0 ], 0 , indent );
2856+ } else {
2857+ zend_ast_export_ns_name_or_expression (str , ast -> child [0 ], 0 , indent );
2858+ }
2859+
28552860 smart_str_appends (str , "::" );
28562861 zend_ast_export_var (str , ast -> child [1 ], indent );
28572862 smart_str_appendc (str , '(' );
@@ -3082,3 +3087,22 @@ zend_ast * ZEND_FASTCALL zend_ast_call_get_args(zend_ast *ast)
30823087 ZEND_UNREACHABLE ();
30833088 return NULL ;
30843089}
3090+
3091+ bool zend_ast_is_parent_hook_call (const zend_ast * ast )
3092+ {
3093+ ZEND_ASSERT (ast -> kind == ZEND_AST_STATIC_CALL );
3094+
3095+ const zend_ast * class_ast = ast -> child [0 ];
3096+ zend_ast * method_ast = ast -> child [1 ];
3097+
3098+ return class_ast -> kind == ZEND_AST_STATIC_PROP
3099+ && !(class_ast -> attr & ZEND_PARENTHESIZED_STATIC_PROP )
3100+ && class_ast -> child [0 ]-> kind == ZEND_AST_ZVAL
3101+ && Z_TYPE_P (zend_ast_get_zval (class_ast -> child [0 ])) == IS_STRING
3102+ && zend_get_class_fetch_type (zend_ast_get_str (class_ast -> child [0 ])) == ZEND_FETCH_CLASS_PARENT
3103+ && class_ast -> child [1 ]-> kind == ZEND_AST_ZVAL
3104+ && method_ast -> kind == ZEND_AST_ZVAL
3105+ && Z_TYPE_P (zend_ast_get_zval (method_ast )) == IS_STRING
3106+ && (zend_string_equals_literal_ci (zend_ast_get_str (method_ast ), "get" )
3107+ || zend_string_equals_literal_ci (zend_ast_get_str (method_ast ), "set" ));
3108+ }
0 commit comments