Identify conflicting sequence registration positions

This commit is contained in:
2026-10-24 00:15:23 +00:00
parent 42663cf07c
commit 57edb8ec19
3 changed files with 51 additions and 7 deletions

View File

@@ -1,5 +1,7 @@
package engine
import "fmt"
type sequenceSelectorSegmentKind uint8
const (
@@ -87,9 +89,13 @@ func DefinitionWithSequenceIdentityRegistrations[T any](definition Definition[T]
func compileSequenceIdentityPolicy(registrations []sequenceIdentityRegistration) (sequencePolicy, []Diagnostic) {
policy := sequencePolicy{}
compiled := make([]sequenceIdentityRegistration, 0, len(registrations))
type positionedRegistration struct {
registration sequenceIdentityRegistration
position int
}
compiled := make([]positionedRegistration, 0, len(registrations))
var diagnostics []Diagnostic
for _, registration := range registrations {
for position, registration := range registrations {
selector := cloneSequenceIdentitySelector(registration.selector)
if registration.invalidPath != nil {
diagnostics = append(diagnostics, Diagnostic{
@@ -113,18 +119,21 @@ func compileSequenceIdentityPolicy(registrations []sequenceIdentityRegistration)
})
continue
}
compiled = append(compiled, sequenceIdentityRegistration{selector: selector, identityFields: fields})
compiled = append(compiled, positionedRegistration{
registration: sequenceIdentityRegistration{selector: selector, identityFields: fields},
position: position + 1,
})
}
for leftIndex := 0; leftIndex < len(compiled); leftIndex++ {
for rightIndex := leftIndex + 1; rightIndex < len(compiled); rightIndex++ {
left, right := compiled[leftIndex], compiled[rightIndex]
left, right := compiled[leftIndex].registration, compiled[rightIndex].registration
if !sequenceIdentitySelectorsOverlap(left.selector, right.selector) || equalSequenceIdentityFields(left.identityFields, right.identityFields) {
continue
}
diagnostics = append(diagnostics, Diagnostic{
Code: CodeOptionsInvalid, Severity: SeverityError, Path: selectorDiagnosticPath(left.selector),
Message: "overlapping sequence registrations must use the same identity fields",
Message: fmt.Sprintf("sequence registrations %d and %d overlap with conflicting identity fields", compiled[leftIndex].position, compiled[rightIndex].position),
})
}
}
@@ -133,7 +142,8 @@ func compileSequenceIdentityPolicy(registrations []sequenceIdentityRegistration)
}
unique := make([]sequenceIdentityRegistration, 0, len(compiled))
for _, registration := range compiled {
for _, positioned := range compiled {
registration := positioned.registration
duplicate := false
for _, existing := range unique {
if sequenceIdentitySelectorsEqual(existing.selector, registration.selector) && equalSequenceIdentityFields(existing.identityFields, registration.identityFields) {

View File

@@ -178,6 +178,34 @@ func TestCompileSequenceIdentityPolicyRejectsConflictingOverlapsWithoutInput(t *
}
}
func TestSequenceOverlapDiagnosticsIdentifyOriginalRegistrationPositions(t *testing.T) {
t.Parallel()
_, diagnostics := compileSequenceIdentityPolicy([]sequenceIdentityRegistration{
{selector: sequenceIdentitySelector{literalSequenceSelector("invalid")}},
{selector: sequenceIdentitySelector{literalSequenceSelector("unrelated")}, identityFields: []string{"id"}},
{selector: sequenceIdentitySelector{literalSequenceSelector("collections"), anyMappingSequenceSelector(), literalSequenceSelector("items")}, identityFields: []string{"id"}},
{selector: sequenceIdentitySelector{literalSequenceSelector("collections"), literalSequenceSelector("foo"), literalSequenceSelector("items")}, identityFields: []string{"name"}},
{selector: sequenceIdentitySelector{literalSequenceSelector("collections"), literalSequenceSelector("bar"), literalSequenceSelector("items")}, identityFields: []string{"code"}},
})
if len(diagnostics) != 3 {
t.Fatalf("diagnostics = %#v, want the invalid registration and two conflicts", diagnostics)
}
for _, pair := range []string{"3 and 4", "3 and 5"} {
found := false
for _, diagnostic := range diagnostics {
if strings.Contains(diagnostic.Message, pair) {
found = true
if diagnostic.Code != CodeOptionsInvalid || diagnostic.Path.String() != "" || len(diagnostic.Related) != 0 {
t.Fatalf("definition overlap invented input coordinates: %#v", diagnostic)
}
}
}
if !found {
t.Errorf("conflicting registration positions %s not identified: %#v", pair, diagnostics)
}
}
}
func TestCompileSequenceIdentityPolicyAllowsDisjointSelectorsAndRoot(t *testing.T) {
policy, diagnostics := compileSequenceIdentityPolicy([]sequenceIdentityRegistration{
{selector: sequenceIdentitySelector{}, identityFields: []string{"id"}},