From 61523ab39605b52689ffa2f6d37081b7f6e52514 Mon Sep 17 00:00:00 2001 From: i582 Date: Thu, 4 Feb 2021 07:12:56 +0300 Subject: [PATCH 1/2] internal: fixed parsing of expression new 1. Now, for the expression 'new A' the correct values EndLine, EndPos, and not -1 will be set; 2. Also, for expressions from php5 '$a = &new Foo', the condition for parsing is fixed when it is necessary to set the Args values and the initialization of the NewTkn field is added, in the case when this condition is false. ## Problem description The reason why the positions after parsing became incorrect is that the check that is responsible for separating expressions like 'new A' and 'new A (args)' relied on comparison with nil, however, when the parser was updated, 'ctor_arguments' began to return not nil, but &ArgumentList{}, so the condition was always true, and in this case, when calculating the position, the second argument of the 'NewTokenNodePosition' function was nil, which is why -1 was returned there. For the second, the reasons are similar. In addition, there was a mistake in the number that needs to be checked. In the expression: 'variable' '=' '&' T_NEW class_name_reference ctor_arguments' it is necessary to check not 3, but 6 elements for nil. --- internal/php5/parser_test.go | 12 ++++++------ internal/php5/php5.go | 5 +++-- internal/php5/php5.y | 5 +++-- internal/php7/parser_test.go | 12 ++++++------ internal/php7/php7.go | 2 +- internal/php7/php7.y | 2 +- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/internal/php5/parser_test.go b/internal/php5/parser_test.go index a8a9bd5..bceac81 100644 --- a/internal/php5/parser_test.go +++ b/internal/php5/parser_test.go @@ -38822,9 +38822,9 @@ func TestExprNew(t *testing.T) { Expr: &ast.ExprNew{ Position: &position.Position{ StartLine: 1, - EndLine: -1, + EndLine: 1, StartPos: 3, - EndPos: -1, + EndPos: 10, }, NewTkn: &token.Token{ ID: token.T_NEW, @@ -43954,9 +43954,9 @@ func TestExprAssign(t *testing.T) { Expr: &ast.ExprAssignReference{ Position: &position.Position{ StartLine: 4, - EndLine: -1, + EndLine: 4, StartPos: 28, - EndPos: -1, + EndPos: 41, }, Var: &ast.ExprVariable{ Position: &position.Position{ @@ -44032,9 +44032,9 @@ func TestExprAssign(t *testing.T) { Expr: &ast.ExprNew{ Position: &position.Position{ StartLine: 4, - EndLine: -1, + EndLine: 4, StartPos: 34, - EndPos: -1, + EndPos: 41, }, NewTkn: &token.Token{ ID: token.T_NEW, diff --git a/internal/php5/php5.go b/internal/php5/php5.go index b213c53..4c564f9 100644 --- a/internal/php5/php5.go +++ b/internal/php5/php5.go @@ -4981,6 +4981,7 @@ yydefault: } else { yyVAL.node = &ast.ExprNew{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), + NewTkn: yyDollar[1].token, Class: yyDollar[2].node, } } @@ -5031,7 +5032,7 @@ yydefault: // line internal/php5/php5.y:2797 { var _new *ast.ExprNew - if yyDollar[3].token != nil { + if yyDollar[6].token != nil { _new = &ast.ExprNew{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[4].token, yyDollar[6].node), NewTkn: yyDollar[4].token, @@ -6401,7 +6402,7 @@ yydefault: yyDollar = yyS[yypt-0 : yypt+1] // line internal/php5/php5.y:3986 { - yyVAL.node = &ArgumentList{} + yyVAL.node = nil } case 352: yyDollar = yyS[yypt-1 : yypt+1] diff --git a/internal/php5/php5.y b/internal/php5/php5.y index 41ef5e4..782337f 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -2751,6 +2751,7 @@ new_expr: } else { $$ = &ast.ExprNew{ Position: yylex.(*Parser).builder.NewTokenNodePosition($1, $2), + NewTkn: $1, Class: $2, } } @@ -2796,7 +2797,7 @@ expr_without_variable: | variable '=' '&' T_NEW class_name_reference ctor_arguments { var _new *ast.ExprNew - if $3 != nil { + if $6 != nil { _new = &ast.ExprNew{ Position: yylex.(*Parser).builder.NewTokenNodePosition($4, $6), NewTkn: $4, @@ -3984,7 +3985,7 @@ backticks_expr: ctor_arguments: /* empty */ { - $$ = &ArgumentList{} + $$ = nil } | function_call_parameter_list { diff --git a/internal/php7/parser_test.go b/internal/php7/parser_test.go index 3df90af..6d09d67 100644 --- a/internal/php7/parser_test.go +++ b/internal/php7/parser_test.go @@ -43581,9 +43581,9 @@ func TestExprNew(t *testing.T) { Expr: &ast.ExprNew{ Position: &position.Position{ StartLine: 1, - EndLine: -1, + EndLine: 1, StartPos: 3, - EndPos: -1, + EndPos: 10, }, NewTkn: &token.Token{ ID: token.T_NEW, @@ -49806,9 +49806,9 @@ func TestExprAssign_Assign(t *testing.T) { Expr: &ast.ExprAssignReference{ Position: &position.Position{ StartLine: 4, - EndLine: -1, + EndLine: 4, StartPos: 28, - EndPos: -1, + EndPos: 41, }, Var: &ast.ExprVariable{ Position: &position.Position{ @@ -49884,9 +49884,9 @@ func TestExprAssign_Assign(t *testing.T) { Expr: &ast.ExprNew{ Position: &position.Position{ StartLine: 4, - EndLine: -1, + EndLine: 4, StartPos: 34, - EndPos: -1, + EndPos: 41, }, NewTkn: &token.Token{ ID: token.T_NEW, diff --git a/internal/php7/php7.go b/internal/php7/php7.go index eeb7595..18eef9d 100644 --- a/internal/php7/php7.go +++ b/internal/php7/php7.go @@ -6091,7 +6091,7 @@ yydefault: yyDollar = yyS[yypt-0 : yypt+1] // line internal/php7/php7.y:3492 { - yyVAL.node = &ArgumentList{} + yyVAL.node = nil } case 398: yyDollar = yyS[yypt-1 : yypt+1] diff --git a/internal/php7/php7.y b/internal/php7/php7.y index fceb827..928b3d1 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -3490,7 +3490,7 @@ backticks_expr: ctor_arguments: /* empty */ { - $$ = &ArgumentList{} + $$ = nil } | argument_list { From 78492f64568beb96b8ba8603fae41f340ae28c53 Mon Sep 17 00:00:00 2001 From: i582 Date: Sun, 7 Feb 2021 07:52:29 +0300 Subject: [PATCH 2/2] internal: fixed parsing of anonymous classes Since now 'ctor_arguments' returns nil, it is necessary to initialize it to avoid panics. --- internal/php7/php7.go | 4 ++++ internal/php7/php7.y | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 18eef9d..c7a41b4 100644 --- a/internal/php7/php7.go +++ b/internal/php7/php7.go @@ -4935,6 +4935,10 @@ yydefault: yyDollar = yyS[yypt-8 : yypt+1] // line internal/php7/php7.y:2499 { + if yyDollar[2].node == nil { + yyDollar[2].node = &ArgumentList{} + } + class := &ast.StmtClass{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[8].token), ClassTkn: yyDollar[1].token, diff --git a/internal/php7/php7.y b/internal/php7/php7.y index 928b3d1..389d96b 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -2497,6 +2497,10 @@ non_empty_for_exprs: anonymous_class: T_CLASS ctor_arguments extends_from implements_list backup_doc_comment '{' class_statement_list '}' { + if $2 == nil { + $2 = &ArgumentList{} + } + class := &ast.StmtClass{ Position: yylex.(*Parser).builder.NewTokensPosition($1, $8), ClassTkn: $1,