Skip to content
This repository was archived by the owner on Nov 18, 2021. It is now read-only.

Commit b1730b6

Browse files
committed
tools/trim: optional fields should not remove non-optional
The solution is rather brute-force, we need to find something more fine-grained eventually. But for now this avoids an erroneous removal. Fixing this will be easier when optional fields are represented as normal fields with an optional flag, as they were in v0.2. Fixes #855 Change-Id: I65829858b1856fcd09aa121f1e1c53fd49864c87 Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9221 Reviewed-by: CUE cueckoo <cueckoo@gmail.com> Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
1 parent f9164c6 commit b1730b6

2 files changed

Lines changed: 55 additions & 7 deletions

File tree

tools/trim/testdata/optional.txtar

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// Optional fields should retain status after removal of unified
2+
// content.
3+
4+
// Issue #855
5+
6+
-- cue.mod/module.cue --
7+
module: "mod.com"
8+
-- a.cue --
9+
package pkg
10+
11+
a: [...#A]
12+
13+
a: [{
14+
annotations: {}
15+
}]
16+
17+
#A: annotations?: [string]: string
18+
19+
b: #B
20+
b: bb: c: 2 // c can be removed, bb not.
21+
#B: bb?: c: 2
22+
23+
-- out/trim --
24+
== a.cue
25+
package pkg
26+
27+
a: [...#A]
28+
29+
a: [{
30+
annotations: {}
31+
}]
32+
33+
#A: annotations?: [string]: string
34+
35+
b: #B
36+
b: bb: {} // c can be removed, bb not.
37+
#B: bb?: c: 2

tools/trim/trim.go

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ func (t *trimmer) markRemove(c adt.Conjunct) {
129129
}
130130

131131
func (t *trimmer) markKeep(c adt.Conjunct) {
132-
if isDominator(c) {
132+
if isDom, _ := isDominator(c); isDom {
133133
return
134134
}
135135
if src := c.Expr().Source(); src != nil {
@@ -143,8 +143,15 @@ func (t *trimmer) markKeep(c adt.Conjunct) {
143143
const dominatorNode = adt.ComprehensionSpan | adt.DefinitionSpan | adt.ConstraintSpan
144144

145145
// isDominator reports whether a node can remove other nodes.
146-
func isDominator(c adt.Conjunct) bool {
147-
return c.CloseInfo.IsInOneOf(dominatorNode)
146+
func isDominator(c adt.Conjunct) (ok, mayRemove bool) {
147+
if !c.CloseInfo.IsInOneOf(dominatorNode) {
148+
return false, false
149+
}
150+
switch c.Field().(type) {
151+
case *adt.OptionalField: // bulk constraints handled elsewhere.
152+
return true, false
153+
}
154+
return true, true
148155
}
149156

150157
// Removable reports whether a non-dominator conjunct can be removed. This is
@@ -158,10 +165,10 @@ func removable(c adt.Conjunct, v *adt.Vertex) bool {
158165
// themselves as it will eliminate the reason for the trigger.
159166
func (t *trimmer) allowRemove(v *adt.Vertex) bool {
160167
for _, c := range v.Conjuncts {
161-
isDom := isDominator(c)
168+
_, allowRemove := isDominator(c)
162169
loc := c.CloseInfo.Location() != c.Expr()
163170
isSpan := c.CloseInfo.RootSpanType() != adt.ConstraintSpan
164-
if isDom && (loc || isSpan) {
171+
if allowRemove && (loc || isSpan) {
165172
return true
166173
}
167174
}
@@ -202,9 +209,11 @@ func (t *trimmer) addDominators(d, v *adt.Vertex, hasDisjunction bool) (doms *ad
202209
doms.Conjuncts = append(doms.Conjuncts, d.Conjuncts...)
203210
}
204211

212+
hasDoms := false
205213
for _, c := range v.Conjuncts {
214+
isDom, _ := isDominator(c)
206215
switch {
207-
case isDominator(c):
216+
case isDom:
208217
doms.AddConjunct(c)
209218
default:
210219
if r, ok := c.Expr().(adt.Resolver); ok {
@@ -236,6 +245,7 @@ func (t *trimmer) addDominators(d, v *adt.Vertex, hasDisjunction bool) (doms *ad
236245
ambiguous = true
237246
}
238247

248+
_ = hasDoms
239249
return doms, hasSubs, ambiguous, strict || ambiguous
240250
}
241251

@@ -310,7 +320,8 @@ func (t *trimmer) findSubordinates(doms, v *adt.Vertex, hasDisjunction bool) (re
310320
}
311321

312322
for _, c := range v.Conjuncts {
313-
if !isDominator(c) && removable(c, v) {
323+
_, allowRemove := isDominator(c)
324+
if !allowRemove && removable(c, v) {
314325
t.markRemove(c)
315326
}
316327
}

0 commit comments

Comments
 (0)