[refactoring] parameters: new node structure

This commit is contained in:
Vadym Slizov 2020-07-05 22:47:46 +03:00
parent b5e29fc9f5
commit ce18c23597
22 changed files with 9359 additions and 9160 deletions

View File

@ -849,7 +849,7 @@ func TestPhp5ArgumentNode(t *testing.T) {
}
func TestPhp5ParameterNode(t *testing.T) {
src := `<?
src := `<?
function foo(bar $bar=null, baz &...$baz) {}
class foo {public function foo(bar $bar=null, baz &...$baz) {}}
function(bar $bar=null, baz &...$baz) {};
@ -861,8 +861,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 5,
StartPos: 6,
EndPos: 211,
StartPos: 5,
EndPos: 210,
},
},
Stmts: []ast.Vertex{
@ -871,18 +871,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 6,
EndPos: 50,
StartPos: 5,
EndPos: 49,
},
},
ReturnsRef: false,
FunctionName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 15,
EndPos: 18,
StartPos: 14,
EndPos: 17,
},
},
Value: []byte("foo"),
@ -893,19 +892,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 19,
EndPos: 32,
StartPos: 18,
EndPos: 31,
},
},
ByRef: false,
Variadic: false,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 19,
EndPos: 22,
StartPos: 18,
EndPos: 21,
},
},
Parts: []ast.Vertex{
@ -914,8 +911,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 19,
EndPos: 22,
StartPos: 18,
EndPos: 21,
},
},
Value: []byte("bar"),
@ -927,8 +924,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 23,
EndPos: 27,
StartPos: 22,
EndPos: 26,
},
},
VarName: &ast.Identifier{
@ -936,8 +933,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 23,
EndPos: 27,
StartPos: 22,
EndPos: 26,
},
},
Value: []byte("$bar"),
@ -948,8 +945,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 28,
EndPos: 32,
StartPos: 27,
EndPos: 31,
},
},
Const: &ast.NameName{
@ -957,8 +954,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 28,
EndPos: 32,
StartPos: 27,
EndPos: 31,
},
},
Parts: []ast.Vertex{
@ -967,8 +964,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 28,
EndPos: 32,
StartPos: 27,
EndPos: 31,
},
},
Value: []byte("null"),
@ -982,19 +979,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 34,
EndPos: 46,
StartPos: 33,
EndPos: 45,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 34,
EndPos: 37,
StartPos: 33,
EndPos: 36,
},
},
Parts: []ast.Vertex{
@ -1003,46 +998,67 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 34,
EndPos: 37,
StartPos: 33,
EndPos: 36,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 42,
EndPos: 46,
StartPos: 37,
EndPos: 45,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 42,
EndPos: 46,
StartPos: 38,
EndPos: 45,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 41,
EndPos: 45,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 41,
EndPos: 45,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
&ast.StmtClass{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 53,
EndPos: 116,
StartPos: 52,
EndPos: 115,
},
},
ClassName: &ast.Identifier{
@ -1050,8 +1066,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 59,
EndPos: 62,
StartPos: 58,
EndPos: 61,
},
},
Value: []byte("foo"),
@ -1062,18 +1078,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 64,
EndPos: 115,
StartPos: 63,
EndPos: 114,
},
},
ReturnsRef: false,
MethodName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 80,
EndPos: 83,
StartPos: 79,
EndPos: 82,
},
},
Value: []byte("foo"),
@ -1084,8 +1099,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 64,
EndPos: 70,
StartPos: 63,
EndPos: 69,
},
},
Value: []byte("public"),
@ -1097,19 +1112,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 84,
EndPos: 97,
StartPos: 83,
EndPos: 96,
},
},
ByRef: false,
Variadic: false,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 84,
EndPos: 87,
StartPos: 83,
EndPos: 86,
},
},
Parts: []ast.Vertex{
@ -1118,8 +1131,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 84,
EndPos: 87,
StartPos: 83,
EndPos: 86,
},
},
Value: []byte("bar"),
@ -1131,8 +1144,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 88,
EndPos: 92,
StartPos: 87,
EndPos: 91,
},
},
VarName: &ast.Identifier{
@ -1140,8 +1153,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 88,
EndPos: 92,
StartPos: 87,
EndPos: 91,
},
},
Value: []byte("$bar"),
@ -1152,8 +1165,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 93,
EndPos: 97,
StartPos: 92,
EndPos: 96,
},
},
Const: &ast.NameName{
@ -1161,8 +1174,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 93,
EndPos: 97,
StartPos: 92,
EndPos: 96,
},
},
Parts: []ast.Vertex{
@ -1171,8 +1184,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 93,
EndPos: 97,
StartPos: 92,
EndPos: 96,
},
},
Value: []byte("null"),
@ -1186,19 +1199,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 99,
EndPos: 111,
StartPos: 98,
EndPos: 110,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 99,
EndPos: 102,
StartPos: 98,
EndPos: 101,
},
},
Parts: []ast.Vertex{
@ -1207,33 +1218,53 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 99,
EndPos: 102,
StartPos: 98,
EndPos: 101,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 107,
EndPos: 111,
StartPos: 102,
EndPos: 110,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 107,
EndPos: 111,
StartPos: 103,
EndPos: 110,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 106,
EndPos: 110,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 106,
EndPos: 110,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
@ -1243,11 +1274,12 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 113,
EndPos: 115,
StartPos: 112,
EndPos: 114,
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
},
@ -1257,8 +1289,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 119,
EndPos: 160,
StartPos: 118,
EndPos: 159,
},
},
Expr: &ast.ExprClosure{
@ -1266,31 +1298,27 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 119,
EndPos: 159,
StartPos: 118,
EndPos: 158,
},
},
ReturnsRef: false,
Static: false,
Params: []ast.Vertex{
&ast.Parameter{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 128,
EndPos: 141,
StartPos: 127,
EndPos: 140,
},
},
Variadic: false,
ByRef: false,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 128,
EndPos: 131,
StartPos: 127,
EndPos: 130,
},
},
Parts: []ast.Vertex{
@ -1299,8 +1327,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 128,
EndPos: 131,
StartPos: 127,
EndPos: 130,
},
},
Value: []byte("bar"),
@ -1312,8 +1340,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 132,
EndPos: 136,
StartPos: 131,
EndPos: 135,
},
},
VarName: &ast.Identifier{
@ -1321,8 +1349,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 132,
EndPos: 136,
StartPos: 131,
EndPos: 135,
},
},
Value: []byte("$bar"),
@ -1333,8 +1361,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 137,
EndPos: 141,
StartPos: 136,
EndPos: 140,
},
},
Const: &ast.NameName{
@ -1342,8 +1370,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 137,
EndPos: 141,
StartPos: 136,
EndPos: 140,
},
},
Parts: []ast.Vertex{
@ -1352,8 +1380,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 137,
EndPos: 141,
StartPos: 136,
EndPos: 140,
},
},
Value: []byte("null"),
@ -1367,19 +1395,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 143,
EndPos: 155,
StartPos: 142,
EndPos: 154,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 143,
EndPos: 146,
StartPos: 142,
EndPos: 145,
},
},
Parts: []ast.Vertex{
@ -1388,38 +1414,59 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 143,
EndPos: 146,
StartPos: 142,
EndPos: 145,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 151,
EndPos: 155,
StartPos: 146,
EndPos: 154,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 151,
EndPos: 155,
StartPos: 147,
EndPos: 154,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 150,
EndPos: 154,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 150,
EndPos: 154,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
&ast.StmtExpression{
@ -1427,8 +1474,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 163,
EndPos: 211,
StartPos: 162,
EndPos: 210,
},
},
Expr: &ast.ExprClosure{
@ -1436,31 +1483,28 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 163,
EndPos: 210,
StartPos: 162,
EndPos: 209,
},
},
ReturnsRef: false,
Static: true,
Static: true,
Params: []ast.Vertex{
&ast.Parameter{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 179,
EndPos: 192,
StartPos: 178,
EndPos: 191,
},
},
ByRef: false,
Variadic: false,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 179,
EndPos: 182,
StartPos: 178,
EndPos: 181,
},
},
Parts: []ast.Vertex{
@ -1469,8 +1513,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 179,
EndPos: 182,
StartPos: 178,
EndPos: 181,
},
},
Value: []byte("bar"),
@ -1482,8 +1526,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 183,
EndPos: 187,
StartPos: 182,
EndPos: 186,
},
},
VarName: &ast.Identifier{
@ -1491,8 +1535,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 183,
EndPos: 187,
StartPos: 182,
EndPos: 186,
},
},
Value: []byte("$bar"),
@ -1503,8 +1547,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 188,
EndPos: 192,
StartPos: 187,
EndPos: 191,
},
},
Const: &ast.NameName{
@ -1512,8 +1556,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 188,
EndPos: 192,
StartPos: 187,
EndPos: 191,
},
},
Parts: []ast.Vertex{
@ -1522,8 +1566,8 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 188,
EndPos: 192,
StartPos: 187,
EndPos: 191,
},
},
Value: []byte("null"),
@ -1537,19 +1581,17 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 194,
EndPos: 206,
StartPos: 193,
EndPos: 205,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 194,
EndPos: 197,
StartPos: 193,
EndPos: 196,
},
},
Parts: []ast.Vertex{
@ -1558,43 +1600,65 @@ func TestPhp5ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 194,
EndPos: 197,
StartPos: 193,
EndPos: 196,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 202,
EndPos: 206,
StartPos: 197,
EndPos: 205,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 202,
EndPos: 206,
StartPos: 198,
EndPos: 205,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 201,
EndPos: 205,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 201,
EndPos: 205,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
},
}
lexer := scanner.NewLexer([]byte(src), "5.6", false, nil)
php5parser := php5.NewParser(lexer, nil)
php5parser.Parse()
@ -6906,8 +6970,6 @@ func TestStmtFunction_ReturnVar(t *testing.T) {
EndPos: 24,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
@ -6950,8 +7012,6 @@ func TestStmtFunction_ReturnVar(t *testing.T) {
EndPos: 37,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
@ -13403,8 +13463,6 @@ func TestExprClosure_Use(t *testing.T) {
EndPos: 14,
},
},
Variadic: false,
ByRef: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -13436,8 +13494,6 @@ func TestExprClosure_Use(t *testing.T) {
EndPos: 18,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -13581,8 +13637,6 @@ func TestExprClosure_Use2(t *testing.T) {
EndPos: 14,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -13614,8 +13668,6 @@ func TestExprClosure_Use2(t *testing.T) {
EndPos: 18,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{

BIN
internal/php5/php5.go generated

Binary file not shown.

View File

@ -2283,12 +2283,27 @@ parameter:
optional_class_type is_reference is_variadic T_VARIABLE
{
identifier := &ast.Identifier{ast.Node{}, $4.Value}
variable := &ast.ExprVariable{ast.Node{}, identifier}
$$ = &ast.Parameter{ast.Node{}, $2 != nil, $3 != nil, $1, variable, nil}
// save position
identifier.GetNode().Position = position.NewTokenPosition($4)
var variable ast.Vertex
variable = &ast.ExprVariable{ast.Node{}, identifier}
variable.GetNode().Position = position.NewTokenPosition($4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $4.Tokens)
if $3 != nil {
variable = &ast.Variadic{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($3, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $3.Tokens)
}
if $2 != nil {
variable = &ast.Reference{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($2, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $2.Tokens)
}
$$ = &ast.Parameter{ast.Node{}, $1, variable, nil}
if $1 != nil {
$$.GetNode().Position = position.NewNodeTokenPosition($1, $4)
} else if $2 != nil {
@ -2299,40 +2314,33 @@ parameter:
$$.GetNode().Position = position.NewTokenPosition($4)
}
// save comments
if $1 != nil {
yylex.(*Parser).MoveFreeFloating($1, $$)
}
if $2 != nil {
yylex.(*Parser).setFreeFloating($$, token.OptionalType, $2.Tokens)
}
if $3 != nil {
yylex.(*Parser).setFreeFloating($$, token.Ampersand, $3.Tokens)
}
yylex.(*Parser).setFreeFloating($$, token.Variadic, $4.Tokens)
// normalize
if $3 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Ampersand, $$.GetNode().Tokens[token.Variadic]); delete($$.GetNode().Tokens, token.Variadic)
}
if $2 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.OptionalType, $$.GetNode().Tokens[token.Ampersand]); delete($$.GetNode().Tokens, token.Ampersand)
}
if $1 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Start, $$.GetNode().Tokens[token.OptionalType]); delete($$.GetNode().Tokens, token.OptionalType)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
}
| optional_class_type is_reference is_variadic T_VARIABLE '=' static_scalar
{
identifier := &ast.Identifier{ast.Node{}, $4.Value}
variable := &ast.ExprVariable{ast.Node{}, identifier}
$$ = &ast.Parameter{ast.Node{}, $2 != nil, $3 != nil, $1, variable, $6}
// save position
identifier.GetNode().Position = position.NewTokenPosition($4)
var variable ast.Vertex
variable = &ast.ExprVariable{ast.Node{}, identifier}
variable.GetNode().Position = position.NewTokenPosition($4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $4.Tokens)
yylex.(*Parser).setFreeFloating(variable, token.End, $5.Tokens)
if $3 != nil {
variable = &ast.Variadic{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($3, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $3.Tokens)
}
if $2 != nil {
variable = &ast.Reference{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($2, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $2.Tokens)
}
$$ = &ast.Parameter{ast.Node{}, $1, variable, $6}
if $1 != nil {
$$.GetNode().Position = position.NewNodesPosition($1, $6)
} else if $2 != nil {
@ -2343,30 +2351,6 @@ parameter:
$$.GetNode().Position = position.NewTokenNodePosition($4, $6)
}
// save comments
if $1 != nil {
yylex.(*Parser).MoveFreeFloating($1, $$)
}
if $2 != nil {
yylex.(*Parser).setFreeFloating($$, token.OptionalType, $2.Tokens)
}
if $3 != nil {
yylex.(*Parser).setFreeFloating($$, token.Ampersand, $3.Tokens)
}
yylex.(*Parser).setFreeFloating($$, token.Variadic, $4.Tokens)
yylex.(*Parser).setFreeFloating($$, token.Var, $5.Tokens)
// normalize
if $3 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Ampersand, $$.GetNode().Tokens[token.Variadic]); delete($$.GetNode().Tokens, token.Variadic)
}
if $2 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.OptionalType, $$.GetNode().Tokens[token.Ampersand]); delete($$.GetNode().Tokens, token.Ampersand)
}
if $1 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Start, $$.GetNode().Tokens[token.OptionalType]); delete($$.GetNode().Tokens, token.OptionalType)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
}
;

File diff suppressed because it is too large Load Diff

381
internal/php5/test.php Normal file
View File

@ -0,0 +1,381 @@
<?
foo($a, ...$b);
$foo($a, ...$b);
$foo->bar($a, ...$b);
foo::bar($a, ...$b);
$foo::bar($a, ...$b);
new foo($a, ...$b);
function foo(bar $bar=null, baz &...$baz) {}
class foo {public function foo(bar $bar=null, baz &...$baz) {}}
function(bar $bar=null, baz &...$baz) {};
static function(bar $bar=null, baz &...$baz) {};
1234567890123456789;
12345678901234567890;
0.;
0b0111111111111111111111111111111111111111111111111111111111111111;
0b1111111111111111111111111111111111111111111111111111111111111111;
0x007111111111111111;
0x8111111111111111;
__CLASS__;
__DIR__;
__FILE__;
__FUNCTION__;
__LINE__;
__NAMESPACE__;
__METHOD__;
__TRAIT__;
"test $var";
"test $var[1]";
"test $var[1234567890123456789012345678901234567890]";
"test $var[bar]";
"test $var[$bar]";
"$foo $bar";
"test $foo->bar()";
"test ${foo}";
"test ${foo[0]}";
"test {$foo->bar()}";
if ($a) :
endif;
if ($a) :
elseif ($b):
endif;
if ($a) :
else:
endif;
if ($a) :
elseif ($b):
elseif ($c):
else:
endif;
while (1) { break; }
while (1) { break 2; }
while (1) : break(3); endwhile;
class foo{ const FOO = 1, BAR = 2; }
class foo{ function bar() {} }
class foo{ public static function &bar() {} }
class foo{ final private function bar() {} protected function baz() {} }
abstract class foo{ abstract public function bar(); }
final class foo extends bar { }
final class foo implements bar { }
final class foo implements bar, baz { }
const FOO = 1, BAR = 2;
while (1) { continue; }
while (1) { continue 2; }
while (1) { continue(3); }
declare(ticks=1);
declare(ticks=1, strict_types=1) {}
declare(ticks=1): enddeclare;
do {} while(1);
echo $a, 1;
echo($a);
for($i = 0; $i < 10; $i++, $i++) {}
for(; $i < 10; $i++) : endfor;
foreach ($a as $v) {}
foreach ([] as $v) {}
foreach ($a as $v) : endforeach;
foreach ($a as $k => $v) {}
foreach ([] as $k => $v) {}
foreach ($a as $k => &$v) {}
foreach ($a as $k => list($v)) {}
function foo() {}
function foo() {
function bar() {}
class Baz {}
return $a;
}
function foo(array $a, callable $b) {return;}
function &foo() {return 1;}
function &foo() {}
global $a, $b, $$c, ${foo()};
a:
goto a;
if ($a) {}
if ($a) {} elseif ($b) {}
if ($a) {} else {}
if ($a) {} elseif ($b) {} elseif ($c) {} else {}
if ($a) {} elseif ($b) {} else if ($c) {} else {}
?> <div></div> <?
interface Foo {}
interface Foo extends Bar {}
interface Foo extends Bar, Baz {}
namespace Foo;
namespace Foo\Bar {}
namespace {}
class foo {var $a;}
class foo {public static $a, $b = 1;}
class foo {public static $a = 1, $b;}
static $a, $b = 1;
static $a = 1, $b;
switch (1) :
case 1:
default:
case 2:
endswitch;
switch (1) :;
case 1;
case 2;
endswitch;
switch (1) {
case 1: break;
case 2: break;
}
switch (1) {;
case 1; break;
case 2; break;
}
throw $e;
trait Foo {}
class Foo { use Bar; }
class Foo { use Bar, Baz {} }
class Foo { use Bar, Baz { one as public; } }
class Foo { use Bar, Baz { one as public two; } }
class Foo { use Bar, Baz { Bar::one insteadof Baz, Quux; Baz::one as two; } }
try {}
try {} catch (Exception $e) {}
try {} catch (Exception $e) {} catch (RuntimeException $e) {}
try {} catch (Exception $e) {} catch (\RuntimeException $e) {} catch (namespace\AdditionException $e) {}
try {} catch (Exception $e) {} finally {}
unset($a, $b);
use Foo;
use \Foo;
use \Foo as Bar;
use Foo, Bar;
use Foo, Bar as Baz;
use function Foo, \Bar;
use function Foo as foo, \Bar as bar;
use const Foo, \Bar;
use const Foo as foo, \Bar as bar;
$a[1];
$a[1][2];
array();
array(1);
array(1=>1, &$b,);
array(3 =>&$b);
array(&$b, 1=>1, 1, 3 =>&$b);
~$a;
!$a;
Foo::Bar;
clone($a);
clone $a;
function(){};
function($a, $b) use ($c, &$d) {};
function($a, $b) use (&$c, $d) {};
function() {};
foo;
namespace\foo;
\foo;
empty($a);
empty(Foo);
@$a;
eval($a);
exit;
exit($a);
die();
die($a);
foo();
namespace\foo(&$a);
\foo([]);
$foo(yield $a);
$a--;
$a++;
--$a;
++$a;
include $a;
include_once $a;
require $a;
require_once $a;
$a instanceof Foo;
$a instanceof namespace\Foo;
$a instanceof \Foo;
isset($a, $b);
isset(Foo);
list() = $b;
list($a, $b) = $b;
list($a[]) = $b;
list(list($a)) = $b;
$a->foo();
new Foo;
new namespace\Foo();
new \Foo();
print($a);
$a->foo;
$a->foo[1];
$a->foo->bar->baz()->quux[0];
$a->foo()[1][1];
`cmd $a`;
`cmd`;
``;
[];
[1];
[1=>1, &$b,];
Foo::bar();
namespace\Foo::bar();
\Foo::bar();
Foo::$bar();
$foo::$bar();
Foo::$bar;
namespace\Foo::$bar;
\Foo::$bar;
$a ? $b : $c;
$a ? : $c;
$a ? $b ? $c : $d : $e;
$a ? $b : $c ? $d : $e;
-$a;
+$a;
$$a;
$$$a;
yield;
yield $a;
yield $a => $b;
yield Foo::class;
yield $a => Foo::class;
(array)$a;
(boolean)$a;
(bool)$a;
(double)$a;
(float)$a;
(integer)$a;
(int)$a;
(object)$a;
(string)$a;
(unset)$a;
$a & $b;
$a | $b;
$a ^ $b;
$a && $b;
$a || $b;
$a . $b;
$a / $b;
$a == $b;
$a >= $b;
$a > $b;
$a === $b;
$a and $b;
$a or $b;
$a xor $b;
$a - $b;
$a % $b;
$a * $b;
$a != $b;
$a !== $b;
$a + $b;
$a ** $b;
$a << $b;
$a >> $b;
$a <= $b;
$a < $b;
$a =& $b;
$a =& new Foo;
$a =& new Foo($b);
$a = $b;
$a &= $b;
$a |= $b;
$a ^= $b;
$a .= $b;
$a /= $b;
$a -= $b;
$a %= $b;
$a *= $b;
$a += $b;
$a **= $b;
$a <<= $b;
$a >>= $b;
(new \Foo());
(new \Foo())->bar()->baz;
(new \Foo())[0][0];
(new \Foo())[0]->bar();
array([0])[0][0];
"foo"[0];
foo[0];
static::foo;
new $foo;
new $foo::$bar;
new $a->b[0];
new $a->b{$b ?: null}->$c->d[0];static $a = [1][0];
static $a = !1;
static $a = ~1;
static $a = +1;
static $a = -1;
static $a = (1);
static $a = 1 ?: 2;
static $a = 1 ? 2 : 3;
static $a = 1 & 2;
static $a = 1 | 2;
static $a = 1 ^ 2;
static $a = 1 && 2;
static $a = 1 || 2;
static $a = 1 . 2;
static $a = 1 / 2;
static $a = 1 == 2;
static $a = 1 >= 2;
static $a = 1 > 2;
static $a = 1 === 2;
static $a = 1 and 2;
static $a = 1 or 2;
static $a = 1 xor 2;
static $a = 1 - 2;
static $a = 1 % 2;
static $a = 1 * 2;
static $a = 1 != 2;
static $a = 1 !== 2;
static $a = 1 + 2;
static $a = 1 ** 2;
static $a = 1 << 2;
static $a = 1 >> 2;
static $a = 1 <= 2;
static $a = 1 < 2;
static $a = Foo::bar;
static $a = Foo::class;
static $a = __CLASS__;
static $a = Foo;
static $a = namespace\Foo;
static $a = \Foo;
static $a = array();
static $a = array(1 => 1, 2);
static $a = [1, 2 => 2][0];
if (yield 1) {}
Foo::$$bar;
$foo();
$foo()[0][0];
$a{$b};
${$a};
$foo::{$bar}();
$foo::bar;
__halt_compiler();
parsing process must be terminated

View File

@ -960,7 +960,7 @@ func TestPhp7ArgumentNode(t *testing.T) {
}
func TestPhp7ParameterNode(t *testing.T) {
src := `<?
src := `<?
function foo(?bar $bar=null, baz &...$baz) {}
class foo {public function foo(?bar $bar=null, baz &...$baz) {}}
function(?bar $bar=null, baz &...$baz) {};
@ -972,8 +972,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 5,
StartPos: 6,
EndPos: 215,
StartPos: 5,
EndPos: 214,
},
},
Stmts: []ast.Vertex{
@ -982,18 +982,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 6,
EndPos: 51,
StartPos: 5,
EndPos: 50,
},
},
ReturnsRef: false,
FunctionName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 15,
EndPos: 18,
StartPos: 14,
EndPos: 17,
},
},
Value: []byte("foo"),
@ -1004,19 +1003,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 19,
EndPos: 33,
StartPos: 18,
EndPos: 32,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Nullable{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 19,
EndPos: 23,
StartPos: 18,
EndPos: 22,
},
},
Expr: &ast.NameName{
@ -1024,8 +1021,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 20,
EndPos: 23,
StartPos: 19,
EndPos: 22,
},
},
Parts: []ast.Vertex{
@ -1034,8 +1031,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 20,
EndPos: 23,
StartPos: 19,
EndPos: 22,
},
},
Value: []byte("bar"),
@ -1048,8 +1045,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 24,
EndPos: 28,
StartPos: 23,
EndPos: 27,
},
},
VarName: &ast.Identifier{
@ -1057,8 +1054,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 24,
EndPos: 28,
StartPos: 23,
EndPos: 27,
},
},
Value: []byte("$bar"),
@ -1069,8 +1066,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 29,
EndPos: 33,
StartPos: 28,
EndPos: 32,
},
},
Const: &ast.NameName{
@ -1078,8 +1075,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 29,
EndPos: 33,
StartPos: 28,
EndPos: 32,
},
},
Parts: []ast.Vertex{
@ -1088,8 +1085,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 29,
EndPos: 33,
StartPos: 28,
EndPos: 32,
},
},
Value: []byte("null"),
@ -1103,19 +1100,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 35,
EndPos: 47,
StartPos: 34,
EndPos: 46,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 35,
EndPos: 38,
StartPos: 34,
EndPos: 37,
},
},
Parts: []ast.Vertex{
@ -1124,46 +1119,67 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 35,
EndPos: 38,
StartPos: 34,
EndPos: 37,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 43,
EndPos: 47,
StartPos: 38,
EndPos: 46,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 43,
EndPos: 47,
StartPos: 39,
EndPos: 46,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 42,
EndPos: 46,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 2,
EndLine: 2,
StartPos: 42,
EndPos: 46,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
&ast.StmtClass{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 54,
EndPos: 118,
StartPos: 53,
EndPos: 117,
},
},
ClassName: &ast.Identifier{
@ -1171,8 +1187,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 60,
EndPos: 63,
StartPos: 59,
EndPos: 62,
},
},
Value: []byte("foo"),
@ -1183,18 +1199,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 65,
EndPos: 117,
StartPos: 64,
EndPos: 116,
},
},
ReturnsRef: false,
MethodName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 81,
EndPos: 84,
StartPos: 80,
EndPos: 83,
},
},
Value: []byte("foo"),
@ -1205,8 +1220,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 65,
EndPos: 71,
StartPos: 64,
EndPos: 70,
},
},
Value: []byte("public"),
@ -1218,19 +1233,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 85,
EndPos: 99,
StartPos: 84,
EndPos: 98,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Nullable{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 85,
EndPos: 89,
StartPos: 84,
EndPos: 88,
},
},
Expr: &ast.NameName{
@ -1238,8 +1251,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 86,
EndPos: 89,
StartPos: 85,
EndPos: 88,
},
},
Parts: []ast.Vertex{
@ -1248,8 +1261,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 86,
EndPos: 89,
StartPos: 85,
EndPos: 88,
},
},
Value: []byte("bar"),
@ -1262,8 +1275,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 90,
EndPos: 94,
StartPos: 89,
EndPos: 93,
},
},
VarName: &ast.Identifier{
@ -1271,8 +1284,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 90,
EndPos: 94,
StartPos: 89,
EndPos: 93,
},
},
Value: []byte("$bar"),
@ -1283,8 +1296,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 95,
EndPos: 99,
StartPos: 94,
EndPos: 98,
},
},
Const: &ast.NameName{
@ -1292,8 +1305,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 95,
EndPos: 99,
StartPos: 94,
EndPos: 98,
},
},
Parts: []ast.Vertex{
@ -1302,8 +1315,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 95,
EndPos: 99,
StartPos: 94,
EndPos: 98,
},
},
Value: []byte("null"),
@ -1317,19 +1330,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 101,
EndPos: 113,
StartPos: 100,
EndPos: 112,
},
},
ByRef: true,
Variadic: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 101,
EndPos: 104,
StartPos: 100,
EndPos: 103,
},
},
Parts: []ast.Vertex{
@ -1338,33 +1349,53 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 101,
EndPos: 104,
StartPos: 100,
EndPos: 103,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 109,
EndPos: 113,
StartPos: 104,
EndPos: 112,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 109,
EndPos: 113,
StartPos: 105,
EndPos: 112,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 108,
EndPos: 112,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 108,
EndPos: 112,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
@ -1374,11 +1405,12 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 3,
EndLine: 3,
StartPos: 115,
EndPos: 117,
StartPos: 114,
EndPos: 116,
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
},
@ -1388,8 +1420,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 121,
EndPos: 163,
StartPos: 120,
EndPos: 162,
},
},
Expr: &ast.ExprClosure{
@ -1397,31 +1429,27 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 121,
EndPos: 162,
StartPos: 120,
EndPos: 161,
},
},
ReturnsRef: false,
Static: false,
Params: []ast.Vertex{
&ast.Parameter{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 130,
EndPos: 144,
StartPos: 129,
EndPos: 143,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Nullable{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 130,
EndPos: 134,
StartPos: 129,
EndPos: 133,
},
},
Expr: &ast.NameName{
@ -1429,8 +1457,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 131,
EndPos: 134,
StartPos: 130,
EndPos: 133,
},
},
Parts: []ast.Vertex{
@ -1439,8 +1467,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 131,
EndPos: 134,
StartPos: 130,
EndPos: 133,
},
},
Value: []byte("bar"),
@ -1453,8 +1481,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 135,
EndPos: 139,
StartPos: 134,
EndPos: 138,
},
},
VarName: &ast.Identifier{
@ -1462,8 +1490,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 135,
EndPos: 139,
StartPos: 134,
EndPos: 138,
},
},
Value: []byte("$bar"),
@ -1474,8 +1502,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 140,
EndPos: 144,
StartPos: 139,
EndPos: 143,
},
},
Const: &ast.NameName{
@ -1483,8 +1511,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 140,
EndPos: 144,
StartPos: 139,
EndPos: 143,
},
},
Parts: []ast.Vertex{
@ -1493,8 +1521,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 140,
EndPos: 144,
StartPos: 139,
EndPos: 143,
},
},
Value: []byte("null"),
@ -1508,19 +1536,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 146,
EndPos: 158,
StartPos: 145,
EndPos: 157,
},
},
Variadic: true,
ByRef: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 146,
EndPos: 149,
StartPos: 145,
EndPos: 148,
},
},
Parts: []ast.Vertex{
@ -1529,38 +1555,59 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 146,
EndPos: 149,
StartPos: 145,
EndPos: 148,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 154,
EndPos: 158,
StartPos: 149,
EndPos: 157,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 154,
EndPos: 158,
StartPos: 150,
EndPos: 157,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 153,
EndPos: 157,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 4,
EndLine: 4,
StartPos: 153,
EndPos: 157,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
&ast.StmtExpression{
@ -1568,8 +1615,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 166,
EndPos: 215,
StartPos: 165,
EndPos: 214,
},
},
Expr: &ast.ExprClosure{
@ -1577,31 +1624,28 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 166,
EndPos: 214,
StartPos: 165,
EndPos: 213,
},
},
Static: true,
ReturnsRef: false,
Static: true,
Params: []ast.Vertex{
&ast.Parameter{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 182,
EndPos: 196,
StartPos: 181,
EndPos: 195,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Nullable{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 182,
EndPos: 186,
StartPos: 181,
EndPos: 185,
},
},
Expr: &ast.NameName{
@ -1609,8 +1653,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 183,
EndPos: 186,
StartPos: 182,
EndPos: 185,
},
},
Parts: []ast.Vertex{
@ -1619,8 +1663,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 183,
EndPos: 186,
StartPos: 182,
EndPos: 185,
},
},
Value: []byte("bar"),
@ -1633,8 +1677,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 187,
EndPos: 191,
StartPos: 186,
EndPos: 190,
},
},
VarName: &ast.Identifier{
@ -1642,8 +1686,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 187,
EndPos: 191,
StartPos: 186,
EndPos: 190,
},
},
Value: []byte("$bar"),
@ -1654,8 +1698,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 192,
EndPos: 196,
StartPos: 191,
EndPos: 195,
},
},
Const: &ast.NameName{
@ -1663,8 +1707,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 192,
EndPos: 196,
StartPos: 191,
EndPos: 195,
},
},
Parts: []ast.Vertex{
@ -1673,8 +1717,8 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 192,
EndPos: 196,
StartPos: 191,
EndPos: 195,
},
},
Value: []byte("null"),
@ -1688,19 +1732,17 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 198,
EndPos: 210,
StartPos: 197,
EndPos: 209,
},
},
Variadic: true,
ByRef: true,
Type: &ast.NameName{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 198,
EndPos: 201,
StartPos: 197,
EndPos: 200,
},
},
Parts: []ast.Vertex{
@ -1709,43 +1751,65 @@ func TestPhp7ParameterNode(t *testing.T) {
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 198,
EndPos: 201,
StartPos: 197,
EndPos: 200,
},
},
Value: []byte("baz"),
},
},
},
Var: &ast.ExprVariable{
Var: &ast.Reference{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 206,
EndPos: 210,
StartPos: 201,
EndPos: 209,
},
},
VarName: &ast.Identifier{
Var: &ast.Variadic{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 206,
EndPos: 210,
StartPos: 202,
EndPos: 209,
},
},
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 205,
EndPos: 209,
},
},
VarName: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
StartLine: 5,
EndLine: 5,
StartPos: 205,
EndPos: 209,
},
},
Value: []byte("$baz"),
},
},
Value: []byte("$baz"),
},
},
},
},
Stmts: []ast.Vertex{},
Stmts: []ast.Vertex{
},
},
},
},
}
lexer := scanner.NewLexer([]byte(src), "7.4", false, nil)
php7parser := php7.NewParser(lexer, nil)
php7parser.Parse()
@ -7497,8 +7561,6 @@ func TestStmtFunction_ReturnVar(t *testing.T) {
EndPos: 24,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
@ -7541,8 +7603,6 @@ func TestStmtFunction_ReturnVar(t *testing.T) {
EndPos: 37,
},
},
ByRef: false,
Variadic: false,
Type: &ast.Identifier{
Node: ast.Node{
Position: &position.Position{
@ -15290,8 +15350,6 @@ func TestExprClosure_Use(t *testing.T) {
EndPos: 14,
},
},
Variadic: false,
ByRef: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -15323,8 +15381,6 @@ func TestExprClosure_Use(t *testing.T) {
EndPos: 18,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -15468,8 +15524,6 @@ func TestExprClosure_Use2(t *testing.T) {
EndPos: 14,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{
@ -15501,8 +15555,6 @@ func TestExprClosure_Use2(t *testing.T) {
EndPos: 18,
},
},
ByRef: false,
Variadic: false,
Var: &ast.ExprVariable{
Node: ast.Node{
Position: &position.Position{

BIN
internal/php7/php7.go generated

Binary file not shown.

View File

@ -2139,12 +2139,27 @@ parameter:
optional_type is_reference is_variadic T_VARIABLE
{
identifier := &ast.Identifier{ast.Node{}, $4.Value}
variable := &ast.ExprVariable{ast.Node{}, identifier}
$$ = &ast.Parameter{ast.Node{}, $2 != nil, $3 != nil, $1, variable, nil}
// save position
identifier.GetNode().Position = position.NewTokenPosition($4)
var variable ast.Vertex
variable = &ast.ExprVariable{ast.Node{}, identifier}
variable.GetNode().Position = position.NewTokenPosition($4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $4.Tokens)
if $3 != nil {
variable = &ast.Variadic{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($3, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $3.Tokens)
}
if $2 != nil {
variable = &ast.Reference{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($2, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $2.Tokens)
}
$$ = &ast.Parameter{ast.Node{}, $1, variable, nil}
if $1 != nil {
$$.GetNode().Position = position.NewNodeTokenPosition($1, $4)
} else if $2 != nil {
@ -2155,41 +2170,33 @@ parameter:
$$.GetNode().Position = position.NewTokenPosition($4)
}
// save comments
if $1 != nil {
yylex.(*Parser).MoveFreeFloating($1, $$)
}
if $2 != nil {
yylex.(*Parser).setFreeFloating($$, token.OptionalType, $2.Tokens)
}
if $3 != nil {
yylex.(*Parser).setFreeFloating($$, token.Ampersand, $3.Tokens)
}
yylex.(*Parser).setFreeFloating($$, token.Variadic, $4.Tokens)
// normalize
if $3 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Ampersand, $$.GetNode().Tokens[token.Variadic]); delete($$.GetNode().Tokens, token.Variadic)
}
if $2 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.OptionalType, $$.GetNode().Tokens[token.Ampersand]); delete($$.GetNode().Tokens, token.Ampersand)
}
if $1 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Start, $$.GetNode().Tokens[token.OptionalType]); delete($$.GetNode().Tokens, token.OptionalType)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
}
| optional_type is_reference is_variadic T_VARIABLE '=' expr
{
identifier := &ast.Identifier{ast.Node{}, $4.Value}
variable := &ast.ExprVariable{ast.Node{}, identifier}
$$ = &ast.Parameter{ast.Node{}, $2 != nil, $3 != nil, $1, variable, $6}
// save position
identifier.GetNode().Position = position.NewTokenPosition($4)
var variable ast.Vertex
variable = &ast.ExprVariable{ast.Node{}, identifier}
variable.GetNode().Position = position.NewTokenPosition($4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $4.Tokens)
yylex.(*Parser).setFreeFloating(variable, token.End, $5.Tokens)
if $3 != nil {
variable = &ast.Variadic{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($3, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $3.Tokens)
}
if $2 != nil {
variable = &ast.Reference{ast.Node{}, variable}
variable.GetNode().Position = position.NewTokensPosition($2, $4)
yylex.(*Parser).setFreeFloating(variable, token.Start, $2.Tokens)
}
$$ = &ast.Parameter{ast.Node{}, $1, variable, $6}
if $1 != nil {
$$.GetNode().Position = position.NewNodesPosition($1, $6)
} else if $2 != nil {
@ -2200,31 +2207,6 @@ parameter:
$$.GetNode().Position = position.NewTokenNodePosition($4, $6)
}
// save comments
if $1 != nil {
yylex.(*Parser).MoveFreeFloating($1, $$)
}
if $2 != nil {
yylex.(*Parser).setFreeFloating($$, token.OptionalType, $2.Tokens)
}
if $3 != nil {
yylex.(*Parser).setFreeFloating($$, token.Ampersand, $3.Tokens)
}
yylex.(*Parser).setFreeFloating($$, token.Variadic, $4.Tokens)
yylex.(*Parser).setFreeFloating($$, token.Var, $5.Tokens)
// normalize
if $3 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Ampersand, $$.GetNode().Tokens[token.Variadic]); delete($$.GetNode().Tokens, token.Variadic)
}
if $2 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.OptionalType, $$.GetNode().Tokens[token.Ampersand]); delete($$.GetNode().Tokens, token.Ampersand)
}
if $1 == nil {
yylex.(*Parser).setFreeFloatingTokens($$, token.Start, $$.GetNode().Tokens[token.OptionalType]); delete($$.GetNode().Tokens, token.OptionalType)
}
yylex.(*Parser).returnTokenToPool(yyDollar, &yyVAL)
}
;

File diff suppressed because it is too large Load Diff

350
internal/php7/test.php Normal file
View File

@ -0,0 +1,350 @@
<?
foo($a, ...$b);
$foo($a, ...$b);
$foo->bar($a, ...$b);
foo::bar($a, ...$b);
$foo::bar($a, ...$b);
new foo($a, ...$b);
/** anonymous class */
new class ($a, ...$b) {};
new class {};
new $foo;
new $foo[1];
new $foo{$bar};
new $foo->bar;
new $foo::$bar;
new static::$bar;
function foo(?bar $bar=null, baz &...$baz) {}
class foo {public function foo(?bar $bar=null, baz &...$baz) {}}
function(?bar $bar=null, baz &...$baz) {};
static function(?bar $bar=null, baz &...$baz) {};
1234567890123456789;
12345678901234567890;
0.;
0b0111111111111111111111111111111111111111111111111111111111111111;
0b1111111111111111111111111111111111111111111111111111111111111111;
0x007111111111111111;
0x8111111111111111;
__CLASS__;
__DIR__;
__FILE__;
__FUNCTION__;
__LINE__;
__NAMESPACE__;
__METHOD__;
__TRAIT__;
"test $var";
"test $var[1]";
"test $var[-1]";
"test $var[1234567890123456789012345678901234567890]";
"test $var[-1234567890123456789012345678901234567890]";
"test $var[bar]";
"test $var[$bar]";
"$foo $bar";
"test $foo->bar()";
"test ${foo}";
"test ${foo[0]}";
"test ${$foo}";
"test {$foo->bar()}";
if ($a) :
endif;
if ($a) :
elseif ($b):
endif;
if ($a) :
else:
endif;
if ($a) :
elseif ($b):
elseif ($c):
else:
endif;
while (1) { break; }
while (1) { break 2; }
while (1) : break(3); endwhile;
class foo{ public const FOO = 1, BAR = 2; }
class foo{ const FOO = 1, BAR = 2; }
class foo{ function bar() {} }
class foo{ public static function &bar() {} }
class foo{ public static function &bar(): void {} }
abstract class foo{ }
final class foo extends bar { }
final class foo implements bar { }
final class foo implements bar, baz { }
new class() extends foo implements bar, baz { };
const FOO = 1, BAR = 2;
while (1) { continue; }
while (1) { continue 2; }
while (1) { continue(3); }
declare(ticks=1);
declare(ticks=1) {}
declare(ticks=1): enddeclare;
do {} while(1);
echo $a, 1;
echo($a);
for($i = 0; $i < 10; $i++, $i++) {}
for(; $i < 10; $i++, $i++) : endfor;
foreach ($a as $v) {}
foreach ($a as $v) : endforeach;
foreach ($a as $k => $v) {}
foreach ($a as $k => &$v) {}
foreach ($a as $k => list($v)) {}
foreach ($a as $k => [$v]) {}
function foo() {}
function foo() {return;}
function &foo() {return 1;}
function &foo(): void {}
global $a, $b;
a:
goto a;
if ($a) {}
if ($a) {} elseif ($b) {}
if ($a) {} else {}
if ($a) {} elseif ($b) {} elseif ($c) {} else {}
if ($a) {} elseif ($b) {} else if ($c) {} else {}
?> <div></div> <?
interface Foo {}
interface Foo extends Bar {}
interface Foo extends Bar, Baz {}
namespace Foo;
namespace Foo {}
namespace {}
class foo {var $a;}
class foo {public static $a, $b = 1;}
static $a, $b = 1;
switch (1) :
case 1:
default:
case 2:
endswitch;
switch (1) :;
case 1;
case 2;
endswitch;
switch (1) {
case 1: break;
case 2: break;
}
switch (1) {;
case 1; break;
case 2; break;
}
throw $e;
trait Foo {}
class Foo { use Bar; }
class Foo { use Bar, Baz {} }
class Foo { use Bar, Baz { one as include; } }
class Foo { use Bar, Baz { one as public; } }
class Foo { use Bar, Baz { one as public two; } }
class Foo { use Bar, Baz { Bar::one insteadof Baz, Quux; Baz::one as two; } }
try {}
try {} catch (Exception $e) {}
try {} catch (Exception|RuntimeException $e) {}
try {} catch (Exception $e) {} catch (RuntimeException $e) {}
try {} catch (Exception $e) {} finally {}
unset($a, $b,);
use Foo;
use \Foo;
use \Foo as Bar;
use Foo, Bar;
use Foo, Bar as Baz;
use function Foo, \Bar;
use function Foo as foo, \Bar as bar;
use const Foo, \Bar;
use const Foo as foo, \Bar as bar;
use \Foo\{Bar, Baz};
use Foo\{Bar, Baz as quux};
use function Foo\{Bar, Baz};
use const \Foo\{Bar, Baz};
use Foo\{const Bar, function Baz};
$a[1];
$a[1][2];
array();
array(1);
array(1=>1, &$b,);
~$a;
!$a;
Foo::Bar;
$foo::Bar;
clone($a);
clone $a;
function(){};
function($a, $b) use ($c, &$d) {};
function(): void {};
foo;
namespace\foo;
\foo;
empty($a);
@$a;
eval($a);
exit;
exit($a);
die;
die($a);
foo();
namespace\foo();
\foo();
$foo();
$a--;
$a++;
--$a;
++$a;
include $a;
include_once $a;
require $a;
require_once $a;
$a instanceof Foo;
$a instanceof namespace\Foo;
$a instanceof \Foo;
isset($a, $b);
list($a) = $b;
list($a[]) = $b;
list(list($a)) = $b;
$a->foo();
new Foo();
new namespace\Foo();
new \Foo();
new class ($a, ...$b) {};
print($a);
$a->foo;
`cmd $a`;
`cmd`;
``;
[];
[1];
[1=>1, &$b,];
[$a] = $b;
[$a[]] = $b;
[list($a)] = $b;
Foo::bar();
namespace\Foo::bar();
\Foo::bar();
Foo::$bar;
$foo::$bar;
namespace\Foo::$bar;
\Foo::$bar;
$a ? $b : $c;
$a ? : $c;
$a ? $b ? $c : $d : $e;
$a ? $b : $c ? $d : $e;
-$a;
+$a;
$$a;
yield;
yield $a;
yield $a => $b;
yield from $a;
(array)$a;
(boolean)$a;
(bool)$a;
(double)$a;
(float)$a;
(integer)$a;
(int)$a;
(object)$a;
(string)$a;
(unset)$a;
$a & $b;
$a | $b;
$a ^ $b;
$a && $b;
$a || $b;
$a ?? $b;
$a . $b;
$a / $b;
$a == $b;
$a >= $b;
$a > $b;
$a === $b;
$a and $b;
$a or $b;
$a xor $b;
$a - $b;
$a % $b;
$a * $b;
$a != $b;
$a !== $b;
$a + $b;
$a ** $b;
$a << $b;
$a >> $b;
$a <= $b;
$a < $b;
$a <=> $b;
$a =& $b;
$a = $b;
$a &= $b;
$a |= $b;
$a ^= $b;
$a .= $b;
$a /= $b;
$a -= $b;
$a %= $b;
$a *= $b;
$a += $b;
$a **= $b;
$a <<= $b;
$a >>= $b;
class foo {public function class() {} }
\foo\bar();
function foo(&$a, ...$b) {
function bar() {}
class Baz {}
trait Quux{}
interface Quuux {}
}
function foo(&$a = 1, ...$b = 1, $c = 1) {}
function foo(array $a, callable $b) {}
abstract final class foo { abstract protected static function bar(); final private function baz() {} }
(new Foo)->bar;
(new Foo)();
[$foo][0]();
foo[1]();
"foo"();
[1]{$foo}();
${foo()};
Foo::$bar();
Foo::{$bar[0]}();
$foo->$bar;
$foo->{$bar[0]};
[1=>&$a, 2=>list($b)];
__halt_compiler();
parsing process must be terminated

View File

@ -20,6 +20,8 @@ type Visitor interface {
type NodeVisitor interface {
Root(n *Root)
Nullable(n *Nullable)
Reference(n *Reference)
Variadic(n *Variadic)
Parameter(n *Parameter)
Identifier(n *Identifier)
ArgumentList(n *ArgumentList)

View File

@ -36,11 +36,29 @@ func (n *Nullable) Accept(v NodeVisitor) {
v.Nullable(n)
}
// Reference node
type Reference struct {
Node
Var Vertex
}
func (n *Reference) Accept(v NodeVisitor) {
v.Reference(n)
}
// Variadic node
type Variadic struct {
Node
Var Vertex
}
func (n *Variadic) Accept(v NodeVisitor) {
v.Variadic(n)
}
// Parameter node
type Parameter struct {
Node
ByRef bool
Variadic bool
Type Vertex
Var Vertex
DefaultValue Vertex

View File

@ -40,6 +40,30 @@ func (t *DFS) Traverse(n ast.Vertex) {
t.Traverse(nn.Expr)
t.visitor.Leave("Expr", true)
}
case *ast.Reference:
if nn == nil {
return
}
if !t.visitor.EnterNode(nn) {
return
}
if nn.Var != nil {
t.visitor.Enter("Var", true)
t.Traverse(nn.Var)
t.visitor.Leave("Var", true)
}
case *ast.Variadic:
if nn == nil {
return
}
if !t.visitor.EnterNode(nn) {
return
}
if nn.Var != nil {
t.visitor.Enter("Var", true)
t.Traverse(nn.Var)
t.visitor.Leave("Var", true)
}
case *ast.Parameter:
if nn == nil {
return

View File

@ -33,10 +33,18 @@ func (v *Dump) print(str string) {
}
func (v *Dump) printIndent(indentDepth int) {
if indentDepth < 0 {
indentDepth = 0
}
v.print(strings.Repeat("\t", indentDepth))
}
func (v *Dump) printIndentIfNotSingle(indentDepth int) {
if indentDepth < 0 {
indentDepth = 0
}
if !v.stack[v.depth-1].singleNode {
v.print(strings.Repeat("\t", indentDepth))
}
@ -173,20 +181,22 @@ func (v *Dump) Nullable(n *ast.Nullable) {
v.printNode(n.GetNode())
}
func (v *Dump) Reference(n *ast.Reference) {
v.printIndentIfNotSingle(v.indent - 1)
v.print("&ast.Reference{\n")
v.printNode(n.GetNode())
}
func (v *Dump) Variadic(n *ast.Variadic) {
v.printIndentIfNotSingle(v.indent - 1)
v.print("&ast.Variadic{\n")
v.printNode(n.GetNode())
}
func (v *Dump) Parameter(n *ast.Parameter) {
v.printIndent(v.indent - 1)
v.print("&ast.Parameter{\n")
v.printNode(n.GetNode())
if n.ByRef {
v.printIndent(v.indent)
v.print("ByRef: true,\n")
}
if n.Variadic {
v.printIndent(v.indent)
v.print("Variadic: true,\n")
}
}
func (v *Dump) Identifier(n *ast.Identifier) {

View File

@ -30,8 +30,7 @@ func ExampleDump() {
Stmts: []ast.Vertex{
&ast.Identifier{},
&ast.Parameter{
Variadic: true,
Var: &ast.ExprVariable{},
Var: &ast.ExprVariable{},
},
&ast.StmtInlineHtml{
Value: []byte("foo"),
@ -64,7 +63,6 @@ func ExampleDump() {
// Value: []byte(""),
// },
// &ast.Parameter{
// Variadic: true,
// Var: &ast.ExprVariable{
// },
// },

View File

@ -502,10 +502,8 @@ func TestResolveFunctionName(t *testing.T) {
FunctionName: &ast.Identifier{Value: []byte("A")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: false,
Variadic: false,
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
},
},
ReturnType: &ast.Nullable{Expr: nameBC},
@ -540,10 +538,8 @@ func TestResolveMethodName(t *testing.T) {
MethodName: &ast.Identifier{Value: []byte("A")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: false,
Variadic: false,
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
},
},
ReturnType: &ast.Nullable{Expr: nameBC},
@ -573,10 +569,8 @@ func TestResolveClosureName(t *testing.T) {
Static: false,
Params: []ast.Vertex{
&ast.Parameter{
ByRef: false,
Variadic: false,
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
Type: nameAB,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("foo")}},
},
},
ClosureUse: nil,

View File

@ -30,6 +30,14 @@ func (v *Null) Nullable(_ *ast.Nullable) {
// do nothing
}
func (v *Null) Reference(_ *ast.Reference) {
// do nothing
}
func (v *Null) Variadic(_ *ast.Variadic) {
// do nothing
}
func (v *Null) Parameter(_ *ast.Parameter) {
// do nothing
}

View File

@ -64,6 +64,10 @@ func (p *PrettyPrinter) printNode(n ast.Vertex) {
p.printNodeRoot(n)
case *ast.Identifier:
p.printNodeIdentifier(n)
case *ast.Reference:
p.printNodeReference(n)
case *ast.Variadic:
p.printNodeVariadic(n)
case *ast.Parameter:
p.printNodeParameter(n)
case *ast.Nullable:
@ -434,6 +438,20 @@ func (p *PrettyPrinter) printNodeIdentifier(n ast.Vertex) {
io.WriteString(p.w, v)
}
func (p *PrettyPrinter) printNodeReference(n ast.Vertex) {
nn := n.(*ast.Reference)
io.WriteString(p.w, "&")
p.Print(nn.Var)
}
func (p *PrettyPrinter) printNodeVariadic(n ast.Vertex) {
nn := n.(*ast.Variadic)
io.WriteString(p.w, "...")
p.Print(nn.Var)
}
func (p *PrettyPrinter) printNodeParameter(n ast.Vertex) {
nn := n.(*ast.Parameter)
@ -442,14 +460,6 @@ func (p *PrettyPrinter) printNodeParameter(n ast.Vertex) {
io.WriteString(p.w, " ")
}
if nn.ByRef {
io.WriteString(p.w, "&")
}
if nn.Variadic {
io.WriteString(p.w, "...")
}
p.Print(nn.Var)
if nn.DefaultValue != nil {

View File

@ -119,10 +119,14 @@ func TestPrintParameter(t *testing.T) {
p := printer.NewPrettyPrinter(o, " ")
p.Print(&ast.Parameter{
ByRef: false,
Variadic: true,
Type: &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Foo")}}},
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}},
Type: &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Foo")}}},
Var: &ast.Variadic{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{
Value: []byte("var"),
},
},
},
DefaultValue: &ast.ScalarString{Value: []byte("'default'")},
})
@ -140,10 +144,8 @@ func TestPrintNullable(t *testing.T) {
p := printer.NewPrettyPrinter(o, " ")
p.Print(&ast.Nullable{
Expr: &ast.Parameter{
ByRef: false,
Variadic: true,
Type: &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Foo")}}},
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}},
Var: &ast.Variadic{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}}},
DefaultValue: &ast.ScalarString{Value: []byte("'default'")},
},
})
@ -1389,9 +1391,7 @@ func TestPrintExprClosure(t *testing.T) {
ReturnsRef: true,
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Variadic: false,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}},
Var: &ast.Reference{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}}},
},
},
ClosureUse: &ast.ExprClosureUse{
@ -2446,14 +2446,12 @@ func TestPrintStmtClassMethod(t *testing.T) {
MethodName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Type: &ast.Nullable{Expr: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("int")}}}},
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("a")}},
Var: &ast.Reference{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("a")}}},
DefaultValue: &ast.ExprConstFetch{Const: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("null")}}}},
},
&ast.Parameter{
Variadic: true,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("b")}},
Var: &ast.Variadic{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("b")}}},
},
},
ReturnType: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("void")}}},
@ -2484,14 +2482,12 @@ func TestPrintStmtAbstractClassMethod(t *testing.T) {
MethodName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Type: &ast.Nullable{Expr: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("int")}}}},
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("a")}},
Var: &ast.Reference{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("a")}}},
DefaultValue: &ast.ExprConstFetch{Const: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("null")}}}},
},
&ast.Parameter{
Variadic: true,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("b")}},
Var: &ast.Variadic{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("b")}}},
},
},
ReturnType: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("void")}}},
@ -3197,9 +3193,7 @@ func TestPrintStmtFunction(t *testing.T) {
FunctionName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Variadic: false,
Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}},
Var: &ast.Reference{Var: &ast.ExprVariable{VarName: &ast.Identifier{Value: []byte("var")}}},
},
},
ReturnType: &ast.NameFullyQualified{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("Foo")}}},

View File

@ -79,6 +79,10 @@ func (p *Printer) printNode(n ast.Vertex) {
p.printNodeRoot(n)
case *ast.Identifier:
p.printNodeIdentifier(n)
case *ast.Reference:
p.printNodeReference(n)
case *ast.Variadic:
p.printNodeVariadic(n)
case *ast.Parameter:
p.printNodeParameter(n)
case *ast.Nullable:
@ -444,6 +448,26 @@ func (p *Printer) printNodeIdentifier(n ast.Vertex) {
p.printFreeFloating(nn, token.End)
}
func (p *Printer) printNodeReference(n ast.Vertex) {
nn := n.(*ast.Reference)
p.printFreeFloating(nn, token.Start)
io.WriteString(p.w, "&")
p.Print(nn.Var)
p.printFreeFloating(nn, token.End)
}
func (p *Printer) printNodeVariadic(n ast.Vertex) {
nn := n.(*ast.Variadic)
p.printFreeFloating(nn, token.Start)
io.WriteString(p.w, "...")
p.Print(nn.Var)
p.printFreeFloating(nn, token.End)
}
func (p *Printer) printNodeParameter(n ast.Vertex) {
nn := n.(*ast.Parameter)
p.printFreeFloating(nn, token.Start)
@ -451,22 +475,10 @@ func (p *Printer) printNodeParameter(n ast.Vertex) {
if nn.Type != nil {
p.Print(nn.Type)
}
p.printFreeFloating(nn, token.OptionalType)
if nn.ByRef {
io.WriteString(p.w, "&")
}
p.printFreeFloating(nn, token.Ampersand)
if nn.Variadic {
io.WriteString(p.w, "...")
}
p.printFreeFloating(nn, token.Variadic)
p.Print(nn.Var)
if nn.DefaultValue != nil {
p.printFreeFloating(nn, token.Var)
io.WriteString(p.w, "=")
p.Print(nn.DefaultValue)
}

View File

@ -107,6 +107,18 @@ func TestParseAndPrintIdentifier(t *testing.T) {
}
}
func TestParseAndPrintParameterTMP(t *testing.T) {
src := `<?php
function foo ( foo & ... $foo = null ) {}`
actual := print(parse(src))
if src != actual {
t.Errorf("\nexpected: %s\ngot: %s\n", src, actual)
}
}
func TestParseAndPrintParameter(t *testing.T) {
src := `<?php

View File

@ -141,8 +141,6 @@ func TestPrinterPrintParameter(t *testing.T) {
p := printer.NewPrinter(o)
p.Print(&ast.Parameter{
ByRef: false,
Variadic: true,
Type: &ast.NameFullyQualified{
Parts: []ast.Vertex{
&ast.NameNamePart{
@ -150,8 +148,10 @@ func TestPrinterPrintParameter(t *testing.T) {
},
},
},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
Var: &ast.Variadic{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
},
},
DefaultValue: &ast.ScalarString{
Value: []byte("'default'"),
@ -172,8 +172,6 @@ func TestPrinterPrintNullable(t *testing.T) {
p := printer.NewPrinter(o)
p.Print(&ast.Nullable{
Expr: &ast.Parameter{
ByRef: true,
Variadic: false,
Type: &ast.NameFullyQualified{
Parts: []ast.Vertex{
&ast.NameNamePart{
@ -181,8 +179,10 @@ func TestPrinterPrintNullable(t *testing.T) {
},
},
},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
},
},
DefaultValue: &ast.ScalarString{
Value: []byte("'default'"),
@ -1703,10 +1703,10 @@ func TestPrinterPrintExprClosure(t *testing.T) {
ReturnsRef: true,
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Variadic: false,
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
},
},
},
},
@ -1748,10 +1748,10 @@ func TestPrinterPrintExprArrowFunction(t *testing.T) {
ReturnsRef: true,
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Variadic: false,
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
},
},
},
},
@ -2925,17 +2925,19 @@ func TestPrinterPrintStmtClassMethod(t *testing.T) {
MethodName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Type: &ast.Nullable{Expr: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("int")}}}},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$a")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$a")},
},
},
DefaultValue: &ast.ExprConstFetch{Const: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("null")}}}},
},
&ast.Parameter{
Variadic: true,
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$b")},
Var: &ast.Variadic{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$b")},
},
},
},
},
@ -2972,17 +2974,19 @@ func TestPrinterPrintStmtAbstractClassMethod(t *testing.T) {
MethodName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Type: &ast.Nullable{Expr: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("int")}}}},
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$a")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$a")},
},
},
DefaultValue: &ast.ExprConstFetch{Const: &ast.NameName{Parts: []ast.Vertex{&ast.NameNamePart{Value: []byte("null")}}}},
},
&ast.Parameter{
Variadic: true,
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$b")},
Var: &ast.Variadic{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$b")},
},
},
},
},
@ -3607,10 +3611,10 @@ func TestPrinterPrintStmtFunction(t *testing.T) {
FunctionName: &ast.Identifier{Value: []byte("foo")},
Params: []ast.Vertex{
&ast.Parameter{
ByRef: true,
Variadic: false,
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
Var: &ast.Reference{
Var: &ast.ExprVariable{
VarName: &ast.Identifier{Value: []byte("$var")},
},
},
},
},