From 2a41f710e1c27d478cd48e8993cee526a9c0f04d Mon Sep 17 00:00:00 2001 From: Johan Fylling Date: Wed, 3 Jun 2026 17:09:51 +0200 Subject: [PATCH] oracle: Fix find-definition on expressions inside `ast.Not` nodes (#8731) `ast.Node.Location` wasn't properly copied during `ResolveRefs` compiler stage Signed-off-by: Johan Fylling --- v1/ast/compile.go | 1 + v1/ast/oracle/oracle_test.go | 83 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/v1/ast/compile.go b/v1/ast/compile.go index 6bc705a232..8aa60e0f44 100644 --- a/v1/ast/compile.go +++ b/v1/ast/compile.go @@ -5540,6 +5540,7 @@ func resolveRefsInExpr(globals map[Var]*usedRef, ignore *declaredVarStack, expr cpy.Terms = &Not{ Body: resolveRefsInBody(globals, ignore, ts.Body), ExplicitBody: ts.ExplicitBody, + Location: ts.Location, } case *LogicalAnd: cpy.Terms = &LogicalAnd{ diff --git a/v1/ast/oracle/oracle_test.go b/v1/ast/oracle/oracle_test.go index c01d896d38..334aef6943 100644 --- a/v1/ast/oracle/oracle_test.go +++ b/v1/ast/oracle/oracle_test.go @@ -878,6 +878,89 @@ str1 := $"{a} {b}"`, Text: []byte("b := false"), }, }, + + { + note: "negation - legacy", + modules: map[string]string{ + "buffer.rego": `package test + +p if { + not f(1) +} + +f(x) := x`, + }, + pos: 26, // position of 'f' inside the negated expression in p + exp: &ast.Location{ + File: "buffer.rego", + Row: 7, + Col: 1, + Text: []byte("f(x) := x"), + }, + }, + { + note: "negation - import, implicit body", + modules: map[string]string{ + "buffer.rego": `package test +import future.keywords.not + +p if { + not f(1) +} + +f(x) := x`, + }, + pos: 53, // position of 'f' inside the negated expression in p + exp: &ast.Location{ + File: "buffer.rego", + Row: 8, + Col: 1, + Text: []byte("f(x) := x"), + }, + }, + { + note: "negation - import, explicit body", + modules: map[string]string{ + "buffer.rego": `package test +import future.keywords.not + +p if { + not { + f(1) + } +} + +f(x) := x`, + }, + pos: 57, // position of 'f' inside the negated expression in p + exp: &ast.Location{ + File: "buffer.rego", + Row: 10, + Col: 1, + Text: []byte("f(x) := x"), + }, + }, + { + note: "negation - import, explicit body, local var", + modules: map[string]string{ + "buffer.rego": `package test +import future.keywords.not + +p if { + not { + x := 42 + x != 2 + } +}`, + }, + pos: 67, // position of 'x' inside the negated expression in p + exp: &ast.Location{ + File: "buffer.rego", + Row: 6, + Col: 3, + Text: []byte("x"), + }, + }, } for _, tc := range cases {