From 5a089642477331958dba1d83b3535f2ea525912b Mon Sep 17 00:00:00 2001 From: Stephan Renatus Date: Tue, 22 Nov 2022 12:00:34 +0100 Subject: [PATCH] ast/parser: generate new wildcards for else The previous behaviour had triggered a check in the formatter for multiple use of wildcard variables: f(_) := true { true } else := false The formatter found `$1`, the `_` argument of f, again in else, and thus changed it into `_1`: f(_1) := true { true } else := false There's no extra meaning to the copied wildcards in `else`, they should not count as second usage. Signed-off-by: Stephan Renatus --- ast/parser.go | 5 +++++ ast/parser_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/ast/parser.go b/ast/parser.go index c1b17bfd74..c4671ffa31 100644 --- a/ast/parser.go +++ b/ast/parser.go @@ -699,6 +699,11 @@ func (p *Parser) parseElse(head *Head) *Rule { rule.SetLoc(p.s.Loc()) rule.Head = head.Copy() + for i := range rule.Head.Args { + if v, ok := rule.Head.Args[i].Value.(Var); ok && v.IsWildcard() { + rule.Head.Args[i].Value = Var(p.genwildcard()) + } + } rule.Head.SetLoc(p.s.Loc()) defer func() { diff --git a/ast/parser_test.go b/ast/parser_test.go index eec88a9fd5..4a541f9cdd 100644 --- a/ast/parser_test.go +++ b/ast/parser_test.go @@ -1634,6 +1634,30 @@ func TestRule(t *testing.T) { }) assertParseError(t, "invalid rule body no separator", `p { a = "foo"bar }`) assertParseError(t, "invalid rule body no newline", `p { a b c }`) + + assertParseRule(t, "wildcard in else args", `f(_) { true } else := false`, &Rule{ + Head: &Head{ + Name: "f", + Reference: Ref{VarTerm("f")}, + Args: Args{ + VarTerm("$0"), + }, + Value: BooleanTerm(true), + }, + Body: MustParseBody(`true`), + Else: &Rule{ + Head: &Head{ + Name: "f", + Assign: true, + Reference: Ref{VarTerm("f")}, + Args: Args{ + VarTerm("$1"), + }, + Value: BooleanTerm(false), + }, + Body: MustParseBody(`true`), + }, + }) } func TestRuleContains(t *testing.T) { @@ -4830,6 +4854,9 @@ func assertParseRule(t *testing.T, msg string, input string, correct *Rule, opts if !rule.Head.Ref().Equal(correct.Head.Ref()) { t.Errorf("Error on test \"%s\": rule heads not equal: ref = %v (parsed), ref = %v (correct)", msg, rule.Head.Ref(), correct.Head.Ref()) } + if !rule.Head.Equal(correct.Head) { + t.Errorf("Error on test \"%s\": rule heads not equal: %v (parsed), %v (correct)", msg, rule.Head, correct.Head) + } if !rule.Equal(correct) { t.Errorf("Error on test \"%s\": rules not equal: %v (parsed), %v (correct)", msg, rule, correct) }