Skip to content

Commit 6e48c0d

Browse files
committed
cue: fix Allows for new evaluator
The new evaluator computes closedness quite differently from the old one. This CL adapts the API to use the new data. Note that the data the new evaluator generates is considerably more convenient. That is why the logic is quite a bit simpler. The logic could probably be simplified more. Also note that HasEllipsis seems to be not computed correclty entirely. Although it seems that many tests improve if we add the check to isClosed or IsClosedStruct, there are some cases where this causes errors. This seems to be the case with one of the tests in TestAllows. As this only manifests itself when structure sharing is disabled, we just mark this test as todo and leave the investigation for later. Issue #3060 Issue #543 Issue #2884 Signed-off-by: Marcel van Lohuizen <[email protected]> Change-Id: I98e8c25e0680674e2aaa9f743a49b39920d7b266 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1194080 Reviewed-by: Daniel Martí <[email protected]> TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]>
1 parent 82bcda5 commit 6e48c0d

File tree

5 files changed

+58
-7
lines changed

5 files changed

+58
-7
lines changed

cue/matrix_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,9 @@ func TODO_Sharing(t *testing.T, c *evalConfig) {
6969
t.Skip("Skipping v3 with sharing")
7070
}
7171
}
72+
73+
func TODO_NoSharing(t *testing.T, c *evalConfig) {
74+
if c.version == internal.DevVersion && !c.flags.Sharing {
75+
t.Skip("Skipping v3 without sharing")
76+
}
77+
}

cue/types_test.go

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,13 +1430,13 @@ func TestFillPathError(t *testing.T) {
14301430
}
14311431

14321432
func TestAllows(t *testing.T) {
1433-
r := &Runtime{}
1434-
14351433
testCases := []struct {
14361434
desc string
14371435
in string
14381436
sel Selector
14391437
allow bool
1438+
1439+
todo_nosharing bool
14401440
}{{
14411441
desc: "allow new field in open struct",
14421442
in: `
@@ -1463,6 +1463,14 @@ func TestAllows(t *testing.T) {
14631463
})
14641464
`,
14651465
sel: Str("b"),
1466+
}, {
1467+
desc: "allow field in pattern",
1468+
in: `
1469+
x: #X
1470+
#X: [>"a"]: 1
1471+
`,
1472+
sel: Str("b"),
1473+
allow: true,
14661474
}, {
14671475
desc: "allow index in open list",
14681476
in: `
@@ -1615,6 +1623,8 @@ func TestAllows(t *testing.T) {
16151623
`,
16161624
sel: AnyString,
16171625
allow: true,
1626+
1627+
todo_nosharing: true,
16181628
}, {
16191629
desc: "disallow label in disjunction",
16201630
in: `
@@ -1657,7 +1667,10 @@ func TestAllows(t *testing.T) {
16571667

16581668
for _, tc := range testCases {
16591669
runMatrix(t, tc.desc, func(t *testing.T, cfg *evalConfig) {
1660-
v := compileT(t, r, tc.in).Value()
1670+
if tc.todo_nosharing {
1671+
TODO_NoSharing(t, cfg)
1672+
}
1673+
v := compileT(t, cfg.runtime(), tc.in).Value()
16611674
v = v.LookupPath(path)
16621675

16631676
got := v.Allows(tc.sel)
@@ -2211,8 +2224,6 @@ func TestUnify(t *testing.T) {
22112224
}}
22122225
// TODO(tdtest): use cuetest.Run when supported.
22132226
doMatrix(t, func(t *testing.T, cfg *evalConfig) {
2214-
TODO_V3(t, cfg)
2215-
22162227
tdtest.Run(t, testCases, func(t *cuetest.T, tc *testCase) {
22172228
v := cfg.getValue(t.T, tc.value)
22182229
x := v.LookupPath(ParsePath(tc.pathA))
@@ -2267,8 +2278,6 @@ func TestUnifyAccept(t *testing.T) {
22672278
}}
22682279
// TODO(tdtest): use cuetest.Run when supported.
22692280
doMatrix(t, func(t *testing.T, cfg *evalConfig) {
2270-
TODO_V3(t, cfg)
2271-
22722281
tdtest.Run(t, testCases, func(t *cuetest.T, tc *testCase) {
22732282
v := cfg.getValue(t.T, tc.value)
22742283
x := v.LookupPath(ParsePath("#v"))

internal/core/adt/closed.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,9 @@ func isClosed(v *Vertex) bool {
344344
// Accept determines whether f is allowed in n. It uses the OpContext for
345345
// caching administrative fields.
346346
func Accept(ctx *OpContext, n *Vertex, f Feature) (found, required bool) {
347+
if ctx.isDevVersion() {
348+
return n.accept(ctx, f), true
349+
}
347350
ctx.generation++
348351
ctx.todo = nil
349352

internal/core/adt/composite.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,10 +964,16 @@ func (v *Vertex) IsClosedList() bool {
964964

965965
// TODO: return error instead of boolean? (or at least have version that does.)
966966
func (v *Vertex) Accept(ctx *OpContext, f Feature) bool {
967+
// TODO(#543): remove this check.
968+
if f.IsDef() {
969+
return true
970+
}
971+
967972
if f.IsHidden() || f.IsLet() {
968973
return true
969974
}
970975

976+
v = v.Indirect()
971977
if x, ok := v.BaseValue.(*Disjunction); ok {
972978
for _, v := range x.Values {
973979
if x, ok := v.(*Vertex); ok && x.Accept(ctx, f) {
@@ -999,6 +1005,14 @@ func (v *Vertex) Accept(ctx *OpContext, f Feature) bool {
9991005
}
10001006
}
10011007

1008+
// TODO: move this check to IsClosedStruct. Right now this causes too many
1009+
// changes in the debug output, and it also appears to be not entirely
1010+
// correct.
1011+
if v.HasEllipsis {
1012+
return true
1013+
1014+
}
1015+
10021016
if !v.IsClosedStruct() || v.Lookup(f) != nil {
10031017
return true
10041018
}

internal/core/adt/unify.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,3 +721,22 @@ func (v *Vertex) lookup(c *OpContext, pos token.Pos, f Feature, flags combinedFl
721721
v.reportFieldIndexError(c, pos, f)
722722
return nil
723723
}
724+
725+
// accept reports whether the given feature is allowed by the pattern
726+
// constraints.
727+
func (v *Vertex) accept(ctx *OpContext, f Feature) bool {
728+
// TODO: this is already handled by callers at the moment, but it may be
729+
// better design to move this here.
730+
// if v.LookupRaw(f) != nil {
731+
// return true, true
732+
// }
733+
734+
v = v.Indirect()
735+
736+
pc := v.PatternConstraints
737+
if pc == nil {
738+
return false
739+
}
740+
741+
return matchPattern(ctx, pc.Allowed, f)
742+
}

0 commit comments

Comments
 (0)