blob: b9738c11592bf767b8149e44b30b196a88edf219 [file] [log] [blame]
// Copyright 2018 The CUE Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package cue
type rewriteMode int
const (
evalRaw rewriteMode = iota
evalSimplify
evalPartial // all but disjunctions
evalFull
)
// testResolve recursively
func testResolve(ctx *context, v value, m rewriteMode) (result value) {
if m == evalRaw || v == nil {
return v
}
return rewriteRec(ctx, v, v.evalPartial(ctx), m)
}
func rewriteRec(ctx *context, raw value, eval evaluated, m rewriteMode) (result value) {
if m >= evalPartial {
if isIncomplete(eval) {
return raw
}
if m == evalFull {
eval = ctx.manifest(eval)
if isBottom(eval) {
return eval
}
}
}
switch x := eval.(type) {
case *structLit:
if m == evalFull {
e := ctx.manifest(x)
if isBottom(e) {
return e
}
x = e.(*structLit)
}
var err *bottom
x, err = x.expandFields(ctx)
if err != nil {
if isIncomplete(err) {
return raw
}
return err
}
arcs := make(arcs, len(x.arcs))
for i, a := range x.arcs {
v := x.at(ctx, i)
a.setValue(rewriteRec(ctx, a.v, v, m))
arcs[i] = a
}
t := x.template
if t != nil {
v := rewriteRec(ctx, t, t.evalPartial(ctx), m)
if isBottom(v) {
return v
}
t = v
}
emit := testResolve(ctx, x.emit, m)
obj := &structLit{x.baseValue, emit, t, x.isClosed, nil, arcs, nil}
return obj
case *list:
elm := rewriteRec(ctx, x.elem, x.elem, m).(*structLit)
len := rewriteRec(ctx, x.len, x.len.(evaluated), m)
typ := rewriteRec(ctx, x.typ, x.typ.(evaluated), m)
return &list{x.baseValue, elm, typ, len}
default:
return eval
}
}