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 Binary files a/internal/php5/php5.go and b/internal/php5/php5.go differ 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 Binary files a/internal/php7/php7.go and b/internal/php7/php7.go differ 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("<<