github.com/joomcode/cue@v0.4.4-0.20221111115225-539fe3512047/internal/core/adt/context.go (about) 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 16 17 import ( 18 "fmt" 19 "log" 20 "os" 21 "reflect" 22 "regexp" 23 "sort" 24 "strings" 25 26 "github.com/cockroachdb/apd/v2" 27 "golang.org/x/text/encoding/unicode" 28 29 "github.com/joomcode/cue/cue/ast" 30 "github.com/joomcode/cue/cue/errors" 31 "github.com/joomcode/cue/cue/token" 32 ) 33 34 // Debug sets whether extra aggressive checking should be done. 35 // This should typically default to true for pre-releases and default to 36 // false otherwise. 37 var Debug bool = os.Getenv("CUE_DEBUG") != "0" 38 39 // Verbosity sets the log level. There are currently only two levels: 40 // 0: no logging 41 // 1: logging 42 var Verbosity int 43 44 // DebugSort specifies that arcs be sorted consistently between implementations. 45 // 0: default 46 // 1: sort by Feature: this should be consistent between implementations where 47 // there is no change in the compiler and indexing code. 48 // 2: alphabetical 49 var DebugSort int 50 51 func DebugSortArcs(c *OpContext, n *Vertex) { 52 if n.IsList() { 53 return 54 } 55 switch a := n.Arcs; DebugSort { 56 case 1: 57 sort.SliceStable(a, func(i, j int) bool { 58 return a[i].Label < a[j].Label 59 }) 60 case 2: 61 sort.SliceStable(a, func(i, j int) bool { 62 return a[i].Label.SelectorString(c.Runtime) < 63 a[j].Label.SelectorString(c.Runtime) 64 }) 65 } 66 } 67 68 func DebugSortFields(c *OpContext, a []Feature) { 69 switch DebugSort { 70 case 1: 71 sort.SliceStable(a, func(i, j int) bool { 72 return a[i] < a[j] 73 }) 74 case 2: 75 sort.SliceStable(a, func(i, j int) bool { 76 return a[i].SelectorString(c.Runtime) < 77 a[j].SelectorString(c.Runtime) 78 }) 79 } 80 } 81 82 // Assert panics if the condition is false. Assert can be used to check for 83 // conditions that are considers to break an internal variant or unexpected 84 // condition, but that nonetheless probably will be handled correctly down the 85 // line. For instance, a faulty condition could lead to to error being caught 86 // down the road, but resulting in an inaccurate error message. In production 87 // code it is better to deal with the bad error message than to panic. 88 // 89 // It is advisable for each use of Assert to document how the error is expected 90 // to be handled down the line. 91 func Assertf(b bool, format string, args ...interface{}) { 92 if Debug && !b { 93 panic(fmt.Sprintf("assertion failed: "+format, args...)) 94 } 95 } 96 97 // Assertf either panics or reports an error to c if the condition is not met. 98 func (c *OpContext) Assertf(pos token.Pos, b bool, format string, args ...interface{}) { 99 if !b { 100 if Debug { 101 panic(fmt.Sprintf("assertion failed: "+format, args...)) 102 } 103 c.addErrf(0, pos, format, args...) 104 } 105 } 106 107 func init() { 108 log.SetFlags(log.Lshortfile) 109 } 110 111 func Logf(format string, args ...interface{}) { 112 if Verbosity == 0 { 113 return 114 } 115 s := fmt.Sprintf(format, args...) 116 _ = log.Output(2, s) 117 } 118 119 var pMap = map[*Vertex]int{} 120 121 func (c *OpContext) Logf(v *Vertex, format string, args ...interface{}) { 122 if Verbosity == 0 { 123 return 124 } 125 if v == nil { 126 s := fmt.Sprintf(strings.Repeat("..", c.nest)+format, args...) 127 _ = log.Output(2, s) 128 return 129 } 130 p := pMap[v] 131 if p == 0 { 132 p = len(pMap) + 1 133 pMap[v] = p 134 } 135 a := append([]interface{}{ 136 strings.Repeat("..", c.nest), 137 p, 138 v.Label.SelectorString(c), 139 v.Path(), 140 }, args...) 141 for i := 2; i < len(a); i++ { 142 switch x := a[i].(type) { 143 case Node: 144 a[i] = c.Str(x) 145 case Feature: 146 a[i] = x.SelectorString(c) 147 } 148 } 149 s := fmt.Sprintf("%s [%d] %s/%v"+format, a...) 150 _ = log.Output(2, s) 151 } 152 153 // Runtime defines an interface for low-level representation conversion and 154 // lookup. 155 type Runtime interface { 156 // StringIndexer allows for converting string labels to and from a 157 // canonical numeric representation. 158 StringIndexer 159 160 // LoadImport loads a unique Vertex associated with a given import path. It 161 // returns nil if no import for this package could be found. 162 LoadImport(importPath string) *Vertex 163 164 // StoreType associates a CUE expression with a Go type. 165 StoreType(t reflect.Type, src ast.Expr, expr Expr) 166 167 // LoadType retrieves a previously stored CUE expression for a given Go 168 // type if available. 169 LoadType(t reflect.Type) (src ast.Expr, expr Expr, ok bool) 170 } 171 172 type Config struct { 173 Runtime 174 Format func(Node) string 175 } 176 177 // New creates an operation context. 178 func New(v *Vertex, cfg *Config) *OpContext { 179 if cfg.Runtime == nil { 180 panic("nil Runtime") 181 } 182 ctx := &OpContext{ 183 Runtime: cfg.Runtime, 184 Format: cfg.Format, 185 vertex: v, 186 } 187 if v != nil { 188 ctx.e = &Environment{Up: nil, Vertex: v} 189 } 190 return ctx 191 } 192 193 // An OpContext implements CUE's unification operation. It's operations only 194 // operation on values that are created with the Runtime with which an OpContext 195 // is associated. An OpContext is not goroutine save and only one goroutine may 196 // use an OpContext at a time. 197 // 198 type OpContext struct { 199 Runtime 200 Format func(Node) string 201 202 nest int 203 204 stats Stats 205 freeListNode *nodeContext 206 207 e *Environment 208 src ast.Node 209 errs *Bottom 210 positions []Node // keep track of error positions 211 212 // vertex is used to determine the path location in case of error. Turning 213 // this into a stack could also allow determining the cyclic path for 214 // structural cycle errors. 215 vertex *Vertex 216 217 nonMonotonicLookupNest int32 218 nonMonotonicRejectNest int32 219 nonMonotonicInsertNest int32 220 nonMonotonicGeneration int32 221 222 // These fields are used associate scratch fields for computing closedness 223 // of a Vertex. These fields could have been included in StructInfo (like 224 // Tomabechi's unification algorithm), but we opted for an indirection to 225 // allow concurrent unification. 226 // 227 // TODO(perf): have two generations: one for each pass of the closedness 228 // algorithm, so that the results of the first pass can be reused for all 229 // features of a node. 230 generation int 231 closed map[*closeInfo]*closeStats 232 todo *closeStats 233 234 // inDisjunct indicates that non-monotonic checks should be skipped. 235 // This is used if we want to do some extra work to eliminate disjunctions 236 // early. The result of unificantion should be thrown away if this check is 237 // used. 238 // 239 // TODO: replace this with a mechanism to determine the correct set (per 240 // conjunct) of StructInfos to include in closedness checking. 241 inDisjunct int 242 243 // inConstaint overrides inDisjunct as field matching should always be 244 // enabled. 245 inConstraint int 246 } 247 248 func (n *nodeContext) skipNonMonotonicChecks() bool { 249 if n.ctx.inConstraint > 0 { 250 return false 251 } 252 return n.ctx.inDisjunct > 0 253 } 254 255 // Impl is for internal use only. This will go. 256 func (c *OpContext) Impl() Runtime { 257 return c.Runtime 258 } 259 260 func (c *OpContext) Pos() token.Pos { 261 if c.src == nil { 262 return token.NoPos 263 } 264 return c.src.Pos() 265 } 266 267 func (c *OpContext) Source() ast.Node { 268 return c.src 269 } 270 271 // NewContext creates an operation context. 272 func NewContext(r Runtime, v *Vertex) *OpContext { 273 return New(v, &Config{Runtime: r}) 274 } 275 276 func (c *OpContext) pos() token.Pos { 277 if c.src == nil { 278 return token.NoPos 279 } 280 return c.src.Pos() 281 } 282 283 func (c *OpContext) spawn(node *Vertex) *Environment { 284 node.Parent = c.e.Vertex // TODO: Is this necessary? 285 return &Environment{ 286 Up: c.e, 287 Vertex: node, 288 289 // Copy cycle data. 290 Cyclic: c.e.Cyclic, 291 Deref: c.e.Deref, 292 Cycles: c.e.Cycles, 293 } 294 } 295 296 func (c *OpContext) Env(upCount int32) *Environment { 297 e := c.e 298 for ; upCount > 0; upCount-- { 299 e = e.Up 300 } 301 return e 302 } 303 304 func (c *OpContext) relNode(upCount int32) *Vertex { 305 e := c.e 306 for ; upCount > 0; upCount-- { 307 e = e.Up 308 } 309 c.Unify(e.Vertex, Partial) 310 return e.Vertex 311 } 312 313 func (c *OpContext) relLabel(upCount int32) Feature { 314 // locate current label. 315 e := c.e 316 for ; upCount > 0; upCount-- { 317 e = e.Up 318 } 319 return e.DynamicLabel 320 } 321 322 func (c *OpContext) concreteIsPossible(op Op, x Expr) bool { 323 if !AssertConcreteIsPossible(op, x) { 324 // No need to take position of expression. 325 c.AddErr(c.NewPosf(token.NoPos, 326 "invalid operand %s ('%s' requires concrete value)", x, op)) 327 return false 328 } 329 return true 330 } 331 332 // Assert that the given expression can evaluate to a concrete value. 333 func AssertConcreteIsPossible(op Op, x Expr) bool { 334 switch v := x.(type) { 335 case *Bottom: 336 case *BoundExpr: 337 return false 338 case Value: 339 return v.Concreteness() == Concrete 340 } 341 return true 342 } 343 344 // HasErr reports whether any error was reported, including whether value 345 // was incomplete. 346 func (c *OpContext) HasErr() bool { 347 return c.errs != nil 348 } 349 350 func (c *OpContext) Err() *Bottom { 351 b := c.errs 352 c.errs = nil 353 return b 354 } 355 356 func (c *OpContext) addErrf(code ErrorCode, pos token.Pos, msg string, args ...interface{}) { 357 err := c.NewPosf(pos, msg, args...) 358 c.addErr(code, err) 359 } 360 361 func (c *OpContext) addErr(code ErrorCode, err errors.Error) { 362 c.AddBottom(&Bottom{Code: code, Err: err}) 363 } 364 365 // AddBottom records an error in OpContext. 366 func (c *OpContext) AddBottom(b *Bottom) { 367 c.errs = CombineErrors(c.src, c.errs, b) 368 } 369 370 // AddErr records an error in OpContext. It returns errors collected so far. 371 func (c *OpContext) AddErr(err errors.Error) *Bottom { 372 if err != nil { 373 c.AddBottom(&Bottom{Err: err}) 374 } 375 return c.errs 376 } 377 378 // NewErrf creates a *Bottom value and returns it. The returned uses the 379 // current source as the point of origin of the error. 380 func (c *OpContext) NewErrf(format string, args ...interface{}) *Bottom { 381 // TODO: consider renaming ot NewBottomf: this is now confusing as we also 382 // have Newf. 383 err := c.Newf(format, args...) 384 return &Bottom{Src: c.src, Err: err, Code: EvalError} 385 } 386 387 // AddErrf records an error in OpContext. It returns errors collected so far. 388 func (c *OpContext) AddErrf(format string, args ...interface{}) *Bottom { 389 return c.AddErr(c.Newf(format, args...)) 390 } 391 392 type frame struct { 393 env *Environment 394 err *Bottom 395 src ast.Node 396 } 397 398 func (c *OpContext) PushState(env *Environment, src ast.Node) (saved frame) { 399 saved.env = c.e 400 saved.err = c.errs 401 saved.src = c.src 402 403 c.errs = nil 404 if src != nil { 405 c.src = src 406 } 407 c.e = env 408 409 return saved 410 } 411 412 func (c *OpContext) PopState(s frame) *Bottom { 413 err := c.errs 414 c.e = s.env 415 c.errs = s.err 416 c.src = s.src 417 return err 418 } 419 420 // PushArc signals c that arc v is currently being processed for the purpose 421 // of error reporting. PopArc should be called with the returned value once 422 // processing of v is completed. 423 func (c *OpContext) PushArc(v *Vertex) (saved *Vertex) { 424 c.vertex, saved = v, c.vertex 425 return saved 426 } 427 428 // PopArc signals completion of processing the current arc. 429 func (c *OpContext) PopArc(saved *Vertex) { 430 c.vertex = saved 431 } 432 433 // Resolve finds a node in the tree. 434 // 435 // Should only be used to insert Conjuncts. TODO: perhaps only return Conjuncts 436 // and error. 437 func (c *OpContext) Resolve(env *Environment, r Resolver) (*Vertex, *Bottom) { 438 s := c.PushState(env, r.Source()) 439 440 arc := r.resolve(c, Partial) 441 442 err := c.PopState(s) 443 if err != nil { 444 return nil, err 445 } 446 447 if arc.ChildErrors != nil && arc.ChildErrors.Code == StructuralCycleError { 448 return nil, arc.ChildErrors 449 } 450 451 arc = arc.Indirect() 452 453 return arc, err 454 } 455 456 // Validate calls validates value for the given validator. 457 // 458 // TODO(errors): return boolean instead: only the caller has enough information 459 // to generate a proper error message. 460 func (c *OpContext) Validate(check Validator, value Value) *Bottom { 461 // TODO: use a position stack to push both values. 462 saved := c.src 463 c.src = check.Source() 464 465 err := check.validate(c, value) 466 467 c.src = saved 468 469 return err 470 } 471 472 // Yield evaluates a Yielder and calls f for each result. 473 func (c *OpContext) Yield(env *Environment, comp *Comprehension, f YieldFunc) *Bottom { 474 y := comp.Clauses 475 476 s := c.PushState(env, y.Source()) 477 478 y.yield(c, f) 479 480 return c.PopState(s) 481 482 } 483 484 // Concrete returns the concrete value of x after evaluating it. 485 // msg is used to mention the context in which an error occurred, if any. 486 func (c *OpContext) Concrete(env *Environment, x Expr, msg interface{}) (result Value, complete bool) { 487 488 w, complete := c.Evaluate(env, x) 489 490 w, ok := c.getDefault(w) 491 if !ok { 492 return w, false 493 } 494 v := Unwrap(w) 495 496 if !IsConcrete(v) { 497 complete = false 498 b := c.NewErrf("non-concrete value %v in operand to %s", w, msg) 499 b.Code = IncompleteError 500 v = b 501 } 502 503 if !complete { 504 return v, complete 505 } 506 507 return v, true 508 } 509 510 // getDefault resolves a disjunction to a single value. If there is no default 511 // value, or if there is more than one default value, it reports an "incomplete" 512 // error and return false. In all other cases it will return true, even if 513 // v is already an error. v may be nil, in which case it will also return nil. 514 func (c *OpContext) getDefault(v Value) (result Value, ok bool) { 515 var d *Disjunction 516 switch x := v.(type) { 517 default: 518 return v, true 519 520 case *Vertex: 521 // TODO: return vertex if not disjunction. 522 switch t := x.BaseValue.(type) { 523 case *Disjunction: 524 d = t 525 526 case *Vertex: 527 return c.getDefault(t) 528 529 default: 530 return x, true 531 } 532 533 case *Disjunction: 534 d = x 535 } 536 537 if d.NumDefaults != 1 { 538 c.addErrf(IncompleteError, c.pos(), 539 "unresolved disjunction %s (type %s)", d, d.Kind()) 540 return nil, false 541 } 542 return c.getDefault(d.Values[0]) 543 } 544 545 // Evaluate evaluates an expression within the given environment and indicates 546 // whether the result is complete. It will always return a non-nil result. 547 func (c *OpContext) Evaluate(env *Environment, x Expr) (result Value, complete bool) { 548 s := c.PushState(env, x.Source()) 549 550 val := c.evalState(x, Partial) 551 552 complete = true 553 554 if err, _ := val.(*Bottom); err != nil && err.IsIncomplete() { 555 complete = false 556 } 557 if val == nil { 558 complete = false 559 // TODO ENSURE THIS DOESN"T HAPPEN> 560 val = &Bottom{ 561 Code: IncompleteError, 562 Err: c.Newf("UNANTICIPATED ERROR"), 563 } 564 565 } 566 567 _ = c.PopState(s) 568 569 if !complete || val == nil { 570 return val, false 571 } 572 573 return val, true 574 } 575 576 func (c *OpContext) evaluateRec(env *Environment, x Expr, state VertexStatus) Value { 577 s := c.PushState(env, x.Source()) 578 579 val := c.evalState(x, state) 580 if val == nil { 581 // Be defensive: this never happens, but just in case. 582 Assertf(false, "nil return value: unspecified error") 583 val = &Bottom{ 584 Code: IncompleteError, 585 Err: c.Newf("UNANTICIPATED ERROR"), 586 } 587 } 588 _ = c.PopState(s) 589 590 return val 591 } 592 593 // value evaluates expression v within the current environment. The result may 594 // be nil if the result is incomplete. value leaves errors untouched to that 595 // they can be collected by the caller. 596 func (c *OpContext) value(x Expr) (result Value) { 597 v := c.evalState(x, Partial) 598 599 v, _ = c.getDefault(v) 600 v = Unwrap(v) 601 return v 602 } 603 604 func (c *OpContext) evalState(v Expr, state VertexStatus) (result Value) { 605 savedSrc := c.src 606 c.src = v.Source() 607 err := c.errs 608 c.errs = nil 609 610 defer func() { 611 c.errs = CombineErrors(c.src, c.errs, err) 612 613 if v, ok := result.(*Vertex); ok { 614 if b, _ := v.BaseValue.(*Bottom); b != nil { 615 switch b.Code { 616 case IncompleteError: 617 case CycleError: 618 if state == Partial { 619 break 620 } 621 fallthrough 622 default: 623 result = b 624 } 625 } 626 } 627 628 // TODO: remove this when we handle errors more principally. 629 if b, ok := result.(*Bottom); ok { 630 if c.src != nil && 631 b.Code == CycleError && 632 len(errors.Positions(b.Err)) == 0 { 633 bb := *b 634 bb.Err = errors.Wrapf(b.Err, c.src.Pos(), "") 635 result = &bb 636 } 637 if c.errs != result { 638 c.errs = CombineErrors(c.src, c.errs, result) 639 } 640 } 641 if c.errs != nil { 642 result = c.errs 643 } 644 c.src = savedSrc 645 }() 646 647 switch x := v.(type) { 648 case Value: 649 return x 650 651 case Evaluator: 652 v := x.evaluate(c) 653 return v 654 655 case Resolver: 656 arc := x.resolve(c, state) 657 if c.HasErr() { 658 return nil 659 } 660 if arc == nil { 661 return nil 662 } 663 664 v := c.evaluate(arc, state) 665 return v 666 667 default: 668 // This can only happen, really, if v == nil, which is not allowed. 669 panic(fmt.Sprintf("unexpected Expr type %T", v)) 670 } 671 } 672 673 // unifyNode returns a possibly partially evaluated node value. 674 // 675 // TODO: maybe return *Vertex, *Bottom 676 // 677 func (c *OpContext) unifyNode(v Expr, state VertexStatus) (result Value) { 678 savedSrc := c.src 679 c.src = v.Source() 680 err := c.errs 681 c.errs = nil 682 683 defer func() { 684 c.errs = CombineErrors(c.src, c.errs, err) 685 686 if v, ok := result.(*Vertex); ok { 687 if b, _ := v.BaseValue.(*Bottom); b != nil { 688 switch b.Code { 689 case IncompleteError: 690 case CycleError: 691 if state == Partial { 692 break 693 } 694 fallthrough 695 default: 696 result = b 697 } 698 } 699 } 700 701 // TODO: remove this when we handle errors more principally. 702 if b, ok := result.(*Bottom); ok { 703 if c.src != nil && 704 b.Code == CycleError && 705 b.Err.Position() == token.NoPos && 706 len(b.Err.InputPositions()) == 0 { 707 bb := *b 708 bb.Err = errors.Wrapf(b.Err, c.src.Pos(), "") 709 result = &bb 710 } 711 c.errs = CombineErrors(c.src, c.errs, result) 712 } 713 if c.errs != nil { 714 result = c.errs 715 } 716 c.src = savedSrc 717 }() 718 719 switch x := v.(type) { 720 case Value: 721 return x 722 723 case Evaluator: 724 v := x.evaluate(c) 725 return v 726 727 case Resolver: 728 v := x.resolve(c, state) 729 if c.HasErr() { 730 return nil 731 } 732 if v == nil { 733 return nil 734 } 735 736 if v.isUndefined() || state > v.status { 737 // Keep a minimum state of AllArcs. 738 // TODO: AllArcs may still not be achieved if a node is currently 739 // evaluating. 740 state := state 741 if state < AllArcs { 742 state = AllArcs 743 } 744 // Use node itself to allow for cycle detection. 745 c.Unify(v, state) 746 } 747 748 return v 749 750 default: 751 // This can only happen, really, if v == nil, which is not allowed. 752 panic(fmt.Sprintf("unexpected Expr type %T", v)) 753 } 754 } 755 756 func (c *OpContext) lookup(x *Vertex, pos token.Pos, l Feature, state VertexStatus) *Vertex { 757 if l == InvalidLabel || x == nil { 758 // TODO: is it possible to have an invalid label here? Maybe through the 759 // API? 760 return &Vertex{} 761 } 762 763 // var kind Kind 764 // if x.BaseValue != nil { 765 // kind = x.BaseValue.Kind() 766 // } 767 768 switch x.BaseValue.(type) { 769 case *StructMarker: 770 if l.Typ() == IntLabel { 771 c.addErrf(0, pos, "invalid struct selector %s (type int)", l) 772 return nil 773 } 774 775 case *ListMarker: 776 switch { 777 case l.Typ() == IntLabel: 778 switch { 779 case l.Index() < 0: 780 c.addErrf(0, pos, "invalid list index %s (index must be non-negative)", l) 781 return nil 782 case l.Index() > len(x.Arcs): 783 c.addErrf(0, pos, "invalid list index %s (out of bounds)", l) 784 return nil 785 } 786 787 case l.IsDef(), l.IsHidden(): 788 789 default: 790 c.addErrf(0, pos, "invalid list index %s (type string)", l) 791 return nil 792 } 793 794 case nil: 795 // c.addErrf(IncompleteError, pos, "incomplete value %s", x) 796 // return nil 797 798 case *Bottom: 799 800 default: 801 kind := x.BaseValue.Kind() 802 if kind&(ListKind|StructKind) != 0 { 803 // c.addErrf(IncompleteError, pos, 804 // "cannot look up %s in incomplete type %s (type %s)", 805 // l, x.Source(), kind) 806 // return nil 807 } else if !l.IsDef() && !l.IsHidden() { 808 c.addErrf(0, pos, 809 "invalid selector %s for value of type %s", l, kind) 810 return nil 811 } 812 } 813 814 a := x.Lookup(l) 815 if a != nil { 816 a = a.Indirect() 817 } 818 819 var hasCycle bool 820 outer: 821 switch { 822 case c.nonMonotonicLookupNest == 0 && c.nonMonotonicRejectNest == 0: 823 case a != nil: 824 if state == Partial { 825 a.nonMonotonicLookupGen = c.nonMonotonicGeneration 826 } 827 828 case x.state != nil && state == Partial: 829 for _, e := range x.state.exprs { 830 if isCyclePlaceholder(e.err) { 831 hasCycle = true 832 } 833 } 834 for _, a := range x.state.usedArcs { 835 if a.Label == l { 836 a.nonMonotonicLookupGen = c.nonMonotonicGeneration 837 if c.nonMonotonicRejectNest > 0 { 838 a.nonMonotonicReject = true 839 } 840 break outer 841 } 842 } 843 a := &Vertex{Label: l, nonMonotonicLookupGen: c.nonMonotonicGeneration} 844 if c.nonMonotonicRejectNest > 0 { 845 a.nonMonotonicReject = true 846 } 847 x.state.usedArcs = append(x.state.usedArcs, a) 848 } 849 850 if a != nil && state > a.status { 851 c.Unify(a, state) 852 } 853 854 if a == nil { 855 if x.state != nil { 856 for _, e := range x.state.exprs { 857 if isCyclePlaceholder(e.err) { 858 hasCycle = true 859 } 860 } 861 } 862 code := IncompleteError 863 if !x.Accept(c, l) { 864 code = 0 865 } else if hasCycle { 866 code = CycleError 867 } 868 // TODO: if the struct was a literal struct, we can also treat it as 869 // closed and make this a permanent error. 870 label := l.SelectorString(c.Runtime) 871 872 // TODO(errors): add path reference and make message 873 // "undefined field %s in %s" 874 if l.IsInt() { 875 c.addErrf(code, pos, "index out of range [%d] with length %d", 876 l.Index(), len(x.Elems())) 877 } else { 878 if code != 0 && x.IsOptional(l) { 879 c.addErrf(code, pos, 880 "cannot reference optional field: %s", label) 881 } else { 882 c.addErrf(code, pos, "undefined field: %s", label) 883 } 884 } 885 } 886 return a 887 } 888 889 func (c *OpContext) Label(src Expr, x Value) Feature { 890 return labelFromValue(c, src, x) 891 } 892 893 func (c *OpContext) typeError(v Value, k Kind) { 894 if isError(v) { 895 return 896 } 897 if !IsConcrete(v) && v.Kind()&k != 0 { 898 c.addErrf(IncompleteError, pos(v), "incomplete %s: %s", k, v) 899 } else { 900 c.AddErrf("cannot use %s (type %s) as type %s", v, v.Kind(), k) 901 } 902 } 903 904 func (c *OpContext) typeErrorAs(v Value, k Kind, as interface{}) { 905 if as == nil { 906 c.typeError(v, k) 907 return 908 } 909 if isError(v) { 910 return 911 } 912 if !IsConcrete(v) && v.Kind()&k != 0 { 913 c.addErrf(IncompleteError, pos(v), 914 "incomplete %s in %v: %s", k, as, v) 915 } else { 916 c.AddErrf("cannot use %s (type %s) as type %s in %v", v, v.Kind(), k, as) 917 } 918 } 919 920 var emptyNode = &Vertex{} 921 922 func pos(x Node) token.Pos { 923 if x.Source() == nil { 924 return token.NoPos 925 } 926 return x.Source().Pos() 927 } 928 929 func (c *OpContext) node(orig Node, x Expr, scalar bool, state VertexStatus) *Vertex { 930 // TODO: always get the vertex. This allows a whole bunch of trickery 931 // down the line. 932 v := c.unifyNode(x, state) 933 934 v, ok := c.getDefault(v) 935 if !ok { 936 // Error already generated by getDefault. 937 return emptyNode 938 } 939 940 // The two if blocks below are rather subtle. If we have an error of 941 // the sentinel value cycle, we have earlier determined that the cycle is 942 // allowed and that it can be ignored here. Any other CycleError is an 943 // annotated cycle error that could be taken as is. 944 // TODO: do something simpler. 945 if scalar { 946 if w := Unwrap(v); !isCyclePlaceholder(w) { 947 v = w 948 } 949 } 950 951 node, ok := v.(*Vertex) 952 if ok && !isCyclePlaceholder(node.BaseValue) { 953 v = node.Value() 954 } 955 956 switch nv := v.(type) { 957 case nil: 958 switch orig.(type) { 959 case *ForClause: 960 c.addErrf(IncompleteError, pos(x), 961 "cannot range over %s (incomplete)", x) 962 default: 963 c.addErrf(IncompleteError, pos(x), 964 "%s undefined (%s is incomplete)", orig, x) 965 } 966 return emptyNode 967 968 case *Bottom: 969 // TODO: this is a bit messy. In some cases errors are already added 970 // and in some cases not. Not a huge deal, as errors will be uniqued 971 // down the line, but could be better. 972 c.AddBottom(nv) 973 return emptyNode 974 975 case *Vertex: 976 if node == nil { 977 panic("unexpected markers with nil node") 978 } 979 980 default: 981 if kind := v.Kind(); kind&StructKind != 0 { 982 switch orig.(type) { 983 case *ForClause: 984 c.addErrf(IncompleteError, pos(x), 985 "cannot range over %s (incomplete type %s)", x, kind) 986 default: 987 c.addErrf(IncompleteError, pos(x), 988 "%s undefined as %s is incomplete (type %s)", orig, x, kind) 989 } 990 return emptyNode 991 992 } else if !ok { 993 c.addErrf(0, pos(x), // TODO(error): better message. 994 "invalid operand %s (found %s, want list or struct)", 995 x.Source(), v.Kind()) 996 return emptyNode 997 } 998 } 999 1000 return node 1001 } 1002 1003 // Elems returns the elements of a list. 1004 func (c *OpContext) Elems(v Value) []*Vertex { 1005 list := c.list(v) 1006 return list.Elems() 1007 } 1008 1009 func (c *OpContext) list(v Value) *Vertex { 1010 x, ok := v.(*Vertex) 1011 if !ok || !x.IsList() { 1012 c.typeError(v, ListKind) 1013 return emptyNode 1014 } 1015 return x 1016 } 1017 1018 func (c *OpContext) scalar(v Value) Value { 1019 v = Unwrap(v) 1020 switch v.(type) { 1021 case *Null, *Bool, *Num, *String, *Bytes: 1022 default: 1023 c.typeError(v, ScalarKinds) 1024 } 1025 return v 1026 } 1027 1028 var zero = &Num{K: NumKind} 1029 1030 func (c *OpContext) Num(v Value, as interface{}) *Num { 1031 v = Unwrap(v) 1032 if isError(v) { 1033 return zero 1034 } 1035 x, ok := v.(*Num) 1036 if !ok { 1037 c.typeErrorAs(v, NumKind, as) 1038 return zero 1039 } 1040 return x 1041 } 1042 1043 func (c *OpContext) Int64(v Value) int64 { 1044 v = Unwrap(v) 1045 if isError(v) { 1046 return 0 1047 } 1048 x, ok := v.(*Num) 1049 if !ok { 1050 c.typeError(v, IntKind) 1051 return 0 1052 } 1053 i, err := x.X.Int64() 1054 if err != nil { 1055 c.AddErrf("number is not an int64: %v", err) 1056 return 0 1057 } 1058 return i 1059 } 1060 1061 func (c *OpContext) uint64(v Value, as string) uint64 { 1062 v = Unwrap(v) 1063 if isError(v) { 1064 return 0 1065 } 1066 x, ok := v.(*Num) 1067 if !ok { 1068 c.typeErrorAs(v, IntKind, as) 1069 return 0 1070 } 1071 if x.X.Negative { 1072 // TODO: improve message 1073 c.AddErrf("cannot convert negative number to uint64") 1074 return 0 1075 } 1076 if !x.X.Coeff.IsUint64() { 1077 // TODO: improve message 1078 c.AddErrf("cannot convert number %s to uint64", x.X) 1079 return 0 1080 } 1081 return x.X.Coeff.Uint64() 1082 } 1083 1084 func (c *OpContext) BoolValue(v Value) bool { 1085 return c.boolValue(v, nil) 1086 } 1087 1088 func (c *OpContext) boolValue(v Value, as interface{}) bool { 1089 v = Unwrap(v) 1090 if isError(v) { 1091 return false 1092 } 1093 x, ok := v.(*Bool) 1094 if !ok { 1095 c.typeErrorAs(v, BoolKind, as) 1096 return false 1097 } 1098 return x.B 1099 } 1100 1101 func (c *OpContext) StringValue(v Value) string { 1102 return c.stringValue(v, nil) 1103 } 1104 1105 // ToBytes returns the bytes value of a scalar value. 1106 func (c *OpContext) ToBytes(v Value) []byte { 1107 if x, ok := v.(*Bytes); ok { 1108 return x.B 1109 } 1110 return []byte(c.ToString(v)) 1111 } 1112 1113 // ToString returns the string value of a scalar value. 1114 func (c *OpContext) ToString(v Value) string { 1115 return c.toStringValue(v, StringKind|NumKind|BytesKind|BoolKind, nil) 1116 1117 } 1118 1119 func (c *OpContext) stringValue(v Value, as interface{}) string { 1120 return c.toStringValue(v, StringKind, as) 1121 } 1122 1123 func (c *OpContext) toStringValue(v Value, k Kind, as interface{}) string { 1124 v = Unwrap(v) 1125 if isError(v) { 1126 return "" 1127 } 1128 if v.Kind()&k == 0 { 1129 if as == nil { 1130 c.typeError(v, k) 1131 } else { 1132 c.typeErrorAs(v, k, as) 1133 } 1134 return "" 1135 } 1136 switch x := v.(type) { 1137 case *String: 1138 return x.Str 1139 1140 case *Bytes: 1141 return bytesToString(x.B) 1142 1143 case *Num: 1144 return x.X.String() 1145 1146 case *Bool: 1147 if x.B { 1148 return "true" 1149 } 1150 return "false" 1151 1152 default: 1153 c.addErrf(IncompleteError, c.pos(), 1154 "non-concrete value %s (type %s)", v, v.Kind()) 1155 } 1156 return "" 1157 } 1158 1159 func bytesToString(b []byte) string { 1160 b, _ = unicode.UTF8.NewDecoder().Bytes(b) 1161 return string(b) 1162 } 1163 1164 func (c *OpContext) bytesValue(v Value, as interface{}) []byte { 1165 v = Unwrap(v) 1166 if isError(v) { 1167 return nil 1168 } 1169 x, ok := v.(*Bytes) 1170 if !ok { 1171 c.typeErrorAs(v, BytesKind, as) 1172 return nil 1173 } 1174 return x.B 1175 } 1176 1177 var matchNone = regexp.MustCompile("^$") 1178 1179 func (c *OpContext) regexp(v Value) *regexp.Regexp { 1180 v = Unwrap(v) 1181 if isError(v) { 1182 return matchNone 1183 } 1184 switch x := v.(type) { 1185 case *String: 1186 if x.RE != nil { 1187 return x.RE 1188 } 1189 // TODO: synchronization 1190 p, err := regexp.Compile(x.Str) 1191 if err != nil { 1192 // FatalError? How to cache error 1193 c.AddErrf("invalid regexp: %s", err) 1194 x.RE = matchNone 1195 } else { 1196 x.RE = p 1197 } 1198 return x.RE 1199 1200 case *Bytes: 1201 if x.RE != nil { 1202 return x.RE 1203 } 1204 // TODO: synchronization 1205 p, err := regexp.Compile(string(x.B)) 1206 if err != nil { 1207 c.AddErrf("invalid regexp: %s", err) 1208 x.RE = matchNone 1209 } else { 1210 x.RE = p 1211 } 1212 return x.RE 1213 1214 default: 1215 c.typeError(v, StringKind|BytesKind) 1216 return matchNone 1217 } 1218 } 1219 1220 // newNum creates a new number of the given kind. It reports an error value 1221 // instead if any error occurred. 1222 func (c *OpContext) newNum(d *apd.Decimal, k Kind, sources ...Node) Value { 1223 if c.HasErr() { 1224 return c.Err() 1225 } 1226 return &Num{Src: c.src, X: *d, K: k} 1227 } 1228 1229 func (c *OpContext) NewInt64(n int64, sources ...Node) Value { 1230 if c.HasErr() { 1231 return c.Err() 1232 } 1233 d := apd.New(n, 0) 1234 return &Num{Src: c.src, X: *d, K: IntKind} 1235 } 1236 1237 func (c *OpContext) NewString(s string) Value { 1238 if c.HasErr() { 1239 return c.Err() 1240 } 1241 return &String{Src: c.src, Str: s} 1242 } 1243 1244 func (c *OpContext) newBytes(b []byte) Value { 1245 if c.HasErr() { 1246 return c.Err() 1247 } 1248 return &Bytes{Src: c.src, B: b} 1249 } 1250 1251 func (c *OpContext) newBool(b bool) Value { 1252 if c.HasErr() { 1253 return c.Err() 1254 } 1255 return &Bool{Src: c.src, B: b} 1256 } 1257 1258 func (c *OpContext) newList(src ast.Node, parent *Vertex) *Vertex { 1259 return &Vertex{Parent: parent, BaseValue: &ListMarker{}} 1260 } 1261 1262 // Str reports a debug string of x. 1263 func (c *OpContext) Str(x Node) string { 1264 if c.Format == nil { 1265 return fmt.Sprintf("%T", x) 1266 } 1267 return c.Format(x) 1268 } 1269 1270 // NewList returns a new list for the given values. 1271 func (c *OpContext) NewList(values ...Value) *Vertex { 1272 // TODO: consider making this a literal list instead. 1273 list := &ListLit{} 1274 v := &Vertex{ 1275 Conjuncts: []Conjunct{{Env: nil, x: list}}, 1276 } 1277 1278 for _, x := range values { 1279 list.Elems = append(list.Elems, x) 1280 } 1281 c.Unify(v, Finalized) 1282 return v 1283 }