php8.1: added first class callable syntax (#18)
This commit is contained in:
		
							parent
							
								
									13ed0df282
								
							
						
					
					
						commit
						50ed139750
					
				| @ -524,6 +524,7 @@ func (b *Builder) NewMethodCall( | ||||
| 		OpenParenthesisTkn:  argumentList.OpenParenthesisTkn, | ||||
| 		Args:                argumentList.Arguments, | ||||
| 		SeparatorTkns:       argumentList.SeparatorTkns, | ||||
| 		EllipsisTkn:         argumentList.EllipsisTkn, | ||||
| 		CloseParenthesisTkn: argumentList.CloseParenthesisTkn, | ||||
| 	} | ||||
| 
 | ||||
| @ -551,6 +552,7 @@ func (b *Builder) NewNullsafeMethodCall( | ||||
| 		OpenParenthesisTkn:  argumentList.OpenParenthesisTkn, | ||||
| 		Args:                argumentList.Arguments, | ||||
| 		SeparatorTkns:       argumentList.SeparatorTkns, | ||||
| 		EllipsisTkn:         argumentList.EllipsisTkn, | ||||
| 		CloseParenthesisTkn: argumentList.CloseParenthesisTkn, | ||||
| 	} | ||||
| 
 | ||||
| @ -1528,3 +1530,37 @@ func (b *Builder) NewUse( | ||||
| 
 | ||||
| 	return use | ||||
| } | ||||
| 
 | ||||
| func (b *Builder) NewArgumentList( | ||||
| 	OpenParenthesisTkn *token.Token, | ||||
| 
 | ||||
| 	ArgList ast.Vertex, | ||||
| 	CommaTkn *token.Token, | ||||
| 
 | ||||
| 	EllipsisTkn *token.Token, | ||||
| 
 | ||||
| 	CloseParenthesisTkn *token.Token, | ||||
| ) *ArgumentList { | ||||
| 	if ArgList == nil { | ||||
| 		return &ArgumentList{ | ||||
| 			Position:            b.Pos.NewTokensPosition(OpenParenthesisTkn, CloseParenthesisTkn), | ||||
| 			OpenParenthesisTkn:  OpenParenthesisTkn, | ||||
| 			EllipsisTkn:         EllipsisTkn, | ||||
| 			CloseParenthesisTkn: CloseParenthesisTkn, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	args, sepTkns := b.SeparatedListItems(ArgList) | ||||
| 
 | ||||
| 	if CommaTkn != nil { | ||||
| 		sepTkns = append(sepTkns, CommaTkn) | ||||
| 	} | ||||
| 
 | ||||
| 	return &ArgumentList{ | ||||
| 		Position:            b.Pos.NewTokensPosition(OpenParenthesisTkn, CloseParenthesisTkn), | ||||
| 		OpenParenthesisTkn:  OpenParenthesisTkn, | ||||
| 		Arguments:           args, | ||||
| 		SeparatorTkns:       sepTkns, | ||||
| 		CloseParenthesisTkn: CloseParenthesisTkn, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -57,6 +57,7 @@ type ArgumentList struct { | ||||
| 	OpenParenthesisTkn  *token.Token | ||||
| 	Arguments           []ast.Vertex | ||||
| 	SeparatorTkns       []*token.Token | ||||
| 	EllipsisTkn         *token.Token | ||||
| 	CloseParenthesisTkn *token.Token | ||||
| } | ||||
| 
 | ||||
|  | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -1340,42 +1340,16 @@ optional_return_type: | ||||
| ; | ||||
| 
 | ||||
| argument_list: | ||||
|         '(' ')' | ||||
|             { | ||||
|                 $$ = &ArgumentList{ | ||||
|                     Position: yylex.(*Parser).builder.Pos.NewTokensPosition($1, $2), | ||||
|                     OpenParenthesisTkn: $1, | ||||
|                     CloseParenthesisTkn: $2, | ||||
|                 } | ||||
|             } | ||||
|         '(' ')'                   { $$ = yylex.(*Parser).builder.NewArgumentList($1, nil, nil, nil, $2) } | ||||
|     |   '(' non_empty_argument_list optional_comma ')' | ||||
|             { | ||||
|                 argumentList := $2.(*ArgumentList) | ||||
|                 argumentList.Position = yylex.(*Parser).builder.Pos.NewTokensPosition($1, $4) | ||||
|                 argumentList.OpenParenthesisTkn = $1 | ||||
|                 if $3 != nil { | ||||
|                     argumentList.SeparatorTkns = append(argumentList.SeparatorTkns, $3) | ||||
|                 } | ||||
|                 argumentList.CloseParenthesisTkn = $4 | ||||
| 
 | ||||
|                 $$ = argumentList | ||||
|             } | ||||
|                                   { $$ = yylex.(*Parser).builder.NewArgumentList($1, $2, $3, nil, $4) } | ||||
|     |   '(' T_ELLIPSIS ')'        { $$ = yylex.(*Parser).builder.NewArgumentList($1, nil, nil, $2, $3) } | ||||
| ; | ||||
| 
 | ||||
| non_empty_argument_list: | ||||
|         argument | ||||
|             { | ||||
|                 $$ = &ArgumentList{ | ||||
|                     Arguments: []ast.Vertex{$1}, | ||||
|                 } | ||||
|             } | ||||
|         argument                  { $$ = yylex.(*Parser).builder.NewSeparatedList($1) } | ||||
|     |   non_empty_argument_list ',' argument | ||||
|             { | ||||
|                 $1.(*ArgumentList).SeparatorTkns = append($1.(*ArgumentList).SeparatorTkns, $2) | ||||
|                 $1.(*ArgumentList).Arguments = append($1.(*ArgumentList).Arguments, $3) | ||||
| 
 | ||||
|                 $$ = $1 | ||||
|             } | ||||
|                                   { $$ = yylex.(*Parser).builder.AppendToSeparatedList($1, $2, $3) } | ||||
| ; | ||||
| 
 | ||||
| argument: | ||||
| @ -2694,6 +2668,7 @@ function_call: | ||||
|                     OpenParenthesisTkn:  $2.(*ArgumentList).OpenParenthesisTkn, | ||||
|                     Args:                $2.(*ArgumentList).Arguments, | ||||
|                     SeparatorTkns:       $2.(*ArgumentList).SeparatorTkns, | ||||
|                     EllipsisTkn:         $2.(*ArgumentList).EllipsisTkn, | ||||
|                     CloseParenthesisTkn: $2.(*ArgumentList).CloseParenthesisTkn, | ||||
|                 } | ||||
|             } | ||||
| @ -2707,6 +2682,7 @@ function_call: | ||||
|                     OpenParenthesisTkn:  $4.(*ArgumentList).OpenParenthesisTkn, | ||||
|                     Args:                $4.(*ArgumentList).Arguments, | ||||
|                     SeparatorTkns:       $4.(*ArgumentList).SeparatorTkns, | ||||
|                     EllipsisTkn:         $4.(*ArgumentList).EllipsisTkn, | ||||
|                     CloseParenthesisTkn: $4.(*ArgumentList).CloseParenthesisTkn, | ||||
|                 } | ||||
| 
 | ||||
| @ -2726,6 +2702,7 @@ function_call: | ||||
|                     OpenParenthesisTkn:  $2.(*ArgumentList).OpenParenthesisTkn, | ||||
|                     Args:                $2.(*ArgumentList).Arguments, | ||||
|                     SeparatorTkns:       $2.(*ArgumentList).SeparatorTkns, | ||||
|                     EllipsisTkn:         $2.(*ArgumentList).EllipsisTkn, | ||||
|                     CloseParenthesisTkn: $2.(*ArgumentList).CloseParenthesisTkn, | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -1506,6 +1506,7 @@ type ExprFunctionCall struct { | ||||
| 	OpenParenthesisTkn  *token.Token | ||||
| 	Args                []Vertex | ||||
| 	SeparatorTkns       []*token.Token | ||||
| 	EllipsisTkn         *token.Token | ||||
| 	CloseParenthesisTkn *token.Token | ||||
| } | ||||
| 
 | ||||
| @ -1610,6 +1611,7 @@ type ExprMethodCall struct { | ||||
| 	OpenParenthesisTkn   *token.Token | ||||
| 	Args                 []Vertex | ||||
| 	SeparatorTkns        []*token.Token | ||||
| 	EllipsisTkn          *token.Token | ||||
| 	CloseParenthesisTkn  *token.Token | ||||
| } | ||||
| 
 | ||||
| @ -1632,6 +1634,7 @@ type ExprNullsafeMethodCall struct { | ||||
| 	OpenParenthesisTkn   *token.Token | ||||
| 	Args                 []Vertex | ||||
| 	SeparatorTkns        []*token.Token | ||||
| 	EllipsisTkn          *token.Token | ||||
| 	CloseParenthesisTkn  *token.Token | ||||
| } | ||||
| 
 | ||||
| @ -1830,6 +1833,7 @@ type ExprStaticCall struct { | ||||
| 	OpenParenthesisTkn   *token.Token | ||||
| 	Args                 []Vertex | ||||
| 	SeparatorTkns        []*token.Token | ||||
| 	EllipsisTkn          *token.Token | ||||
| 	CloseParenthesisTkn  *token.Token | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -1323,6 +1323,7 @@ func (v *Dumper) ExprFunctionCall(n *ast.ExprFunctionCall) { | ||||
| 	v.dumpToken("OpenParenthesisTkn", n.OpenParenthesisTkn) | ||||
| 	v.dumpVertexList("Args", n.Args) | ||||
| 	v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) | ||||
| 	v.dumpToken("EllipsisTkn", n.EllipsisTkn) | ||||
| 	v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| @ -1409,6 +1410,7 @@ func (v *Dumper) ExprMethodCall(n *ast.ExprMethodCall) { | ||||
| 	v.dumpToken("OpenParenthesisTkn", n.OpenParenthesisTkn) | ||||
| 	v.dumpVertexList("Args", n.Args) | ||||
| 	v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) | ||||
| 	v.dumpToken("EllipsisTkn", n.EllipsisTkn) | ||||
| 	v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| @ -1428,6 +1430,7 @@ func (v *Dumper) ExprNullsafeMethodCall(n *ast.ExprNullsafeMethodCall) { | ||||
| 	v.dumpToken("OpenParenthesisTkn", n.OpenParenthesisTkn) | ||||
| 	v.dumpVertexList("Args", n.Args) | ||||
| 	v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) | ||||
| 	v.dumpToken("EllipsisTkn", n.EllipsisTkn) | ||||
| 	v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| @ -1591,6 +1594,7 @@ func (v *Dumper) ExprStaticCall(n *ast.ExprStaticCall) { | ||||
| 	v.dumpVertexList("Args", n.Args) | ||||
| 	v.dumpTokenList("SeparatorTkns", n.SeparatorTkns) | ||||
| 	v.dumpToken("CloseParenthesisTkn", n.CloseParenthesisTkn) | ||||
| 	v.dumpToken("EllipsisTkn", n.EllipsisTkn) | ||||
| 
 | ||||
| 	v.indent-- | ||||
| 	v.print(v.indent, "},\n") | ||||
|  | ||||
| @ -1364,6 +1364,9 @@ func (f *formatter) ExprFunctionCall(n *ast.ExprFunctionCall) { | ||||
| 	if len(n.Args) > 0 { | ||||
| 		n.SeparatorTkns = f.formatList(n.Args, ',') | ||||
| 	} | ||||
| 	if n.EllipsisTkn != nil { | ||||
| 		n.EllipsisTkn = f.newToken(token.T_ELLIPSIS, []byte("...")) | ||||
| 	} | ||||
| 	n.CloseParenthesisTkn = f.newToken(')', []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -1424,6 +1427,9 @@ func (f *formatter) ExprMethodCall(n *ast.ExprMethodCall) { | ||||
| 	if len(n.Args) > 0 { | ||||
| 		n.SeparatorTkns = f.formatList(n.Args, ',') | ||||
| 	} | ||||
| 	if n.EllipsisTkn != nil { | ||||
| 		n.EllipsisTkn = f.newToken(token.T_ELLIPSIS, []byte("...")) | ||||
| 	} | ||||
| 	n.CloseParenthesisTkn = f.newToken(')', []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -1448,6 +1454,9 @@ func (f *formatter) ExprNullsafeMethodCall(n *ast.ExprNullsafeMethodCall) { | ||||
| 	if len(n.Args) > 0 { | ||||
| 		n.SeparatorTkns = f.formatList(n.Args, ',') | ||||
| 	} | ||||
| 	if n.EllipsisTkn != nil { | ||||
| 		n.EllipsisTkn = f.newToken(token.T_ELLIPSIS, []byte("...")) | ||||
| 	} | ||||
| 	n.CloseParenthesisTkn = f.newToken(')', []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -1569,6 +1578,9 @@ func (f *formatter) ExprStaticCall(n *ast.ExprStaticCall) { | ||||
| 	if len(n.Args) > 0 { | ||||
| 		n.SeparatorTkns = f.formatList(n.Args, ',') | ||||
| 	} | ||||
| 	if n.EllipsisTkn != nil { | ||||
| 		n.EllipsisTkn = f.newToken(token.T_ELLIPSIS, []byte("...")) | ||||
| 	} | ||||
| 	n.CloseParenthesisTkn = f.newToken(')', []byte(")")) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -787,6 +787,7 @@ func (p *printer) ExprFunctionCall(n *ast.ExprFunctionCall) { | ||||
| 	p.printNode(n.Function) | ||||
| 	p.printToken(n.OpenParenthesisTkn, []byte("(")) | ||||
| 	p.printSeparatedList(n.Args, n.SeparatorTkns, []byte(",")) | ||||
| 	p.printToken(n.EllipsisTkn, nil) | ||||
| 	p.printToken(n.CloseParenthesisTkn, []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -828,6 +829,7 @@ func (p *printer) ExprMethodCall(n *ast.ExprMethodCall) { | ||||
| 	p.printToken(n.CloseCurlyBracketTkn, nil) | ||||
| 	p.printToken(n.OpenParenthesisTkn, []byte("(")) | ||||
| 	p.printSeparatedList(n.Args, n.SeparatorTkns, []byte(",")) | ||||
| 	p.printToken(n.EllipsisTkn, nil) | ||||
| 	p.printToken(n.CloseParenthesisTkn, []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -839,6 +841,7 @@ func (p *printer) ExprNullsafeMethodCall(n *ast.ExprNullsafeMethodCall) { | ||||
| 	p.printToken(n.CloseCurlyBracketTkn, nil) | ||||
| 	p.printToken(n.OpenParenthesisTkn, []byte("(")) | ||||
| 	p.printSeparatedList(n.Args, n.SeparatorTkns, []byte(",")) | ||||
| 	p.printToken(n.EllipsisTkn, nil) | ||||
| 	p.printToken(n.CloseParenthesisTkn, []byte(")")) | ||||
| } | ||||
| 
 | ||||
| @ -915,6 +918,7 @@ func (p *printer) ExprStaticCall(n *ast.ExprStaticCall) { | ||||
| 	p.printToken(n.CloseCurlyBracketTkn, nil) | ||||
| 	p.printToken(n.OpenParenthesisTkn, p.ifNodeList(n.Args, []byte("("))) | ||||
| 	p.printSeparatedList(n.Args, n.SeparatorTkns, []byte(",")) | ||||
| 	p.printToken(n.EllipsisTkn, nil) | ||||
| 	p.printToken(n.CloseParenthesisTkn, p.ifNodeList(n.Args, []byte(")"))) | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -84,3 +84,23 @@ class Foo { | ||||
| } | ||||
| `) | ||||
| } | ||||
| 
 | ||||
| func TestFirstClassCallableSyntaxPHP81(t *testing.T) { | ||||
| 	tester.NewParserPrintTestSuite(t).UsePHP8().Run(`<?php | ||||
| $fn = id(...); | ||||
| stdClass::doesNotExist(...); | ||||
| (new stdClass)->doesNotExist(...); | ||||
| Test::privateMethod(...); | ||||
| Test::instanceMethod(...); | ||||
| $fn = (new A)->$name2(...); | ||||
| false && strlen(...); | ||||
| $foo?->foo->bar(...); | ||||
| $foo?->foo($foo->bar(...)); | ||||
| $foo = $closure->__invoke(...); | ||||
| 
 | ||||
| // #[Attribute(...)] // not working | ||||
| // class Foo {} | ||||
| 
 | ||||
| // new Foo(...); // not working | ||||
| `) | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user