add Heredoc node

This commit is contained in:
z7zmey 2018-04-05 13:47:36 +03:00
parent a0cc61bdc0
commit 9ea1f05f90
12 changed files with 676 additions and 459 deletions

View File

@ -0,0 +1,44 @@
package scalar
import (
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/walker"
)
// Heredoc node
type Heredoc struct {
Label string
Parts []node.Node
}
// NewHeredoc node constructor
func NewHeredoc(Label string, Parts []node.Node) *Heredoc {
return &Heredoc{
Label,
Parts,
}
}
// Attributes returns node attributes as map
func (n *Heredoc) Attributes() map[string]interface{} {
return map[string]interface{}{
"Label": n.Label,
}
}
// Walk traverses nodes
// Walk is invoked recursively until v.EnterNode returns true
func (n *Heredoc) Walk(v walker.Visitor) {
if v.EnterNode(n) == false {
return
}
if n.Parts != nil {
vv := v.GetChildrenVisitor("Parts")
for _, nn := range n.Parts {
if nn != nil {
nn.Walk(vv)
}
}
}
}

View File

@ -0,0 +1,144 @@
package scalar_test
import (
"bytes"
"testing"
"github.com/z7zmey/php-parser/node/expr"
"github.com/z7zmey/php-parser/node"
"github.com/z7zmey/php-parser/node/scalar"
"github.com/z7zmey/php-parser/node/stmt"
"github.com/z7zmey/php-parser/php7"
"github.com/z7zmey/php-parser/php5"
)
func TestHeredocSimpleLabel(t *testing.T) {
src := `<? <<<LBL
test $var
LBL;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "LBL",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "test "},
&expr.Variable{VarName: &node.Identifier{Value: "var"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestSimpleHeredocLabel(t *testing.T) {
src := `<? <<<"LBL"
test $var
LBL;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "\"LBL\"",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "test "},
&expr.Variable{VarName: &node.Identifier{Value: "var"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestSimpleNowdocLabel(t *testing.T) {
src := `<? <<<'LBL'
test $var
LBL;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "'LBL'",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "test $var\n"},
},
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestEmptyHeredoc(t *testing.T) {
src := `<? <<<CAD
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestHeredocScalarString(t *testing.T) {
src := `<? <<<CAD
hello
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello\n"},
},
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}

View File

@ -102,87 +102,4 @@ func TestMultilineSingleQuotedScalarString(t *testing.T) {
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php") actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestPlainHeredocEmptyString(t *testing.T) {
src := `<? <<<CAD
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Encapsed{},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestPlainHeredocScalarString(t *testing.T) {
src := `<? <<<CAD
hello
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestHeredocScalarString(t *testing.T) {
src := `<? <<<"CAD"
hello
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestNowdocScalarString(t *testing.T) {
src := `<? <<<'CAD'
hello $world
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.String{Value: "\thello $world\n"},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
actual, _, _ = php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}

View File

@ -45,6 +45,11 @@ var nameNodesTests = []struct {
[]string{"Parts"}, []string{"Parts"},
nil, nil,
}, },
{
&scalar.Heredoc{Label: "LBL", Parts: []node.Node{&scalar.EncapsedStringPart{Value: "foo"}}},
[]string{"Parts"},
map[string]interface{}{"Label": "LBL"},
},
} }
type visitorMock struct { type visitorMock struct {

File diff suppressed because it is too large Load Diff

View File

@ -2720,13 +2720,17 @@ common_scalar:
} }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
{ {
$$ = scalar.NewString($2.Value) encapsed := scalar.NewEncapsedStringPart($2.Value)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))/* TODO: mark as Heredoc*/ positions.AddPosition(encapsed, positionBuilder.NewTokenPosition($2))
comments.AddComments(encapsed, $2.Comments())
$$ = scalar.NewHeredoc($1.Value, []node.Node{encapsed})
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
| T_START_HEREDOC T_END_HEREDOC | T_START_HEREDOC T_END_HEREDOC
{ {
$$ = scalar.NewEncapsed(nil) $$ = scalar.NewHeredoc($1.Value, nil)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $2)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $2))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
@ -3066,7 +3070,7 @@ scalar:
} }
| T_START_HEREDOC encaps_list T_END_HEREDOC | T_START_HEREDOC encaps_list T_END_HEREDOC
{ {
$$ = scalar.NewEncapsed($2) $$ = scalar.NewHeredoc($1.Value, $2)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }

View File

@ -45,30 +45,6 @@ func TestPhp5(t *testing.T) {
function(bar $bar=null, baz &...$baz) {}; function(bar $bar=null, baz &...$baz) {};
static function(bar $bar=null, baz &...$baz) {}; static function(bar $bar=null, baz &...$baz) {};
"test";
"\$test";
"
test
";
'$test';
'
$test
';
<<<CAD
CAD;
<<<CAD
hello
CAD;
<<<"CAD"
hello
CAD;
<<<"CAD"
hello $world
CAD;
<<<'CAD'
hello $world
CAD;
1234567890123456789; 1234567890123456789;
12345678901234567890; 12345678901234567890;
0.; 0.;
@ -545,42 +521,6 @@ CAD;
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
&stmt.Expression{
Expr: &scalar.String{Value: "\"test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\\$test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\n\t\t\ttest\n\t\t\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'$test'"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'\n\t\t\t$test\n\t\t'"},
},
&stmt.Expression{
Expr: &scalar.Encapsed{},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
&stmt.Expression{
Expr: &scalar.Encapsed{
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello "},
&expr.Variable{VarName: &node.Identifier{Value: "world"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello $world\n"},
},
&stmt.Expression{ &stmt.Expression{
Expr: &scalar.Lnumber{Value: "1234567890123456789"}, Expr: &scalar.Lnumber{Value: "1234567890123456789"},
}, },
@ -3678,3 +3618,106 @@ CAD;
actual, _, _ := php5.Parse(bytes.NewBufferString(src), "test.php") actual, _, _ := php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestPhp5Strings(t *testing.T) {
src := `<?
"test";
"\$test";
"
test
";
'$test';
'
$test
';
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.String{Value: "\"test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\\$test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\n\t\t\ttest\n\t\t\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'$test'"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'\n\t\t\t$test\n\t\t'"},
},
},
}
actual, _, _ := php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestPhp5Heredoc(t *testing.T) {
src := `<?
<<<CAD
CAD;
<<<CAD
hello
CAD;
<<<"CAD"
hello
CAD;
<<<"CAD"
hello $world
CAD;
<<<'CAD'
hello $world
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "\"CAD\"",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "\"CAD\"",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello "},
&expr.Variable{VarName: &node.Identifier{Value: "world"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "'CAD'",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello $world\n"},
},
},
},
},
}
actual, _, _ := php5.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}

View File

@ -344,7 +344,7 @@ const yyEofCode = 1
const yyErrCode = 2 const yyErrCode = 2
const yyInitialStackSize = 16 const yyInitialStackSize = 16
//line php7/php7.y:2610 //line php7/php7.y:2615
//line yacctab:1 //line yacctab:1
var yyExca = [...]int{ var yyExca = [...]int{
@ -5082,21 +5082,25 @@ yydefault:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2126 //line php7/php7.y:2126
{ {
yyVAL.node = scalar.NewString(yyDollar[2].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token)) /* TODO: mark as Heredoc*/ positions.AddPosition(encapsed, positionBuilder.NewTokenPosition(yyDollar[2].token))
comments.AddComments(encapsed, yyDollar[2].token.Comments())
yyVAL.node = scalar.NewHeredoc(yyDollar[1].token.Value, []node.Node{encapsed})
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }
case 407: case 407:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2131 //line php7/php7.y:2136
{ {
yyVAL.node = scalar.NewEncapsed(nil) yyVAL.node = scalar.NewHeredoc(yyDollar[1].token.Value, nil)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[2].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[2].token))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }
case 408: case 408:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2137 //line php7/php7.y:2142
{ {
yyVAL.node = scalar.NewEncapsed(yyDollar[2].list) yyVAL.node = scalar.NewEncapsed(yyDollar[2].list)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token))
@ -5104,27 +5108,27 @@ yydefault:
} }
case 409: case 409:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2143 //line php7/php7.y:2148
{ {
yyVAL.node = scalar.NewEncapsed(yyDollar[2].list) yyVAL.node = scalar.NewHeredoc(yyDollar[1].token.Value, yyDollar[2].list)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token))
comments.AddComments(yyVAL.node, yyDollar[1].token.Comments()) comments.AddComments(yyVAL.node, yyDollar[1].token.Comments())
} }
case 410: case 410:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2148 //line php7/php7.y:2153
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 411: case 411:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2149 //line php7/php7.y:2154
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 412: case 412:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2154 //line php7/php7.y:2159
{ {
yyVAL.node = expr.NewConstFetch(yyDollar[1].node) yyVAL.node = expr.NewConstFetch(yyDollar[1].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodePosition(yyDollar[1].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodePosition(yyDollar[1].node))
@ -5132,7 +5136,7 @@ yydefault:
} }
case 413: case 413:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2160 //line php7/php7.y:2165
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
positions.AddPosition(target, positionBuilder.NewTokenPosition(yyDollar[3].token)) positions.AddPosition(target, positionBuilder.NewTokenPosition(yyDollar[3].token))
@ -5144,7 +5148,7 @@ yydefault:
} }
case 414: case 414:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2170 //line php7/php7.y:2175
{ {
target := node.NewIdentifier(yyDollar[3].token.Value) target := node.NewIdentifier(yyDollar[3].token.Value)
positions.AddPosition(target, positionBuilder.NewTokenPosition(yyDollar[3].token)) positions.AddPosition(target, positionBuilder.NewTokenPosition(yyDollar[3].token))
@ -5156,79 +5160,79 @@ yydefault:
} }
case 415: case 415:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2182 //line php7/php7.y:2187
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 416: case 416:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2183 //line php7/php7.y:2188
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 417: case 417:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line php7/php7.y:2187 //line php7/php7.y:2192
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 418: case 418:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2188 //line php7/php7.y:2193
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 419: case 419:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2192 //line php7/php7.y:2197
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 420: case 420:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2196 //line php7/php7.y:2201
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 421: case 421:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2197 //line php7/php7.y:2202
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 422: case 422:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2198 //line php7/php7.y:2203
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 423: case 423:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2202 //line php7/php7.y:2207
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 424: case 424:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2203 //line php7/php7.y:2208
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 425: case 425:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2204 //line php7/php7.y:2209
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 426: case 426:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2208 //line php7/php7.y:2213
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 427: case 427:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2210 //line php7/php7.y:2215
{ {
yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token))
@ -5236,7 +5240,7 @@ yydefault:
} }
case 428: case 428:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2216 //line php7/php7.y:2221
{ {
yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token))
@ -5244,7 +5248,7 @@ yydefault:
} }
case 429: case 429:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2222 //line php7/php7.y:2227
{ {
yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token))
@ -5252,7 +5256,7 @@ yydefault:
} }
case 430: case 430:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2228 //line php7/php7.y:2233
{ {
yyVAL.node = expr.NewMethodCall(yyDollar[1].node, yyDollar[3].node, yyDollar[4].nodesWithEndToken.nodes) yyVAL.node = expr.NewMethodCall(yyDollar[1].node, yyDollar[3].node, yyDollar[4].nodesWithEndToken.nodes)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].nodesWithEndToken.endToken)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].nodesWithEndToken.endToken))
@ -5260,25 +5264,25 @@ yydefault:
} }
case 431: case 431:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2233 //line php7/php7.y:2238
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 432: case 432:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2237 //line php7/php7.y:2242
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 433: case 433:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2238 //line php7/php7.y:2243
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 434: case 434:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2240 //line php7/php7.y:2245
{ {
yyVAL.node = expr.NewPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5286,7 +5290,7 @@ yydefault:
} }
case 435: case 435:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2249 //line php7/php7.y:2254
{ {
name := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$")) name := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$"))
positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5298,7 +5302,7 @@ yydefault:
} }
case 436: case 436:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2259 //line php7/php7.y:2264
{ {
yyVAL.node = expr.NewVariable(yyDollar[3].node) yyVAL.node = expr.NewVariable(yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token))
@ -5306,7 +5310,7 @@ yydefault:
} }
case 437: case 437:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2265 //line php7/php7.y:2270
{ {
yyVAL.node = expr.NewVariable(yyDollar[2].node) yyVAL.node = expr.NewVariable(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5314,7 +5318,7 @@ yydefault:
} }
case 438: case 438:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2274 //line php7/php7.y:2279
{ {
yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5322,7 +5326,7 @@ yydefault:
} }
case 439: case 439:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2280 //line php7/php7.y:2285
{ {
yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5330,13 +5334,13 @@ yydefault:
} }
case 440: case 440:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2288 //line php7/php7.y:2293
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 441: case 441:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2290 //line php7/php7.y:2295
{ {
yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token))
@ -5344,7 +5348,7 @@ yydefault:
} }
case 442: case 442:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2296 //line php7/php7.y:2301
{ {
yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewArrayDimFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodeTokenPosition(yyDollar[1].node, yyDollar[4].token))
@ -5352,7 +5356,7 @@ yydefault:
} }
case 443: case 443:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2302 //line php7/php7.y:2307
{ {
yyVAL.node = expr.NewPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5360,7 +5364,7 @@ yydefault:
} }
case 444: case 444:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2308 //line php7/php7.y:2313
{ {
yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5368,7 +5372,7 @@ yydefault:
} }
case 445: case 445:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2314 //line php7/php7.y:2319
{ {
yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node) yyVAL.node = expr.NewStaticPropertyFetch(yyDollar[1].node, yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5376,7 +5380,7 @@ yydefault:
} }
case 446: case 446:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2323 //line php7/php7.y:2328
{ {
yyVAL.node = node.NewIdentifier(yyDollar[1].token.Value) yyVAL.node = node.NewIdentifier(yyDollar[1].token.Value)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5384,19 +5388,19 @@ yydefault:
} }
case 447: case 447:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2328 //line php7/php7.y:2333
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 448: case 448:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2329 //line php7/php7.y:2334
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 449: case 449:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2334 //line php7/php7.y:2339
{ {
yyVAL.node = node.NewIdentifier(yyDollar[1].token.Value) yyVAL.node = node.NewIdentifier(yyDollar[1].token.Value)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5404,19 +5408,19 @@ yydefault:
} }
case 450: case 450:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2339 //line php7/php7.y:2344
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 451: case 451:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2340 //line php7/php7.y:2345
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 452: case 452:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2345 //line php7/php7.y:2350
{ {
if yyDollar[1].list[len(yyDollar[1].list)-1] == nil { if yyDollar[1].list[len(yyDollar[1].list)-1] == nil {
yyVAL.list = yyDollar[1].list[:len(yyDollar[1].list)-1] yyVAL.list = yyDollar[1].list[:len(yyDollar[1].list)-1]
@ -5426,31 +5430,31 @@ yydefault:
} }
case 453: case 453:
yyDollar = yyS[yypt-0 : yypt+1] yyDollar = yyS[yypt-0 : yypt+1]
//line php7/php7.y:2355 //line php7/php7.y:2360
{ {
yyVAL.node = nil yyVAL.node = nil
} }
case 454: case 454:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2356 //line php7/php7.y:2361
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }
case 455: case 455:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2361 //line php7/php7.y:2366
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
} }
case 456: case 456:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2362 //line php7/php7.y:2367
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
} }
case 457: case 457:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2367 //line php7/php7.y:2372
{ {
yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node, false) yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[3].node, false)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[3].node))
@ -5458,7 +5462,7 @@ yydefault:
} }
case 458: case 458:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2373 //line php7/php7.y:2378
{ {
yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node, false) yyVAL.node = expr.NewArrayItem(nil, yyDollar[1].node, false)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodePosition(yyDollar[1].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodePosition(yyDollar[1].node))
@ -5466,7 +5470,7 @@ yydefault:
} }
case 459: case 459:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2379 //line php7/php7.y:2384
{ {
yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[4].node, true) yyVAL.node = expr.NewArrayItem(yyDollar[1].node, yyDollar[4].node, true)
positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[4].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewNodesPosition(yyDollar[1].node, yyDollar[4].node))
@ -5474,7 +5478,7 @@ yydefault:
} }
case 460: case 460:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2385 //line php7/php7.y:2390
{ {
yyVAL.node = expr.NewArrayItem(nil, yyDollar[2].node, true) yyVAL.node = expr.NewArrayItem(nil, yyDollar[2].node, true)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5482,7 +5486,7 @@ yydefault:
} }
case 461: case 461:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php7/php7.y:2391 //line php7/php7.y:2396
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList(yyDollar[5].list) list := expr.NewList(yyDollar[5].list)
@ -5495,7 +5499,7 @@ yydefault:
} }
case 462: case 462:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2402 //line php7/php7.y:2407
{ {
// TODO: Cannot use list() as standalone expression // TODO: Cannot use list() as standalone expression
list := expr.NewList(yyDollar[3].list) list := expr.NewList(yyDollar[3].list)
@ -5508,13 +5512,13 @@ yydefault:
} }
case 463: case 463:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2415 //line php7/php7.y:2420
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[2].node) yyVAL.list = append(yyDollar[1].list, yyDollar[2].node)
} }
case 464: case 464:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2417 //line php7/php7.y:2422
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[2].token.Value)
positions.AddPosition(encapsed, positionBuilder.NewTokenPosition(yyDollar[2].token)) positions.AddPosition(encapsed, positionBuilder.NewTokenPosition(yyDollar[2].token))
@ -5523,13 +5527,13 @@ yydefault:
} }
case 465: case 465:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2423 //line php7/php7.y:2428
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
} }
case 466: case 466:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2425 //line php7/php7.y:2430
{ {
encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value) encapsed := scalar.NewEncapsedStringPart(yyDollar[1].token.Value)
positions.AddPosition(encapsed, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(encapsed, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5538,7 +5542,7 @@ yydefault:
} }
case 467: case 467:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2435 //line php7/php7.y:2440
{ {
name := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$")) name := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$"))
positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5550,7 +5554,7 @@ yydefault:
} }
case 468: case 468:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2445 //line php7/php7.y:2450
{ {
identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$")) identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$"))
positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5565,7 +5569,7 @@ yydefault:
} }
case 469: case 469:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2458 //line php7/php7.y:2463
{ {
identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$")) identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$"))
positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5583,7 +5587,7 @@ yydefault:
} }
case 470: case 470:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2474 //line php7/php7.y:2479
{ {
yyVAL.node = expr.NewVariable(yyDollar[2].node) yyVAL.node = expr.NewVariable(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[3].token))
@ -5591,7 +5595,7 @@ yydefault:
} }
case 471: case 471:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2480 //line php7/php7.y:2485
{ {
name := node.NewIdentifier(yyDollar[2].token.Value) name := node.NewIdentifier(yyDollar[2].token.Value)
positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[2].token)) positions.AddPosition(name, positionBuilder.NewTokenPosition(yyDollar[2].token))
@ -5603,7 +5607,7 @@ yydefault:
} }
case 472: case 472:
yyDollar = yyS[yypt-6 : yypt+1] yyDollar = yyS[yypt-6 : yypt+1]
//line php7/php7.y:2490 //line php7/php7.y:2495
{ {
identifier := node.NewIdentifier(yyDollar[2].token.Value) identifier := node.NewIdentifier(yyDollar[2].token.Value)
positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[2].token)) positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[2].token))
@ -5618,13 +5622,13 @@ yydefault:
} }
case 473: case 473:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2503 //line php7/php7.y:2508
{ {
yyVAL.node = yyDollar[2].node yyVAL.node = yyDollar[2].node
} }
case 474: case 474:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2507 //line php7/php7.y:2512
{ {
yyVAL.node = scalar.NewString(yyDollar[1].token.Value) yyVAL.node = scalar.NewString(yyDollar[1].token.Value)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5632,7 +5636,7 @@ yydefault:
} }
case 475: case 475:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2513 //line php7/php7.y:2518
{ {
// TODO: add option to handle 64 bit integer // TODO: add option to handle 64 bit integer
if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil { if _, err := strconv.Atoi(yyDollar[1].token.Value); err == nil {
@ -5646,7 +5650,7 @@ yydefault:
} }
case 476: case 476:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2525 //line php7/php7.y:2530
{ {
// TODO: add option to handle 64 bit integer // TODO: add option to handle 64 bit integer
if _, err := strconv.Atoi(yyDollar[2].token.Value); err == nil { if _, err := strconv.Atoi(yyDollar[2].token.Value); err == nil {
@ -5666,7 +5670,7 @@ yydefault:
} }
case 477: case 477:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2543 //line php7/php7.y:2548
{ {
identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$")) identifier := node.NewIdentifier(strings.TrimLeft(yyDollar[1].token.Value, "$"))
positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token)) positions.AddPosition(identifier, positionBuilder.NewTokenPosition(yyDollar[1].token))
@ -5678,7 +5682,7 @@ yydefault:
} }
case 478: case 478:
yyDollar = yyS[yypt-5 : yypt+1] yyDollar = yyS[yypt-5 : yypt+1]
//line php7/php7.y:2556 //line php7/php7.y:2561
{ {
yyVAL.node = expr.NewIsset(yyDollar[3].list) yyVAL.node = expr.NewIsset(yyDollar[3].list)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[5].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[5].token))
@ -5686,7 +5690,7 @@ yydefault:
} }
case 479: case 479:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2562 //line php7/php7.y:2567
{ {
yyVAL.node = expr.NewEmpty(yyDollar[3].node) yyVAL.node = expr.NewEmpty(yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token))
@ -5694,7 +5698,7 @@ yydefault:
} }
case 480: case 480:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2568 //line php7/php7.y:2573
{ {
yyVAL.node = expr.NewInclude(yyDollar[2].node) yyVAL.node = expr.NewInclude(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5702,7 +5706,7 @@ yydefault:
} }
case 481: case 481:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2574 //line php7/php7.y:2579
{ {
yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node) yyVAL.node = expr.NewIncludeOnce(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5710,7 +5714,7 @@ yydefault:
} }
case 482: case 482:
yyDollar = yyS[yypt-4 : yypt+1] yyDollar = yyS[yypt-4 : yypt+1]
//line php7/php7.y:2580 //line php7/php7.y:2585
{ {
yyVAL.node = expr.NewEval(yyDollar[3].node) yyVAL.node = expr.NewEval(yyDollar[3].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokensPosition(yyDollar[1].token, yyDollar[4].token))
@ -5718,7 +5722,7 @@ yydefault:
} }
case 483: case 483:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2586 //line php7/php7.y:2591
{ {
yyVAL.node = expr.NewRequire(yyDollar[2].node) yyVAL.node = expr.NewRequire(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5726,7 +5730,7 @@ yydefault:
} }
case 484: case 484:
yyDollar = yyS[yypt-2 : yypt+1] yyDollar = yyS[yypt-2 : yypt+1]
//line php7/php7.y:2592 //line php7/php7.y:2597
{ {
yyVAL.node = expr.NewRequireOnce(yyDollar[2].node) yyVAL.node = expr.NewRequireOnce(yyDollar[2].node)
positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node)) positions.AddPosition(yyVAL.node, positionBuilder.NewTokenNodePosition(yyDollar[1].token, yyDollar[2].node))
@ -5734,19 +5738,19 @@ yydefault:
} }
case 485: case 485:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2600 //line php7/php7.y:2605
{ {
yyVAL.list = []node.Node{yyDollar[1].node} yyVAL.list = []node.Node{yyDollar[1].node}
} }
case 486: case 486:
yyDollar = yyS[yypt-3 : yypt+1] yyDollar = yyS[yypt-3 : yypt+1]
//line php7/php7.y:2601 //line php7/php7.y:2606
{ {
yyVAL.list = append(yyDollar[1].list, yyDollar[3].node) yyVAL.list = append(yyDollar[1].list, yyDollar[3].node)
} }
case 487: case 487:
yyDollar = yyS[yypt-1 : yypt+1] yyDollar = yyS[yypt-1 : yypt+1]
//line php7/php7.y:2605 //line php7/php7.y:2610
{ {
yyVAL.node = yyDollar[1].node yyVAL.node = yyDollar[1].node
} }

View File

@ -2124,13 +2124,17 @@ scalar:
} }
| T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC | T_START_HEREDOC T_ENCAPSED_AND_WHITESPACE T_END_HEREDOC
{ {
$$ = scalar.NewString($2.Value) encapsed := scalar.NewEncapsedStringPart($2.Value)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))/* TODO: mark as Heredoc*/ positions.AddPosition(encapsed, positionBuilder.NewTokenPosition($2))
comments.AddComments(encapsed, $2.Comments())
$$ = scalar.NewHeredoc($1.Value, []node.Node{encapsed})
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
| T_START_HEREDOC T_END_HEREDOC | T_START_HEREDOC T_END_HEREDOC
{ {
$$ = scalar.NewEncapsed(nil) $$ = scalar.NewHeredoc($1.Value, nil)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $2)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $2))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }
@ -2142,7 +2146,7 @@ scalar:
} }
| T_START_HEREDOC encaps_list T_END_HEREDOC | T_START_HEREDOC encaps_list T_END_HEREDOC
{ {
$$ = scalar.NewEncapsed($2) $$ = scalar.NewHeredoc($1.Value, $2)
positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3)) positions.AddPosition($$, positionBuilder.NewTokensPosition($1, $3))
comments.AddComments($$, $1.Comments()) comments.AddComments($$, $1.Comments())
} }

View File

@ -54,30 +54,6 @@ func TestPhp7(t *testing.T) {
function(?bar $bar=null, baz &...$baz) {}; function(?bar $bar=null, baz &...$baz) {};
static function(?bar $bar=null, baz &...$baz) {}; static function(?bar $bar=null, baz &...$baz) {};
"test";
"\$test";
"
test
";
'$test';
'
$test
';
<<<CAD
CAD;
<<<CAD
hello
CAD;
<<<"CAD"
hello
CAD;
<<<"CAD"
hello $world
CAD;
<<<'CAD'
hello $world
CAD;
1234567890123456789; 1234567890123456789;
12345678901234567890; 12345678901234567890;
0.; 0.;
@ -578,42 +554,6 @@ CAD;
Stmts: []node.Node{}, Stmts: []node.Node{},
}, },
}, },
&stmt.Expression{
Expr: &scalar.String{Value: "\"test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\\$test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\n\t\t\ttest\n\t\t\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'$test'"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'\n\t\t\t$test\n\t\t'"},
},
&stmt.Expression{
Expr: &scalar.Encapsed{},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello\n"},
},
&stmt.Expression{
Expr: &scalar.Encapsed{
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello "},
&expr.Variable{VarName: &node.Identifier{Value: "world"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\thello $world\n"},
},
&stmt.Expression{ &stmt.Expression{
Expr: &scalar.Lnumber{Value: "1234567890123456789"}, Expr: &scalar.Lnumber{Value: "1234567890123456789"},
}, },
@ -3229,3 +3169,106 @@ CAD;
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php") actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual) assertEqual(t, expected, actual)
} }
func TestPhp5Strings(t *testing.T) {
src := `<?
"test";
"\$test";
"
test
";
'$test';
'
$test
';
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.String{Value: "\"test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\\$test\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "\"\n\t\t\ttest\n\t\t\""},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'$test'"},
},
&stmt.Expression{
Expr: &scalar.String{Value: "'\n\t\t\t$test\n\t\t'"},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}
func TestPhp5Heredoc(t *testing.T) {
src := `<?
<<<CAD
CAD;
<<<CAD
hello
CAD;
<<<"CAD"
hello
CAD;
<<<"CAD"
hello $world
CAD;
<<<'CAD'
hello $world
CAD;
`
expected := &stmt.StmtList{
Stmts: []node.Node{
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "CAD",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "\"CAD\"",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "\"CAD\"",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello "},
&expr.Variable{VarName: &node.Identifier{Value: "world"}},
&scalar.EncapsedStringPart{Value: "\n"},
},
},
},
&stmt.Expression{
Expr: &scalar.Heredoc{
Label: "'CAD'",
Parts: []node.Node{
&scalar.EncapsedStringPart{Value: "\thello $world\n"},
},
},
},
},
}
actual, _, _ := php7.Parse(bytes.NewBufferString(src), "test.php")
assertEqual(t, expected, actual)
}

View File

@ -8481,6 +8481,8 @@ yyrule141: // [b]?\<\<\<[ \t]*({VAR_NAME}|([']{VAR_NAME}['])|(["]{VAR_NAME}["]))
} }
break break
} }
heredocToken := make([]lex.Char, lblLast-lblFirst+1)
copy(heredocToken, tb[lblFirst:lblLast+1])
switch tb[lblFirst].Rune { switch tb[lblFirst].Rune {
case '\'': case '\'':
lblFirst++ lblFirst++
@ -8513,7 +8515,7 @@ yyrule141: // [b]?\<\<\<[ \t]*({VAR_NAME}|([']{VAR_NAME}['])|(["]{VAR_NAME}["]))
} }
} }
l.ungetChars(ungetCnt) l.ungetChars(ungetCnt)
lval.Token(l.newToken(tb)) lval.Token(l.newToken(heredocToken))
return T_START_HEREDOC return T_START_HEREDOC
} }
yyrule142: // .|[ \t\n\r] yyrule142: // .|[ \t\n\r]

View File

@ -366,6 +366,9 @@ NEW_LINE (\r|\n|\r\n)
break break
} }
heredocToken := make([]lex.Char, lblLast - lblFirst + 1)
copy(heredocToken, tb[lblFirst:lblLast+1])
switch tb[lblFirst].Rune { switch tb[lblFirst].Rune {
case '\'' : case '\'' :
lblFirst++ lblFirst++
@ -402,7 +405,7 @@ NEW_LINE (\r|\n|\r\n)
l.ungetChars(ungetCnt) l.ungetChars(ungetCnt)
lval.Token(l.newToken(tb)); lval.Token(l.newToken(heredocToken));
return T_START_HEREDOC return T_START_HEREDOC
<NOWDOC>.|[ \t\n\r] <NOWDOC>.|[ \t\n\r]