Skip to content

Commit

Permalink
internal/core/adt: hoist value validation
Browse files Browse the repository at this point in the history
This allows the code to be used by two implementations.

Signed-off-by: Marcel van Lohuizen <mpvl@gmail.com>
Change-Id: I42c50391e382c0b9d5a1eb91b7a2d98b61550f4c
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/551414
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>
Reviewed-by: Aram Hăvărneanu <aram@cue.works>
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
  • Loading branch information
mpvl committed Mar 24, 2023
1 parent 47f0025 commit eea60b9
Showing 1 changed file with 69 additions and 53 deletions.
122 changes: 69 additions & 53 deletions internal/core/adt/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -515,63 +515,21 @@ func (n *nodeContext) postDisjunct(state vertexStatus) {

// We are no longer evaluating.

// Either set to Conjunction or error.
// TODO: verify and simplify the below code to determine whether
// something is a struct.
markStruct := false
if n.aStruct != nil {
markStruct = true
} else if len(n.node.Structs) > 0 {
markStruct = n.kind&StructKind != 0 && !n.hasTop
}
n.validateValue(state)

v := n.node.Value()
if n.node.BaseValue == nil && markStruct {
n.node.BaseValue = &StructMarker{}
v = n.node
}
if v != nil && IsConcrete(v) {
// Also check when we already have errors as we may find more
// serious errors and would like to know about all errors anyway.

if n.lowerBound != nil {
if b := ctx.Validate(n.lowerBound, v); b != nil {
// TODO(errors): make Validate return boolean and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if e, _ := b.Err.(*ValueError); e != nil {
e.AddPosition(n.lowerBound)
e.AddPosition(v)
}
n.addBottom(b)
}
}
if n.upperBound != nil {
if b := ctx.Validate(n.upperBound, v); b != nil {
// TODO(errors): make Validate return boolean and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if e, _ := b.Err.(*ValueError); e != nil {
e.AddPosition(n.upperBound)
e.AddPosition(v)
}

// TODO(perf): only delay processing of actual non-monotonic checks.
skip := n.skipNonMonotonicChecks()
if v != nil && IsConcrete(v) && !skip {
for _, v := range n.checks {
// TODO(errors): make Validate return bottom and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if b := ctx.Validate(v, n.node); b != nil {
n.addBottom(b)
}
}
// MOVE BELOW
// TODO(perf): only delay processing of actual non-monotonic checks.
skip := n.skipNonMonotonicChecks()
if v := n.node.Value(); v != nil && IsConcrete(v) && !skip {
for _, v := range n.checks {
// TODO(errors): make Validate return bottom and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if b := ctx.Validate(v, n.node); b != nil {
n.addBottom(b)
}
}
}
} else if state == finalized {
n.node.BaseValue = n.getValidators(finalized)
}

if v == nil {
Expand Down Expand Up @@ -602,6 +560,64 @@ func (n *nodeContext) postDisjunct(state vertexStatus) {
n.completeArcs(state)
}

// validateValue checks collected bound validators and checks them against
// the current value. If there is no value, it sets the current value
// to these validators itself.
//
// Before it does this, it also checks whether n is of another incompatible
// type, like struct. This prevents validators from being inadvertently set.
// TODO: optimize this function for new implementation.
func (n *nodeContext) validateValue(state vertexStatus) {
ctx := n.ctx

// Either set to Conjunction or error.
// TODO: verify and simplify the below code to determine whether
// something is a struct.
markStruct := false
if n.aStruct != nil {
markStruct = true
} else if len(n.node.Structs) > 0 {
markStruct = n.kind&StructKind != 0 && !n.hasTop
}
v := n.node.Value()
if n.node.BaseValue == nil && markStruct {
n.node.BaseValue = &StructMarker{}
v = n.node
}
if v != nil && IsConcrete(v) {
// Also check when we already have errors as we may find more
// serious errors and would like to know about all errors anyway.

if n.lowerBound != nil {
if b := ctx.Validate(n.lowerBound, v); b != nil {
// TODO(errors): make Validate return boolean and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if e, _ := b.Err.(*ValueError); e != nil {
e.AddPosition(n.lowerBound)
e.AddPosition(v)
}
n.addBottom(b)
}
}
if n.upperBound != nil {
if b := ctx.Validate(n.upperBound, v); b != nil {
// TODO(errors): make Validate return boolean and generate
// optimized conflict message. Also track and inject IDs
// to determine origin location.s
if e, _ := b.Err.(*ValueError); e != nil {
e.AddPosition(n.upperBound)
e.AddPosition(v)
}
n.addBottom(b)
}
}

} else if state == finalized {
n.node.BaseValue = n.getValidators(finalized)
}
}

// incompleteErrors reports all errors from uncompleted conjuncts.
// If final is true, errors are permanent and reported to parents.
func (n *nodeContext) incompleteErrors(final bool) *Bottom {
Expand Down

0 comments on commit eea60b9

Please sign in to comment.