mirror of
https://github.com/google/go-jsonnet.git
synced 2025-08-07 23:07:14 +02:00
Allow positional params after optionals
This commit is contained in:
parent
0e67cc3c68
commit
ce07c7fb8b
@ -153,7 +153,6 @@ func (p *parser) parseArgument() (ast.Fodder, *ast.Identifier, ast.Fodder, ast.N
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sbarzowski) - this returned bool is weird
|
// TODO(sbarzowski) - this returned bool is weird
|
||||||
// TODO(sbarzowski) - name - it's also used for parameters
|
|
||||||
func (p *parser) parseArguments(elementKind string) (*token, *ast.Arguments, bool, error) {
|
func (p *parser) parseArguments(elementKind string) (*token, *ast.Arguments, bool, error) {
|
||||||
args := &ast.Arguments{}
|
args := &ast.Arguments{}
|
||||||
gotComma := false
|
gotComma := false
|
||||||
@ -211,32 +210,67 @@ func (p *parser) parseArguments(elementKind string) (*token, *ast.Arguments, boo
|
|||||||
|
|
||||||
// TODO(sbarzowski) - this returned bool is weird
|
// TODO(sbarzowski) - this returned bool is weird
|
||||||
func (p *parser) parseParameters(elementKind string) (*token, []ast.Parameter, bool, error) {
|
func (p *parser) parseParameters(elementKind string) (*token, []ast.Parameter, bool, error) {
|
||||||
parenR, args, trailingComma, err := p.parseArguments(elementKind)
|
|
||||||
if err != nil {
|
var parenR *token
|
||||||
return nil, nil, false, err
|
|
||||||
}
|
|
||||||
var params []ast.Parameter
|
var params []ast.Parameter
|
||||||
for _, arg := range args.Positional {
|
gotComma := false
|
||||||
idFodder, id, ok := astVarToIdentifier(arg.Expr)
|
commaFodder := ast.Fodder{}
|
||||||
if !ok {
|
first := true
|
||||||
return nil, nil, false, errors.MakeStaticError(fmt.Sprintf("Expected simple identifier but got a complex expression."), *arg.Expr.Loc())
|
for {
|
||||||
|
next := p.peek()
|
||||||
|
|
||||||
|
if next.kind == tokenParenR {
|
||||||
|
// gotComma can be true or false here.
|
||||||
|
parenR = p.pop()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
params = append(params, ast.Parameter{
|
|
||||||
NameFodder: idFodder,
|
if !first && !gotComma {
|
||||||
Name: *id,
|
return nil, nil, false, errors.MakeStaticError(fmt.Sprintf("Expected a comma before next %s, got %s.", elementKind, next), next.loc)
|
||||||
CommaFodder: arg.CommaFodder,
|
}
|
||||||
})
|
|
||||||
|
idFodder, id, eqFodder, expr, err := p.parseArgument()
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.peek().kind == tokenComma {
|
||||||
|
comma := p.pop()
|
||||||
|
gotComma = true
|
||||||
|
commaFodder = comma.fodder
|
||||||
|
} else {
|
||||||
|
gotComma = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if id == nil {
|
||||||
|
// Param has no default, is just 'id2'
|
||||||
|
idFodder2, id2, ok := astVarToIdentifier(expr)
|
||||||
|
if !ok {
|
||||||
|
return nil, nil, false, errors.MakeStaticError(fmt.Sprintf("Expected simple identifier but got a complex expression."), *expr.Loc())
|
||||||
|
}
|
||||||
|
param := ast.Parameter{
|
||||||
|
NameFodder: idFodder2,
|
||||||
|
Name: *id2,
|
||||||
|
}
|
||||||
|
if gotComma {
|
||||||
|
param.CommaFodder = commaFodder
|
||||||
|
}
|
||||||
|
params = append(params, param)
|
||||||
|
} else {
|
||||||
|
// Param has a default: id=expr
|
||||||
|
params = append(params, ast.Parameter{
|
||||||
|
NameFodder: idFodder,
|
||||||
|
Name: *id,
|
||||||
|
EqFodder: eqFodder,
|
||||||
|
DefaultArg: expr,
|
||||||
|
CommaFodder: commaFodder,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
first = false
|
||||||
}
|
}
|
||||||
for _, arg := range args.Named {
|
|
||||||
params = append(params, ast.Parameter{
|
return parenR, params, gotComma, nil
|
||||||
NameFodder: arg.NameFodder,
|
|
||||||
Name: arg.Name,
|
|
||||||
EqFodder: arg.EqFodder,
|
|
||||||
DefaultArg: arg.Arg,
|
|
||||||
CommaFodder: arg.CommaFodder,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return parenR, params, trailingComma, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(sbarzowski) add location to all individual binds
|
// TODO(sbarzowski) add location to all individual binds
|
||||||
|
@ -54,6 +54,7 @@ var tests = []string{
|
|||||||
`function(x) x`,
|
`function(x) x`,
|
||||||
`function(x=5) x`,
|
`function(x=5) x`,
|
||||||
`function(x, y=5) x`,
|
`function(x, y=5) x`,
|
||||||
|
`function(a=5, b) [a, b]`,
|
||||||
|
|
||||||
`local foo = "bar"; foo`,
|
`local foo = "bar"; foo`,
|
||||||
`local foo(bar) = bar; foo(1)`,
|
`local foo(bar) = bar; foo(1)`,
|
||||||
@ -151,7 +152,6 @@ var errorTests = []testError{
|
|||||||
{`function(,)`, `test:1:10-11 Unexpected: (",", ",") while parsing terminal`},
|
{`function(,)`, `test:1:10-11 Unexpected: (",", ",") while parsing terminal`},
|
||||||
{`function(a=)`, `test:1:12-13 Unexpected: (")", ")") while parsing terminal`},
|
{`function(a=)`, `test:1:12-13 Unexpected: (")", ")") while parsing terminal`},
|
||||||
{`function(a=,)`, `test:1:12-13 Unexpected: (",", ",") while parsing terminal`},
|
{`function(a=,)`, `test:1:12-13 Unexpected: (",", ",") while parsing terminal`},
|
||||||
{`function(a=5, b)`, `test:1:15-16 Positional argument after a named argument is not allowed`},
|
|
||||||
{`a b`, `test:1:3-4 Did not expect: (IDENTIFIER, "b")`},
|
{`a b`, `test:1:3-4 Did not expect: (IDENTIFIER, "b")`},
|
||||||
{`foo(a, bar(a b))`, `test:1:14-15 Expected a comma before next function argument, got (IDENTIFIER, "b").`},
|
{`foo(a, bar(a b))`, `test:1:14-15 Expected a comma before next function argument, got (IDENTIFIER, "b").`},
|
||||||
|
|
||||||
|
4
testdata/positional_after_optional.golden
vendored
Normal file
4
testdata/positional_after_optional.golden
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[
|
||||||
|
1,
|
||||||
|
2
|
||||||
|
]
|
1
testdata/positional_after_optional.jsonnet
vendored
Normal file
1
testdata/positional_after_optional.jsonnet
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
local foo(x=1, y) = [x,y]; foo(y=2)
|
Loading…
Reference in New Issue
Block a user