From 38141ce97f653badc43cc933db4d2f139a26c008 Mon Sep 17 00:00:00 2001 From: Vadym Slizov Date: Mon, 28 Dec 2020 00:38:39 +0200 Subject: [PATCH] refactoring: create "ScalarEncapsedStringVar" node --- internal/php5/parser_test.go | 120 ++++++++++++------------------ internal/php5/php5.go | 106 ++++++++++++-------------- internal/php5/php5.y | 58 ++++++--------- internal/php7/parser_test.go | 120 ++++++++++++------------------ internal/php7/php7.go | 96 +++++++++++------------- internal/php7/php7.y | 58 ++++++--------- pkg/ast/ast.go | 1 + pkg/ast/node.go | 19 +++++ pkg/ast/traverser/dfs.go | 17 +++++ pkg/ast/visitor/dumper.go | 16 ++++ pkg/ast/visitor/formatter.go | 15 ++++ pkg/ast/visitor/formatter_test.go | 49 ++++++++++++ pkg/ast/visitor/null.go | 4 + pkg/ast/visitor/printer.go | 9 +++ 14 files changed, 361 insertions(+), 327 deletions(-) diff --git a/internal/php5/parser_test.go b/internal/php5/parser_test.go index 928496a..c875222 100644 --- a/internal/php5/parser_test.go +++ b/internal/php5/parser_test.go @@ -4335,14 +4335,14 @@ func TestScalarEncapsed_DollarOpenCurlyBraces(t *testing.T) { }, Value: []byte("test "), }, - &ast.ParserBrackets{ + &ast.ScalarEncapsedStringVar{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 9, EndPos: 15, }, - OpenBracketTkn: &token.Token{ + DollarOpenCurlyBracketTkn: &token.Token{ ID: token.T_DOLLAR_OPEN_CURLY_BRACES, Value: []byte("${"), Position: &position.Position{ @@ -4352,34 +4352,26 @@ func TestScalarEncapsed_DollarOpenCurlyBraces(t *testing.T) { EndPos: 11, }, }, - Child: &ast.ExprVariable{ + VarName: &ast.Identifier{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - VarName: &ast.Identifier{ + IdentifierTkn: &token.Token{ + ID: token.T_STRING_VARNAME, + Value: []byte("foo"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING_VARNAME, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - }, - Value: []byte("foo"), }, + Value: []byte("foo"), }, - CloseBracketTkn: &token.Token{ + CloseCurlyBracketTkn: &token.Token{ ID: token.ID(125), Value: []byte("}"), Position: &position.Position{ @@ -4501,14 +4493,14 @@ func TestScalarEncapsed_DollarOpenCurlyBracesDimNumber(t *testing.T) { }, Value: []byte("test "), }, - &ast.ParserBrackets{ + &ast.ScalarEncapsedStringVar{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 9, - EndPos: 18, + EndPos: 15, }, - OpenBracketTkn: &token.Token{ + DollarOpenCurlyBracketTkn: &token.Token{ ID: token.T_DOLLAR_OPEN_CURLY_BRACES, Value: []byte("${"), Position: &position.Position{ @@ -4518,81 +4510,65 @@ func TestScalarEncapsed_DollarOpenCurlyBracesDimNumber(t *testing.T) { EndPos: 11, }, }, - Child: &ast.ExprArrayDimFetch{ + VarName: &ast.Identifier{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, - EndPos: 17, + EndPos: 14, }, - Var: &ast.ExprVariable{ + IdentifierTkn: &token.Token{ + ID: token.T_STRING_VARNAME, + Value: []byte("foo"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - VarName: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING_VARNAME, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - }, - Value: []byte("foo"), - }, }, - OpenBracketTkn: &token.Token{ - ID: token.ID(91), - Value: []byte("["), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, + Value: []byte("foo"), + }, + OpenSquareBracketTkn: &token.Token{ + ID: token.ID(91), + Value: []byte("["), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 14, + EndPos: 15, }, - Dim: &ast.ScalarLnumber{ + }, + Dim: &ast.ScalarLnumber{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 15, + EndPos: 16, + }, + NumberTkn: &token.Token{ + ID: token.T_LNUMBER, + Value: []byte("0"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 15, EndPos: 16, }, - NumberTkn: &token.Token{ - ID: token.T_LNUMBER, - Value: []byte("0"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - }, - Value: []byte("0"), }, - CloseBracketTkn: &token.Token{ - ID: token.ID(93), - Value: []byte("]"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, + Value: []byte("0"), + }, + CloseSquareBracketTkn: &token.Token{ + ID: token.ID(93), + Value: []byte("]"), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 16, + EndPos: 17, }, }, - CloseBracketTkn: &token.Token{ + CloseCurlyBracketTkn: &token.Token{ ID: token.ID(125), Value: []byte("}"), Position: &position.Position{ diff --git a/internal/php5/php5.go b/internal/php5/php5.go index ce0b005..b1468ec 100644 --- a/internal/php5/php5.go +++ b/internal/php5/php5.go @@ -340,7 +340,7 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -// line internal/php5/php5.y:5677 +// line internal/php5/php5.y:5665 // line yacctab:1 var yyExca = [...]int{ @@ -7995,61 +7995,49 @@ yydefault: yyDollar = yyS[yypt-3 : yypt+1] // line internal/php5/php5.y:5414 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewNodePosition(yyDollar[2].node), - VarName: yyDollar[2].node, - }, - CloseBracketTkn: yyDollar[3].token, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: yyDollar[2].node, + CloseCurlyBracketTkn: yyDollar[3].token, } } case 499: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5426 + // line internal/php5/php5.y:5423 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - IdentifierTkn: yyDollar[2].token, - Value: yyDollar[2].token.Value, - }, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), + IdentifierTkn: yyDollar[2].token, + Value: yyDollar[2].token.Value, }, - CloseBracketTkn: yyDollar[3].token, + CloseCurlyBracketTkn: yyDollar[3].token, } } case 500: yyDollar = yyS[yypt-6 : yypt+1] - // line internal/php5/php5.y:5442 + // line internal/php5/php5.y:5436 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[6].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[2].token, yyDollar[5].token), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - IdentifierTkn: yyDollar[2].token, - Value: yyDollar[2].token.Value, - }, - }, - OpenBracketTkn: yyDollar[3].token, - Dim: yyDollar[4].node, - CloseBracketTkn: yyDollar[5].token, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), + IdentifierTkn: yyDollar[2].token, + Value: yyDollar[2].token.Value, }, - CloseBracketTkn: yyDollar[6].token, + OpenSquareBracketTkn: yyDollar[3].token, + Dim: yyDollar[4].node, + CloseSquareBracketTkn: yyDollar[5].token, + CloseCurlyBracketTkn: yyDollar[6].token, } } case 501: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5464 + // line internal/php5/php5.y:5452 { yyVAL.node = &ast.ParserBrackets{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), @@ -8060,7 +8048,7 @@ yydefault: } case 502: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5476 + // line internal/php5/php5.y:5464 { yyVAL.node = &ast.ScalarString{ Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[1].token), @@ -8070,7 +8058,7 @@ yydefault: } case 503: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5484 + // line internal/php5/php5.y:5472 { // TODO: add option to handle 64 bit integer if _, err := strconv.Atoi(string(yyDollar[1].token.Value)); err == nil { @@ -8089,7 +8077,7 @@ yydefault: } case 504: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5501 + // line internal/php5/php5.y:5489 { yyVAL.node = &ast.ExprVariable{ Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[1].token), @@ -8102,7 +8090,7 @@ yydefault: } case 505: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php5/php5.y:5515 + // line internal/php5/php5.y:5503 { yyVAL.node = &ast.ExprIsset{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -8115,7 +8103,7 @@ yydefault: } case 506: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php5/php5.y:5526 + // line internal/php5/php5.y:5514 { yyVAL.node = &ast.ExprEmpty{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -8127,7 +8115,7 @@ yydefault: } case 507: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php5/php5.y:5536 + // line internal/php5/php5.y:5524 { yyVAL.node = &ast.ExprEmpty{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -8139,7 +8127,7 @@ yydefault: } case 508: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php5/php5.y:5546 + // line internal/php5/php5.y:5534 { yyVAL.node = &ast.ExprInclude{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -8149,7 +8137,7 @@ yydefault: } case 509: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php5/php5.y:5554 + // line internal/php5/php5.y:5542 { yyVAL.node = &ast.ExprIncludeOnce{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -8159,7 +8147,7 @@ yydefault: } case 510: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php5/php5.y:5562 + // line internal/php5/php5.y:5550 { yyVAL.node = &ast.ExprEval{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -8171,7 +8159,7 @@ yydefault: } case 511: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php5/php5.y:5572 + // line internal/php5/php5.y:5560 { yyVAL.node = &ast.ExprRequire{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -8181,7 +8169,7 @@ yydefault: } case 512: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php5/php5.y:5580 + // line internal/php5/php5.y:5568 { yyVAL.node = &ast.ExprRequireOnce{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -8191,7 +8179,7 @@ yydefault: } case 513: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5591 + // line internal/php5/php5.y:5579 { yyVAL.node = &ast.ParserSeparatedList{ Items: []ast.Vertex{yyDollar[1].node}, @@ -8199,7 +8187,7 @@ yydefault: } case 514: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5597 + // line internal/php5/php5.y:5585 { yyDollar[1].node.(*ast.ParserSeparatedList).SeparatorTkns = append(yyDollar[1].node.(*ast.ParserSeparatedList).SeparatorTkns, yyDollar[2].token) yyDollar[1].node.(*ast.ParserSeparatedList).Items = append(yyDollar[1].node.(*ast.ParserSeparatedList).Items, yyDollar[3].node) @@ -8208,19 +8196,19 @@ yydefault: } case 515: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5607 + // line internal/php5/php5.y:5595 { yyVAL.node = yyDollar[1].node } case 516: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php5/php5.y:5611 + // line internal/php5/php5.y:5599 { yyVAL.node = yyDollar[1].node } case 517: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5618 + // line internal/php5/php5.y:5606 { yyVAL.node = &ast.ExprClassConstFetch{ Position: yylex.(*Parser).builder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[3].token), @@ -8235,7 +8223,7 @@ yydefault: } case 518: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5631 + // line internal/php5/php5.y:5619 { yyVAL.node = &ast.ExprClassConstFetch{ Position: yylex.(*Parser).builder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[3].token), @@ -8250,7 +8238,7 @@ yydefault: } case 519: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5647 + // line internal/php5/php5.y:5635 { yyVAL.node = &ast.ExprClassConstFetch{ Position: yylex.(*Parser).builder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[3].token), @@ -8265,7 +8253,7 @@ yydefault: } case 520: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php5/php5.y:5663 + // line internal/php5/php5.y:5651 { yyVAL.node = &ast.ExprClassConstFetch{ Position: yylex.(*Parser).builder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[3].token), diff --git a/internal/php5/php5.y b/internal/php5/php5.y index 245e18a..5c2a399 100644 --- a/internal/php5/php5.y +++ b/internal/php5/php5.y @@ -5412,52 +5412,40 @@ encaps_var: } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewNodePosition($2), - VarName: $2, - }, - CloseBracketTkn: $3, + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: $2, + CloseCurlyBracketTkn: $3, } } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Child: &ast.ExprVariable{ + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: &ast.Identifier{ Position: yylex.(*Parser).builder.NewTokenPosition($2), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, + IdentifierTkn: $2, + Value: $2.Value, }, - CloseBracketTkn: $3, + CloseCurlyBracketTkn: $3, } } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $6), - OpenBracketTkn: $1, - Child: &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $5), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - }, - OpenBracketTkn: $3, - Dim: $4, - CloseBracketTkn: $5, + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition($2), + IdentifierTkn: $2, + Value: $2.Value, }, - CloseBracketTkn: $6, + OpenSquareBracketTkn: $3, + Dim: $4, + CloseSquareBracketTkn: $5, + CloseCurlyBracketTkn: $6, } } | T_CURLY_OPEN variable '}' diff --git a/internal/php7/parser_test.go b/internal/php7/parser_test.go index 4957b16..ca22168 100644 --- a/internal/php7/parser_test.go +++ b/internal/php7/parser_test.go @@ -4692,14 +4692,14 @@ func TestScalarEncapsed_DollarOpenCurlyBraces(t *testing.T) { }, Value: []byte("test "), }, - &ast.ParserBrackets{ + &ast.ScalarEncapsedStringVar{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 9, EndPos: 15, }, - OpenBracketTkn: &token.Token{ + DollarOpenCurlyBracketTkn: &token.Token{ ID: token.T_DOLLAR_OPEN_CURLY_BRACES, Value: []byte("${"), Position: &position.Position{ @@ -4709,34 +4709,26 @@ func TestScalarEncapsed_DollarOpenCurlyBraces(t *testing.T) { EndPos: 11, }, }, - Child: &ast.ExprVariable{ + VarName: &ast.Identifier{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - VarName: &ast.Identifier{ + IdentifierTkn: &token.Token{ + ID: token.T_STRING_VARNAME, + Value: []byte("foo"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING_VARNAME, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - }, - Value: []byte("foo"), }, + Value: []byte("foo"), }, - CloseBracketTkn: &token.Token{ + CloseCurlyBracketTkn: &token.Token{ ID: token.ID(125), Value: []byte("}"), Position: &position.Position{ @@ -4858,14 +4850,14 @@ func TestScalarEncapsed_DollarOpenCurlyBracesDimNumber(t *testing.T) { }, Value: []byte("test "), }, - &ast.ParserBrackets{ + &ast.ScalarEncapsedStringVar{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 9, - EndPos: 18, + EndPos: 15, }, - OpenBracketTkn: &token.Token{ + DollarOpenCurlyBracketTkn: &token.Token{ ID: token.T_DOLLAR_OPEN_CURLY_BRACES, Value: []byte("${"), Position: &position.Position{ @@ -4875,81 +4867,65 @@ func TestScalarEncapsed_DollarOpenCurlyBracesDimNumber(t *testing.T) { EndPos: 11, }, }, - Child: &ast.ExprArrayDimFetch{ + VarName: &ast.Identifier{ Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, - EndPos: 17, + EndPos: 14, }, - Var: &ast.ExprVariable{ + IdentifierTkn: &token.Token{ + ID: token.T_STRING_VARNAME, + Value: []byte("foo"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 11, EndPos: 14, }, - VarName: &ast.Identifier{ - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - IdentifierTkn: &token.Token{ - ID: token.T_STRING_VARNAME, - Value: []byte("foo"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 11, - EndPos: 14, - }, - }, - Value: []byte("foo"), - }, }, - OpenBracketTkn: &token.Token{ - ID: token.ID(91), - Value: []byte("["), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 14, - EndPos: 15, - }, + Value: []byte("foo"), + }, + OpenSquareBracketTkn: &token.Token{ + ID: token.ID(91), + Value: []byte("["), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 14, + EndPos: 15, }, - Dim: &ast.ScalarLnumber{ + }, + Dim: &ast.ScalarLnumber{ + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 15, + EndPos: 16, + }, + NumberTkn: &token.Token{ + ID: token.T_LNUMBER, + Value: []byte("0"), Position: &position.Position{ StartLine: 1, EndLine: 1, StartPos: 15, EndPos: 16, }, - NumberTkn: &token.Token{ - ID: token.T_LNUMBER, - Value: []byte("0"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 15, - EndPos: 16, - }, - }, - Value: []byte("0"), }, - CloseBracketTkn: &token.Token{ - ID: token.ID(93), - Value: []byte("]"), - Position: &position.Position{ - StartLine: 1, - EndLine: 1, - StartPos: 16, - EndPos: 17, - }, + Value: []byte("0"), + }, + CloseSquareBracketTkn: &token.Token{ + ID: token.ID(93), + Value: []byte("]"), + Position: &position.Position{ + StartLine: 1, + EndLine: 1, + StartPos: 16, + EndPos: 17, }, }, - CloseBracketTkn: &token.Token{ + CloseCurlyBracketTkn: &token.Token{ ID: token.ID(125), Value: []byte("}"), Position: &position.Position{ diff --git a/internal/php7/php7.go b/internal/php7/php7.go index 5e50fce..f4271ba 100644 --- a/internal/php7/php7.go +++ b/internal/php7/php7.go @@ -339,7 +339,7 @@ const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -// line internal/php7/php7.y:4390 +// line internal/php7/php7.y:4378 // line yacctab:1 var yyExca = [...]int{ @@ -6868,61 +6868,49 @@ yydefault: yyDollar = yyS[yypt-3 : yypt+1] // line internal/php7/php7.y:4172 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewNodePosition(yyDollar[2].node), - VarName: yyDollar[2].node, - }, - CloseBracketTkn: yyDollar[3].token, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: yyDollar[2].node, + CloseCurlyBracketTkn: yyDollar[3].token, } } case 478: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php7/php7.y:4184 + // line internal/php7/php7.y:4181 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - IdentifierTkn: yyDollar[2].token, - Value: yyDollar[2].token.Value, - }, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), + IdentifierTkn: yyDollar[2].token, + Value: yyDollar[2].token.Value, }, - CloseBracketTkn: yyDollar[3].token, + CloseCurlyBracketTkn: yyDollar[3].token, } } case 479: yyDollar = yyS[yypt-6 : yypt+1] - // line internal/php7/php7.y:4200 + // line internal/php7/php7.y:4194 { - yyVAL.node = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[6].token), - OpenBracketTkn: yyDollar[1].token, - Child: &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[2].token, yyDollar[5].token), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), - IdentifierTkn: yyDollar[2].token, - Value: yyDollar[2].token.Value, - }, - }, - OpenBracketTkn: yyDollar[3].token, - Dim: yyDollar[4].node, - CloseBracketTkn: yyDollar[5].token, + yyVAL.node = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), + DollarOpenCurlyBracketTkn: yyDollar[1].token, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[2].token), + IdentifierTkn: yyDollar[2].token, + Value: yyDollar[2].token.Value, }, - CloseBracketTkn: yyDollar[6].token, + OpenSquareBracketTkn: yyDollar[3].token, + Dim: yyDollar[4].node, + CloseSquareBracketTkn: yyDollar[5].token, + CloseCurlyBracketTkn: yyDollar[6].token, } } case 480: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php7/php7.y:4222 + // line internal/php7/php7.y:4210 { yyVAL.node = &ast.ParserBrackets{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token), @@ -6933,7 +6921,7 @@ yydefault: } case 481: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php7/php7.y:4234 + // line internal/php7/php7.y:4222 { yyVAL.node = &ast.ScalarString{ Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[1].token), @@ -6943,7 +6931,7 @@ yydefault: } case 482: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php7/php7.y:4242 + // line internal/php7/php7.y:4230 { // TODO: add option to handle 64 bit integer if _, err := strconv.Atoi(string(yyDollar[1].token.Value)); err == nil { @@ -6962,7 +6950,7 @@ yydefault: } case 483: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php7/php7.y:4259 + // line internal/php7/php7.y:4247 { _, err := strconv.Atoi(string(yyDollar[2].token.Value)) isInt := err == nil @@ -6988,7 +6976,7 @@ yydefault: } case 484: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php7/php7.y:4283 + // line internal/php7/php7.y:4271 { yyVAL.node = &ast.ExprVariable{ Position: yylex.(*Parser).builder.NewTokenPosition(yyDollar[1].token), @@ -7001,7 +6989,7 @@ yydefault: } case 485: yyDollar = yyS[yypt-5 : yypt+1] - // line internal/php7/php7.y:4297 + // line internal/php7/php7.y:4285 { if yyDollar[4].token != nil { yyDollar[3].node.(*ast.ParserSeparatedList).SeparatorTkns = append(yyDollar[3].node.(*ast.ParserSeparatedList).SeparatorTkns, yyDollar[4].token) @@ -7018,7 +7006,7 @@ yydefault: } case 486: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php7/php7.y:4312 + // line internal/php7/php7.y:4300 { yyVAL.node = &ast.ExprEmpty{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -7030,7 +7018,7 @@ yydefault: } case 487: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php7/php7.y:4322 + // line internal/php7/php7.y:4310 { yyVAL.node = &ast.ExprInclude{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -7040,7 +7028,7 @@ yydefault: } case 488: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php7/php7.y:4330 + // line internal/php7/php7.y:4318 { yyVAL.node = &ast.ExprIncludeOnce{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -7050,7 +7038,7 @@ yydefault: } case 489: yyDollar = yyS[yypt-4 : yypt+1] - // line internal/php7/php7.y:4338 + // line internal/php7/php7.y:4326 { yyVAL.node = &ast.ExprEval{ Position: yylex.(*Parser).builder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token), @@ -7062,7 +7050,7 @@ yydefault: } case 490: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php7/php7.y:4348 + // line internal/php7/php7.y:4336 { yyVAL.node = &ast.ExprRequire{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -7072,7 +7060,7 @@ yydefault: } case 491: yyDollar = yyS[yypt-2 : yypt+1] - // line internal/php7/php7.y:4356 + // line internal/php7/php7.y:4344 { yyVAL.node = &ast.ExprRequireOnce{ Position: yylex.(*Parser).builder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node), @@ -7082,7 +7070,7 @@ yydefault: } case 492: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php7/php7.y:4367 + // line internal/php7/php7.y:4355 { yyVAL.node = &ast.ParserSeparatedList{ Items: []ast.Vertex{yyDollar[1].node}, @@ -7090,7 +7078,7 @@ yydefault: } case 493: yyDollar = yyS[yypt-3 : yypt+1] - // line internal/php7/php7.y:4373 + // line internal/php7/php7.y:4361 { yyDollar[1].node.(*ast.ParserSeparatedList).SeparatorTkns = append(yyDollar[1].node.(*ast.ParserSeparatedList).SeparatorTkns, yyDollar[2].token) yyDollar[1].node.(*ast.ParserSeparatedList).Items = append(yyDollar[1].node.(*ast.ParserSeparatedList).Items, yyDollar[3].node) @@ -7099,7 +7087,7 @@ yydefault: } case 494: yyDollar = yyS[yypt-1 : yypt+1] - // line internal/php7/php7.y:4383 + // line internal/php7/php7.y:4371 { yyVAL.node = yyDollar[1].node } diff --git a/internal/php7/php7.y b/internal/php7/php7.y index f388612..e695902 100644 --- a/internal/php7/php7.y +++ b/internal/php7/php7.y @@ -4170,52 +4170,40 @@ encaps_var: } | T_DOLLAR_OPEN_CURLY_BRACES expr '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Child: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewNodePosition($2), - VarName: $2, - }, - CloseBracketTkn: $3, + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: $2, + CloseCurlyBracketTkn: $3, } } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), - OpenBracketTkn: $1, - Child: &ast.ExprVariable{ + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: &ast.Identifier{ Position: yylex.(*Parser).builder.NewTokenPosition($2), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, + IdentifierTkn: $2, + Value: $2.Value, }, - CloseBracketTkn: $3, + CloseCurlyBracketTkn: $3, } } | T_DOLLAR_OPEN_CURLY_BRACES T_STRING_VARNAME '[' expr ']' '}' { - $$ = &ast.ParserBrackets{ - Position: yylex.(*Parser).builder.NewTokensPosition($1, $6), - OpenBracketTkn: $1, - Child: &ast.ExprArrayDimFetch{ - Position: yylex.(*Parser).builder.NewTokensPosition($2, $5), - Var: &ast.ExprVariable{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - VarName: &ast.Identifier{ - Position: yylex.(*Parser).builder.NewTokenPosition($2), - IdentifierTkn: $2, - Value: $2.Value, - }, - }, - OpenBracketTkn: $3, - Dim: $4, - CloseBracketTkn: $5, + $$ = &ast.ScalarEncapsedStringVar{ + Position: yylex.(*Parser).builder.NewTokensPosition($1, $3), + DollarOpenCurlyBracketTkn: $1, + VarName: &ast.Identifier{ + Position: yylex.(*Parser).builder.NewTokenPosition($2), + IdentifierTkn: $2, + Value: $2.Value, }, - CloseBracketTkn: $6, + OpenSquareBracketTkn: $3, + Dim: $4, + CloseSquareBracketTkn: $5, + CloseCurlyBracketTkn: $6, } } | T_CURLY_OPEN variable '}' diff --git a/pkg/ast/ast.go b/pkg/ast/ast.go index 2debd18..214c67d 100644 --- a/pkg/ast/ast.go +++ b/pkg/ast/ast.go @@ -175,6 +175,7 @@ type NodeVisitor interface { ScalarDnumber(n *ScalarDnumber) ScalarEncapsed(n *ScalarEncapsed) ScalarEncapsedStringPart(n *ScalarEncapsedStringPart) + ScalarEncapsedStringVar(n *ScalarEncapsedStringVar) ScalarHeredoc(n *ScalarHeredoc) ScalarLnumber(n *ScalarLnumber) ScalarMagicConstant(n *ScalarMagicConstant) diff --git a/pkg/ast/node.go b/pkg/ast/node.go index cf71bcd..edfa296 100644 --- a/pkg/ast/node.go +++ b/pkg/ast/node.go @@ -131,6 +131,25 @@ func (n *ScalarEncapsedStringPart) GetPosition() *position.Position { return n.Position } +// ScalarEncapsedStringVar node +type ScalarEncapsedStringVar struct { + Position *position.Position + DollarOpenCurlyBracketTkn *token.Token + VarName Vertex + OpenSquareBracketTkn *token.Token + Dim Vertex + CloseSquareBracketTkn *token.Token + CloseCurlyBracketTkn *token.Token +} + +func (n *ScalarEncapsedStringVar) Accept(v NodeVisitor) { + v.ScalarEncapsedStringVar(n) +} + +func (n *ScalarEncapsedStringVar) GetPosition() *position.Position { + return n.Position +} + // ScalarHeredoc node type ScalarHeredoc struct { Position *position.Position diff --git a/pkg/ast/traverser/dfs.go b/pkg/ast/traverser/dfs.go index c41d2eb..f5683de 100644 --- a/pkg/ast/traverser/dfs.go +++ b/pkg/ast/traverser/dfs.go @@ -2455,6 +2455,23 @@ func (t *DFS) Traverse(n ast.Vertex) { if !t.visitor.EnterNode(nn) { return } + case *ast.ScalarEncapsedStringVar: + if nn == nil { + return + } + if !t.visitor.EnterNode(nn) { + return + } + if nn.VarName != nil { + t.visitor.Enter("VarName", true) + t.Traverse(nn.VarName) + t.visitor.Leave("VarName", true) + } + if nn.Dim != nil { + t.visitor.Enter("Dim", true) + t.Traverse(nn.Dim) + t.visitor.Leave("Dim", true) + } case *ast.ScalarHeredoc: if nn == nil { return diff --git a/pkg/ast/visitor/dumper.go b/pkg/ast/visitor/dumper.go index b9c8af6..6b01b99 100644 --- a/pkg/ast/visitor/dumper.go +++ b/pkg/ast/visitor/dumper.go @@ -2258,6 +2258,22 @@ func (v *Dumper) ScalarEncapsedStringPart(n *ast.ScalarEncapsedStringPart) { v.print(v.indent, "},\n") } +func (v *Dumper) ScalarEncapsedStringVar(n *ast.ScalarEncapsedStringVar) { + v.print(0, "&ast.ScalarEncapsedStringVar{\n") + v.indent++ + + v.dumpPosition(n.Position) + v.dumpToken("DollarOpenCurlyBracketTkn", n.DollarOpenCurlyBracketTkn) + v.dumpVertex("VarName", n.VarName) + v.dumpToken("OpenSquareBracketTkn", n.OpenSquareBracketTkn) + v.dumpVertex("Dim", n.Dim) + v.dumpToken("CloseSquareBracketTkn", n.CloseSquareBracketTkn) + v.dumpToken("CloseCurlyBracketTkn", n.CloseCurlyBracketTkn) + + v.indent-- + v.print(v.indent, "},\n") +} + func (v *Dumper) ScalarHeredoc(n *ast.ScalarHeredoc) { v.print(0, "&ast.ScalarHeredoc{\n") v.indent++ diff --git a/pkg/ast/visitor/formatter.go b/pkg/ast/visitor/formatter.go index 193f8b1..8c42228 100644 --- a/pkg/ast/visitor/formatter.go +++ b/pkg/ast/visitor/formatter.go @@ -1970,6 +1970,21 @@ func (f *formatter) ScalarEncapsedStringPart(n *ast.ScalarEncapsedStringPart) { } } +func (f *formatter) ScalarEncapsedStringVar(n *ast.ScalarEncapsedStringVar) { + n.DollarOpenCurlyBracketTkn = f.newToken(token.T_DOLLAR_OPEN_CURLY_BRACES, []byte("${")) + n.VarName.Accept(f) + + n.OpenSquareBracketTkn = nil + n.CloseSquareBracketTkn = nil + if n.Dim != nil { + n.OpenSquareBracketTkn = f.newToken('[', []byte("[")) + n.Dim.Accept(f) + n.CloseSquareBracketTkn = f.newToken(']', []byte("]")) + } + + n.CloseCurlyBracketTkn = f.newToken('}', []byte("}")) +} + func (f *formatter) ScalarHeredoc(n *ast.ScalarHeredoc) { n.OpenHeredocTkn = f.newToken(token.T_START_HEREDOC, []byte("<<