this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

internal/core/adt: remove EvalV2 closeInfo remnants

Remove closeInfo struct pointer and all Spawn* methods
from CloseInfo. These were part of the EvalV2 closedness
tracking and are no longer needed.

- Remove embedded *closeInfo field from CloseInfo
- Remove closeInfo and closeStats struct definitions
- Remove closeNodeType enum (closeRef, closeDef, closeEmbed)
- Remove SpawnEmbed, SpawnGroup, SpawnRef, SpawnSpan methods
- Remove closed_test.go (EvalV2-specific test file)
- Simplify methods to return default values
- Update error handling to remove closeInfo references
- Remove closed map and todo fields from OpContext

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I73332663e77cb38d53dc2e5365968a4ca12291d4
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1219981
Unity-Result: CUE porcuepine <cue.porcuepine@gmail.com>
Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>

+23 -595
+11 -146
internal/core/adt/closed.go
··· 87 87 return v.ClosedRecursive || v.IsInOneOf(DefinitionSpan) 88 88 } 89 89 90 - type closeNodeType uint8 91 - 92 - const ( 93 - // a closeRef node is created when there is a non-definition reference. 94 - closeRef closeNodeType = iota 95 - 96 - // closeDef indicates this node was introduced as a result of referencing 97 - // a definition. 98 - closeDef 99 - 100 - // closeEmbed indicates this node was added as a result of an embedding. 101 - closeEmbed 102 - ) 103 - 104 - // TODO: merge with closeInfo: this is a leftover of the refactoring. 105 90 type CloseInfo struct { 106 - *closeInfo // old implementation (TODO: remove) 107 91 // defID is a unique ID to track anything that gets inserted from this 108 92 // Conjunct. 109 93 opID uint64 // generation of this conjunct, used for sanity check. ··· 138 122 } 139 123 140 124 func (c CloseInfo) Location() Node { 141 - if c.closeInfo == nil { 142 - return nil 143 - } 144 - return c.closeInfo.location 125 + return nil 145 126 } 146 127 147 128 func (c CloseInfo) span() SpanType { 148 - if c.closeInfo == nil { 149 - return 0 150 - } 151 - return c.closeInfo.span 129 + return 0 152 130 } 153 131 154 132 func (c CloseInfo) RootSpanType() SpanType { 155 - if c.closeInfo == nil { 156 - return 0 157 - } 158 - return c.root 133 + return 0 159 134 } 160 135 161 136 // IsInOneOf reports whether c is contained within any of the span types in the ··· 167 142 // TODO(perf): remove: error positions should always be computed on demand 168 143 // in dedicated error types. 169 144 func (c *CloseInfo) AddPositions(ctx *OpContext) { 170 - for s := c.closeInfo; s != nil; s = s.parent { 171 - if loc := s.location; loc != nil { 172 - ctx.AddPosition(loc) 173 - } 174 - } 145 + c.AncestorPositions(func(n Node) { 146 + ctx.AddPosition(n) 147 + }) 175 148 } 176 149 177 - // TODO(perf): use on StructInfo. Then if parent and expression are the same 178 - // it is possible to use cached value. 179 - func (c CloseInfo) SpawnEmbed(x Node) CloseInfo { 180 - c.closeInfo = &closeInfo{ 181 - parent: c.closeInfo, 182 - location: x, 183 - mode: closeEmbed, 184 - root: EmbeddingSpan, 185 - span: c.span() | EmbeddingSpan, 186 - } 187 - return c 188 - } 189 - 190 - // SpawnGroup is used for structs that contain embeddings that may end up 191 - // closing the struct. This is to force that `b` is not allowed in 192 - // 193 - // a: {#foo} & {b: int} 194 - func (c CloseInfo) SpawnGroup(x Expr) CloseInfo { 195 - c.closeInfo = &closeInfo{ 196 - parent: c.closeInfo, 197 - location: x, 198 - span: c.span(), 199 - } 200 - return c 201 - } 202 - 203 - // SpawnSpan is used to track that a value is introduced by a comprehension 204 - // or constraint. Definition and embedding spans are introduced with SpawnRef 205 - // and SpawnEmbed, respectively. 206 - func (c CloseInfo) SpawnSpan(x Node, t SpanType) CloseInfo { 207 - c.closeInfo = &closeInfo{ 208 - parent: c.closeInfo, 209 - location: x, 210 - root: t, 211 - span: c.span() | t, 212 - } 213 - return c 214 - } 215 - 216 - func (c CloseInfo) SpawnRef(arc *Vertex, isDef bool, x Expr) CloseInfo { 217 - span := c.span() 218 - found := false 219 - if !isDef { 220 - xnode := Node(x) // Optimization so we're comparing identical interface types. 221 - // TODO: make this work for non-definitions too. 222 - for p := c.closeInfo; p != nil; p = p.parent { 223 - if p.span == span && p.location == xnode { 224 - found = true 225 - break 226 - } 227 - } 228 - } 229 - if !found { 230 - c.closeInfo = &closeInfo{ 231 - parent: c.closeInfo, 232 - location: x, 233 - span: span, 234 - } 235 - } 236 - if isDef { 237 - c.mode = closeDef 238 - c.closeInfo.root = DefinitionSpan 239 - c.closeInfo.span |= DefinitionSpan 240 - } 241 - return c 150 + // AncestorPositions calls f for each parent of c, starting with the most 151 + // immediate parent. This is used to add positions to errors that are 152 + // associated with a CloseInfo. 153 + func (c *CloseInfo) AncestorPositions(f func(Node)) { 154 + // TODO(evalv3): track positions 242 155 } 243 156 244 157 // IsDef reports whether an expressions is a reference that references a ··· 277 190 ComprehensionSpan 278 191 DefinitionSpan 279 192 ) 280 - 281 - type closeInfo struct { 282 - // location records the expression that led to this node's introduction. 283 - location Node 284 - 285 - // The parent node in the tree. 286 - parent *closeInfo 287 - 288 - // TODO(performance): if references are chained, we could have a separate 289 - // parent pointer to skip the chain. 290 - 291 - // mode indicates whether this node was added as part of an embedding, 292 - // definition or non-definition reference. 293 - mode closeNodeType 294 - 295 - // noCheck means this struct is irrelevant for closedness checking. This can 296 - // happen when: 297 - // - it is a sibling of a new definition. 298 - noCheck bool // don't process for inclusion info 299 - 300 - root SpanType 301 - span SpanType 302 - } 303 - 304 - // closeStats holds the administrative fields for a closeInfo value. Each 305 - // closeInfo is associated with a single closeStats value per unification 306 - // operator. This association is done through an OpContext. This allows the 307 - // same value to be used in multiple concurrent unification operations. 308 - // NOTE: there are other parts of the algorithm that are not thread-safe yet. 309 - type closeStats struct { 310 - // the other fields of this closeStats value are only valid if generation 311 - // is equal to the generation in OpContext. This allows for lazy 312 - // initialization of closeStats. 313 - generation uint64 314 - 315 - // These counts keep track of how many required child nodes need to be 316 - // completed before this node is accepted. 317 - requiredCount int 318 - acceptedCount int 319 - 320 - // accepted is set if this node is accepted. 321 - accepted bool 322 - 323 - required bool 324 - 325 - inTodoList bool // true if added to todo list. 326 - next *closeStats 327 - } 328 193 329 194 // isClosed reports whether v is closed at this level (so not recursively). 330 195 func isClosed(v *Vertex) bool {
-432
internal/core/adt/closed_test.go
··· 1 - // Copyright 2020 CUE Authors 2 - // 3 - // Licensed under the Apache License, Version 2.0 (the "License"); 4 - // you may not use this file except in compliance with the License. 5 - // You may obtain a copy of the License at 6 - // 7 - // http://www.apache.org/licenses/LICENSE-2.0 8 - // 9 - // Unless required by applicable law or agreed to in writing, software 10 - // distributed under the License is distributed on an "AS IS" BASIS, 11 - // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 - // See the License for the specific language governing permissions and 13 - // limitations under the License. 14 - 15 - package adt_test 16 - 17 - import ( 18 - "testing" 19 - 20 - "cuelang.org/go/cue/parser" 21 - "cuelang.org/go/internal" 22 - "cuelang.org/go/internal/core/adt" 23 - "cuelang.org/go/internal/core/compile" 24 - "cuelang.org/go/internal/core/eval" 25 - "cuelang.org/go/internal/core/runtime" 26 - ) 27 - 28 - // TestClosedness is a bootstrap and debugging test for developing the 29 - // closedness algorithm. Most details of closedness is tested in the standard 30 - // test suite. 31 - func TestClosedness(t *testing.T) { 32 - r := runtime.New() 33 - ctx := eval.NewContext(r, nil) 34 - if ctx.Version == internal.EvalV3 { 35 - t.Skip("TODO: fix these tests on evalv3") 36 - } 37 - mkStruct := func(info adt.CloseInfo, s string) *adt.StructInfo { 38 - x, err := parser.ParseExpr("", s) 39 - if err != nil { 40 - t.Fatal(err) 41 - } 42 - expr, err := compile.Expr(nil, r, "", x) 43 - if err != nil { 44 - t.Fatal(err) 45 - } 46 - st := expr.Elem().(*adt.StructLit) 47 - st.Init(ctx) 48 - 49 - return &adt.StructInfo{ 50 - StructLit: st, 51 - CloseInfo: info, 52 - } 53 - } 54 - 55 - mkRef := func(s string) adt.Expr { 56 - f := adt.MakeIdentLabel(r, s, "") 57 - return &adt.FieldReference{Label: f} 58 - } 59 - 60 - type test struct { 61 - f string 62 - found bool 63 - } 64 - 65 - testCases := []struct { 66 - desc string 67 - n func() *adt.Vertex 68 - tests []test 69 - required bool 70 - }{{ 71 - desc: "simple embedding", 72 - // test: { 73 - // a: 1 74 - // c: 1 75 - // 76 - // def 77 - // } 78 - // def: { 79 - // c: 1 80 - // d: 1 81 - // } 82 - n: func() *adt.Vertex { 83 - var ( 84 - root adt.CloseInfo 85 - embed = root.SpawnEmbed(mkRef("dummy")) 86 - def = embed.SpawnRef(nil, false, mkRef("def")) 87 - ) 88 - return &adt.Vertex{ 89 - Structs: []*adt.StructInfo{ 90 - mkStruct(root, "{a: 1, c: 1}"), 91 - mkStruct(def, "{c: 1, d: 1}"), 92 - }, 93 - } 94 - }, 95 - tests: []test{ 96 - {"a", true}, 97 - {"c", true}, 98 - {"d", true}, 99 - {"e", false}, // allowed, but not found 100 - }, 101 - required: false, 102 - }, { 103 - desc: "closing embedding", 104 - // test: { 105 - // a: 1 106 - // c: 1 107 - // 108 - // #def 109 - // } 110 - // #def: { 111 - // c: 1 112 - // d: 1 113 - // } 114 - n: func() *adt.Vertex { 115 - var ( 116 - root adt.CloseInfo 117 - embed = root.SpawnEmbed(mkRef("dummy")) 118 - def = embed.SpawnRef(nil, true, mkRef("#def")) 119 - ) 120 - return &adt.Vertex{ 121 - Structs: []*adt.StructInfo{ 122 - mkStruct(root, "{a: 1, c: 1}"), 123 - mkStruct(def, "{c: 1, d: 1}"), 124 - }, 125 - } 126 - }, 127 - tests: []test{ 128 - {"a", true}, 129 - {"c", true}, 130 - {"d", true}, 131 - {"e", false}, 132 - }, 133 - required: true, 134 - }, { 135 - desc: "narrow down definitions in subfields", 136 - // test: #foo 137 - // test: { 138 - // a: 1 139 - // b: 1 140 - // } 141 - // #foo: { 142 - // c: #bar 143 - // c: #baz 144 - // c: d: 1 145 - // c: e: 1 146 - // } 147 - // #bar: { 148 - // d: 1 149 - // e: 1 150 - // } 151 - // #baz: { 152 - // d: 1 153 - // f: 1 154 - // } 155 - n: func() *adt.Vertex { 156 - var ( 157 - root adt.CloseInfo 158 - foo = root.SpawnRef(nil, true, mkRef("#foo")) 159 - bar = foo.SpawnRef(nil, true, mkRef("#bar")) 160 - baz = foo.SpawnRef(nil, true, mkRef("#baz")) 161 - ) 162 - return &adt.Vertex{ 163 - Structs: []*adt.StructInfo{ 164 - mkStruct(root, "{a: 1, b:1}"), 165 - mkStruct(foo, "{d: 1, e: 1}"), 166 - mkStruct(bar, "{d: 1, e: 1}"), 167 - mkStruct(baz, "{d: 1, f: 1}"), 168 - }, 169 - } 170 - }, 171 - tests: []test{ 172 - {"a", false}, 173 - {"b", false}, 174 - {"d", true}, 175 - {"e", false}, 176 - {"f", false}, 177 - }, 178 - required: true, 179 - }, { 180 - desc: "chained references", 181 - // test: foo 182 - // test: { 183 - // a: 1 184 - // b: 1 185 - // } 186 - // foo: bar 187 - // bar: { 188 - // #baz 189 - // e: 1 190 - // } 191 - // #baz: { 192 - // c: 1 193 - // d: 1 194 - // } 195 - n: func() *adt.Vertex { 196 - var ( 197 - root adt.CloseInfo 198 - foo = root.SpawnRef(nil, false, mkRef("foo")) 199 - bar = foo.SpawnRef(nil, false, mkRef("bar")) 200 - baz = bar.SpawnEmbed(mkRef("#baz")) 201 - def = baz.SpawnRef(nil, true, mkRef("#baz")) 202 - ) 203 - return &adt.Vertex{ 204 - Structs: []*adt.StructInfo{ 205 - mkStruct(bar, "{e: 1}"), 206 - mkStruct(def, "{c: 1, d: 1}"), 207 - mkStruct(root, "{a: 1, c: 1}"), 208 - }, 209 - } 210 - }, 211 - tests: []test{ 212 - {"a", false}, 213 - {"c", true}, 214 - {"d", true}, 215 - {"e", true}, 216 - {"f", false}, 217 - }, 218 - required: true, 219 - }, { 220 - desc: "conjunction embedding", 221 - // test: foo 222 - // test: { 223 - // a: 1 224 - // b: 1 225 - // } 226 - // foo: { 227 - // #bar & #baz 228 - // f: 1 229 - // } 230 - // #bar: { 231 - // c: 1 232 - // d: 1 233 - // } 234 - // #baz: { 235 - // d: 1 236 - // } 237 - // #baz: { 238 - // e: 1 239 - // } 240 - n: func() *adt.Vertex { 241 - var ( 242 - root adt.CloseInfo 243 - foo = root.SpawnRef(nil, false, mkRef("foo")) 244 - embed = foo.SpawnEmbed(mkRef("dummy")) 245 - bar = embed.SpawnRef(nil, true, mkRef("#bar")) 246 - baz = embed.SpawnRef(nil, true, mkRef("#baz")) 247 - ) 248 - return &adt.Vertex{ 249 - Structs: []*adt.StructInfo{ 250 - mkStruct(root, "{a: 1, c: 1}"), 251 - mkStruct(foo, "{f: 1}"), 252 - mkStruct(bar, "{c: 1, d: 1}"), 253 - mkStruct(baz, "{d: 1}"), 254 - mkStruct(baz, "{e: 1}"), 255 - }, 256 - } 257 - }, 258 - tests: []test{ 259 - {"a", false}, 260 - {"c", false}, 261 - {"d", true}, 262 - {"e", false}, 263 - {"f", true}, 264 - {"g", false}, 265 - }, 266 - required: true, 267 - }, { 268 - desc: "local closing", 269 - // test: { 270 - // #def 271 - // a: 1 272 - // b: 1 273 - // } 274 - // test: { 275 - // c: 1 276 - // d: 1 277 - // } 278 - // #def: { 279 - // c: 1 280 - // e: 1 281 - // } 282 - n: func() *adt.Vertex { 283 - var ( 284 - root adt.CloseInfo 285 - // isolate local struct. 286 - spawned = root.SpawnRef(nil, false, mkRef("dummy")) 287 - embed = spawned.SpawnEmbed(mkRef("dummy")) 288 - def = embed.SpawnRef(nil, true, mkRef("#def")) 289 - ) 290 - return &adt.Vertex{ 291 - Structs: []*adt.StructInfo{ 292 - mkStruct(spawned, "{a: 1, b: 1}"), 293 - mkStruct(root, "{c: 1, d: 1}"), 294 - mkStruct(def, "{c: 1, e: 1}"), 295 - }, 296 - } 297 - }, 298 - tests: []test{ 299 - {"d", false}, 300 - {"a", true}, 301 - {"c", true}, 302 - {"e", true}, 303 - {"f", false}, 304 - }, 305 - required: true, 306 - }, { 307 - desc: "local closing of def", 308 - // #test: { 309 - // #def 310 - // a: 1 311 - // b: 1 312 - // } 313 - // #test: { 314 - // c: 1 315 - // d: 1 316 - // } 317 - // #def: { 318 - // c: 1 319 - // e: 1 320 - // } 321 - n: func() *adt.Vertex { 322 - var ( 323 - root adt.CloseInfo 324 - test = root.SpawnRef(nil, true, mkRef("#test")) 325 - // isolate local struct. 326 - spawned = test.SpawnRef(nil, false, mkRef("dummy")) 327 - embed = spawned.SpawnEmbed(mkRef("dummy")) 328 - def = embed.SpawnRef(nil, true, mkRef("#def")) 329 - ) 330 - return &adt.Vertex{ 331 - Structs: []*adt.StructInfo{ 332 - mkStruct(spawned, "{a: 1, b: 1}"), 333 - mkStruct(test, "{c: 1, d: 1}"), 334 - mkStruct(def, "{c: 1, e: 1}"), 335 - }, 336 - } 337 - }, 338 - tests: []test{ 339 - {"a", true}, 340 - {"d", false}, 341 - {"c", true}, 342 - {"e", true}, 343 - {"f", false}, 344 - }, 345 - required: true, 346 - }, { 347 - desc: "branching", 348 - // test: #foo 349 - // #foo: { 350 - // c: #bar1 351 - // c: #bar2 352 - // } 353 - // #bar1: { 354 - // d: #baz1 355 - // d: #baz2 356 - // } 357 - // #bar2: { 358 - // d: #baz3 359 - // d: {#baz4} 360 - // } 361 - // #baz1: e: 1 362 - // #baz2: e: 1 363 - // #baz3: e: 1 364 - // #baz4: e: 1 365 - n: func() *adt.Vertex { 366 - var ( 367 - root adt.CloseInfo 368 - foo = root.SpawnRef(nil, true, mkRef("#foo")) 369 - bar1 = foo.SpawnRef(nil, true, mkRef("#bar1")) 370 - bar2 = foo.SpawnRef(nil, true, mkRef("#bar2")) 371 - baz1 = bar1.SpawnRef(nil, true, mkRef("#baz1")) 372 - baz2 = bar1.SpawnRef(nil, true, mkRef("#baz2")) 373 - baz3 = bar2.SpawnRef(nil, true, mkRef("#baz3")) 374 - spw3 = bar2.SpawnRef(nil, false, mkRef("spw3")) 375 - emb2 = spw3.SpawnEmbed(mkRef("emb")) 376 - baz4 = emb2.SpawnRef(nil, true, mkRef("#baz4")) 377 - ) 378 - return &adt.Vertex{ 379 - Structs: []*adt.StructInfo{ 380 - mkStruct(root, "{}"), 381 - mkStruct(foo, "{}"), 382 - mkStruct(bar1, "{}"), 383 - mkStruct(bar2, "{}"), 384 - mkStruct(baz1, "{e: 1, f: 1, g: 1}"), 385 - mkStruct(baz2, "{e: 1, f: 1, g: 1}"), 386 - mkStruct(baz3, "{e: 1, g: 1}"), 387 - mkStruct(baz4, "{e: 1, f: 1}"), 388 - }, 389 - } 390 - }, 391 - tests: []test{ 392 - {"a", false}, 393 - {"e", true}, 394 - {"f", false}, 395 - {"g", false}, 396 - }, 397 - required: true, 398 - }} 399 - // TODO: 400 - // dt1: { 401 - // #Test: { 402 - // #SSH: !~"^ssh://" 403 - // source: #SSH | #Test 404 - // } 405 - 406 - // foo: #Test & { 407 - // source: "http://blablabla" 408 - // } 409 - 410 - // bar: #Test & { 411 - // source: foo 412 - // } 413 - // } 414 - // 415 - // ----- 416 - for _, tc := range testCases { 417 - t.Run(tc.desc, func(t *testing.T) { 418 - n := tc.n() 419 - for _, sub := range tc.tests { 420 - t.Run(sub.f, func(t *testing.T) { 421 - f := adt.MakeIdentLabel(r, sub.f, "") 422 - 423 - ok, required := adt.Accept(ctx, n, f) 424 - if ok != sub.found || required != tc.required { 425 - t.Errorf("got (%v, %v); want (%v, %v)", 426 - ok, required, sub.found, tc.required) 427 - } 428 - }) 429 - } 430 - }) 431 - } 432 - }
+1 -2
internal/core/adt/composite.go
··· 1423 1423 func findConjunct(cs []Conjunct, c Conjunct) (int, Conjunct) { 1424 1424 for i, x := range cs { 1425 1425 // TODO: disregard certain fields from comparison (e.g. Refs)? 1426 - if x.CloseInfo.closeInfo == c.CloseInfo.closeInfo && // V2 1427 - x.x == c.x && 1426 + if x.x == c.x && 1428 1427 x.Env.Up == c.Env.Up && x.Env.Vertex == c.Env.Vertex { 1429 1428 return i, x 1430 1429 }
+1 -3
internal/core/adt/context.go
··· 143 143 // TODO(perf): have two generations: one for each pass of the closedness 144 144 // algorithm, so that the results of the first pass can be reused for all 145 145 // features of a node. 146 - opID uint64 147 - closed map[*closeInfo]*closeStats 148 - todo *closeStats 146 + opID uint64 149 147 150 148 // evalDepth indicates the current depth of evaluation. It is used to 151 149 // detect structural cycles and their severity.s
+7 -9
internal/core/adt/errors.go
··· 223 223 addPositions(err, c) 224 224 } 225 225 } 226 - if c.CloseInfo.closeInfo != nil { 227 - err.AddPosition(c.CloseInfo.location) 226 + if p := c.CloseInfo.Location(); p != nil { 227 + err.AddPosition(p) 228 228 } 229 229 } 230 230 ··· 235 235 if f, ok := c.x.(*Field); ok && f.ArcType == ArcRequired { 236 236 err.AddPosition(c.x) 237 237 } 238 - if c.CloseInfo.closeInfo != nil { 239 - err.AddPosition(c.CloseInfo.location) 238 + if p := c.CloseInfo.Location(); p != nil { 239 + err.AddPosition(p) 240 240 } 241 241 return true 242 242 }) ··· 324 324 } 325 325 326 326 func (v *ValueError) AddClosedPositions(c CloseInfo) { 327 - for s := c.closeInfo; s != nil; s = s.parent { 328 - if loc := s.location; loc != nil { 329 - v.AddPosition(loc) 330 - } 331 - } 327 + c.AncestorPositions(func(n Node) { 328 + v.AddPosition(n) 329 + }) 332 330 } 333 331 334 332 func (c *OpContext) errNode() *Vertex {
+2 -2
internal/core/adt/sched.go
··· 603 603 604 604 // The Conjunct processed by this task. 605 605 env *Environment 606 - id CloseInfo // TODO: rename to closeInfo? 607 - x Node // The conjunct Expression or Value. 606 + id CloseInfo 607 + x Node // The conjunct Expression or Value. 608 608 609 609 // For Comprehensions: 610 610 comp *envComprehension
+1 -1
internal/core/adt/typocheck.go
··· 805 805 if w == nil { 806 806 return 807 807 } 808 - // Merge missing closeInfos 808 + // Merge missing conjunct infos 809 809 outer: 810 810 for _, wci := range nw.conjunctInfo { 811 811 for _, vci := range nv.conjunctInfo {