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

Commit

Permalink
internal: replace untyped functions with typed ones
Browse files Browse the repository at this point in the history
- UnifyBuiltin
- FromGoValue / FromGoType
- EvalExpr

Change-Id: I361630412b48ca2c0c5fbc31f627e53a8921ecb0
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9425
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
  • Loading branch information
mpvl committed Apr 21, 2021
1 parent d76e2cc commit 1f78a8d
Show file tree
Hide file tree
Showing 11 changed files with 109 additions and 132 deletions.
4 changes: 2 additions & 2 deletions cmd/cue/cmd/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import (
"cuelang.org/go/cue/load"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
"cuelang.org/go/internal"
"cuelang.org/go/internal/encoding"
"cuelang.org/go/internal/filetypes"
"cuelang.org/go/internal/value"
Expand Down Expand Up @@ -350,7 +349,8 @@ func (i *expressionIter) value() cue.Value {
if len(i.expr) == 0 {
return i.iter.value()
}
return internal.EvalExpr(i.iter.value(), i.expr[i.i]).(cue.Value)
// TODO: replace with FillPath.
return value.EvalExpr(i.iter.value(), i.expr[i.i])
}

type config struct {
Expand Down
3 changes: 1 addition & 2 deletions cmd/cue/cmd/custom.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import (

"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
"cuelang.org/go/internal"
itask "cuelang.org/go/internal/task"
"cuelang.org/go/internal/value"
_ "cuelang.org/go/pkg/tool/cli" // Register tasks
Expand Down Expand Up @@ -201,7 +200,7 @@ func newTaskFunc(cmd *Command) flow.TaskFunc {
}

// Verify entry against template.
v = internal.UnifyBuiltin(v, kind).(cue.Value)
v = value.UnifyBuiltin(v, kind)
if err := v.Err(); err != nil {
return nil, errors.Promote(err, "newTask")
}
Expand Down
24 changes: 0 additions & 24 deletions cue/builtin.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,8 @@
package cue

import (
"strings"

"cuelang.org/go/cue/token"
"cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/runtime"
)

func pos(n adt.Node) (p token.Pos) {
Expand All @@ -33,23 +29,3 @@ func pos(n adt.Node) (p token.Pos) {
}
return src.Pos()
}

func init() {
// TODO: unroll this function. Should no longer be necessary to be internal.
internal.UnifyBuiltin = func(val interface{}, kind string) interface{} {
v := val.(Value)

p := strings.Split(kind, ".")
pkg, name := p[0], p[1]
s, _ := runtime.SharedRuntime.LoadImport(pkg)
if s == nil {
return v
}
a := s.Lookup(v.idx.Label(name, false))
if a == nil {
return v
}

return v.Unify(makeValue(v.idx, a))
}
}
46 changes: 0 additions & 46 deletions cue/go.go

This file was deleted.

9 changes: 0 additions & 9 deletions cue/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,15 +173,6 @@ func (inst *Instance) eval(ctx *adt.OpContext) adt.Value {
return v
}

func init() {
internal.EvalExpr = func(value, expr interface{}) interface{} {
v := value.(Value)
e := expr.(ast.Expr)
ctx := newContext(v.idx)
return newValueRoot(v.idx, ctx, evalExpr(ctx, v.v, e))
}
}

// pkgID reports a package path that can never resolve to a valid package.
func pkgID() string {
return "_"
Expand Down
11 changes: 6 additions & 5 deletions cuego/cuego.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import (
"sync"

"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/cue/parser"
"cuelang.org/go/internal"
"cuelang.org/go/internal/value"
)

// DefaultContext is the shared context used with top-level functions.
Expand Down Expand Up @@ -159,12 +160,12 @@ func (c *Context) Constrain(x interface{}, constraints string) error {
var (
mutex sync.Mutex
instance *cue.Instance
runtime = &cue.Runtime{}
runtime = cuecontext.New()
)

func init() {
var err error
instance, err = runtime.Compile("<cuego>", "{}")
instance, err = value.ConvertToRuntime(runtime).Compile("<cuego>", "{}")
if err != nil {
panic(err)
}
Expand All @@ -176,7 +177,7 @@ func fromGoValue(x interface{}, nilIsNull bool) (v cue.Value, err error) {
// Instance) here as any previously unrecognized field can never match an
// existing one and can only be merged.
mutex.Lock()
v = internal.FromGoValue(runtime, x, nilIsNull).(cue.Value)
v = value.FromGoValue(runtime, x, nilIsNull)
mutex.Unlock()
if err := v.Err(); err != nil {
return v, err
Expand Down Expand Up @@ -204,7 +205,7 @@ func fromGoType(x interface{}) cue.Value {
// Instance) here as any previously unrecognized field can never match an
// existing one and can only be merged.
mutex.Lock()
v := internal.FromGoType(runtime, x).(cue.Value)
v := value.FromGoType(runtime, x)
mutex.Unlock()
return v
}
17 changes: 8 additions & 9 deletions encoding/gocode/gocodec/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (

"cuelang.org/go/cue"
"cuelang.org/go/cue/cuecontext"
"cuelang.org/go/internal"
"cuelang.org/go/internal/value"
)

Expand All @@ -36,7 +35,7 @@ type Config struct {
// A Codec decodes and encodes CUE from and to Go values and validates and
// completes Go values based on CUE templates.
type Codec struct {
runtime *cue.Runtime
runtime *cue.Context
mutex sync.RWMutex
}

Expand All @@ -46,7 +45,7 @@ type Codec struct {
// Runtime is not used elsewhere while using Codec. However, only the concurrent
// use of Decode, Validate, and Complete is efficient.
func New(r *cue.Runtime, c *Config) *Codec {
return &Codec{runtime: r}
return &Codec{runtime: value.ConvertToContext(r)}
}

// ExtractType extracts a CUE value from a Go type.
Expand Down Expand Up @@ -162,24 +161,24 @@ func (c *Codec) Complete(v cue.Value, x interface{}) error {
return w.Unify(v).Decode(x)
}

func fromGoValue(r *cue.Runtime, x interface{}, allowDefault bool) (cue.Value, error) {
v := internal.FromGoValue(r, x, allowDefault).(cue.Value)
func fromGoValue(r *cue.Context, x interface{}, allowDefault bool) (cue.Value, error) {
v := value.FromGoValue(r, x, allowDefault)
if err := v.Err(); err != nil {
return v, err
}
return v, nil
}

func fromGoType(r *cue.Runtime, x interface{}) (cue.Value, error) {
v := internal.FromGoType(r, x).(cue.Value)
func fromGoType(r *cue.Context, x interface{}) (cue.Value, error) {
v := value.FromGoType(r, x)
if err := v.Err(); err != nil {
return v, err
}
return v, nil
}

func checkAndForkContext(r *cue.Runtime, v cue.Value) *cue.Runtime {
rr := value.ConvertToRuntime(v.Context())
func checkAndForkContext(r *cue.Context, v cue.Value) *cue.Context {
rr := v.Context()
if r != rr {
panic("value not from same runtime")
}
Expand Down
24 changes: 0 additions & 24 deletions internal/internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,6 @@ type Decimal = apd.Decimal
// incomplete.
var ErrIncomplete = errors.New("incomplete value")

// EvalExpr evaluates an expression within an existing struct value.
// Identifiers only resolve to values defined within the struct.
//
// Expressions may refer to builtin packages if they can be uniquely identified
//
// Both value and result are of type cue.Value, but are an interface to prevent
// cyclic dependencies.
//
// TODO: extract interface
var EvalExpr func(value, expr interface{}) (result interface{})

// FromGoValue converts an arbitrary Go value to the corresponding CUE value.
// instance must be of type *cue.Instance.
// The returned value is a cue.Value, which the caller must cast to.
var FromGoValue func(instance, x interface{}, allowDefault bool) interface{}

// FromGoType converts an arbitrary Go type to the corresponding CUE value.
// instance must be of type *cue.Instance.
// The returned value is a cue.Value, which the caller must cast to.
var FromGoType func(instance, x interface{}) interface{}

// UnifyBuiltin returns the given Value unified with the given builtin template.
var UnifyBuiltin func(v interface{}, kind string) interface{}

// MakeInstance makes a new instance from a value.
var MakeInstance func(value interface{}) (instance interface{})

Expand Down
95 changes: 88 additions & 7 deletions internal/value/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,15 @@
package value

import (
"strings"

"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/errors"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/compile"
"cuelang.org/go/internal/core/convert"
"cuelang.org/go/internal/core/eval"
"cuelang.org/go/internal/core/runtime"
"cuelang.org/go/internal/types"
)
Expand All @@ -38,17 +45,91 @@ func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) {
return t.R, t.V
}

// TODO:
// Make wraps cue.MakeValue.
func Make(ctx *adt.OpContext, v adt.Value) cue.Value {
return (*cue.Context)(ctx.Impl().(*runtime.Runtime)).Encode(v)
}

func MakeError(r *runtime.Runtime, err errors.Error) cue.Value {
b := &adt.Bottom{Err: err}
node := &adt.Vertex{BaseValue: b}
node.UpdateStatus(adt.Finalized)
node.AddConjunct(adt.MakeRootConjunct(nil, b))
return (*cue.Context)(r).Encode(node)
}

// UnifyBuiltin returns the given Value unified with the given builtin template.
func UnifyBuiltin(v cue.Value, kind string) cue.Value {
p := strings.Split(kind, ".")
pkg, name := p[0], p[1]
s, _ := runtime.SharedRuntime.LoadImport(pkg)
if s == nil {
return v
}

ctx := v.Context()
a := s.Lookup((*runtime.Runtime)(ctx).Label(name, false))
if a == nil {
return v
}

return v.Unify(ctx.Encode(a))
}

func FromGoValue(r *cue.Context, x interface{}, nilIsTop bool) cue.Value {
rt := (*runtime.Runtime)(r)
rt.Init()
ctx := eval.NewContext(rt, nil)
v := convert.GoValueToValue(ctx, x, nilIsTop)
n := adt.ToVertex(v)
return r.Encode(n)
}

func FromGoType(r *cue.Context, x interface{}) cue.Value {
rt := (*runtime.Runtime)(r)
rt.Init()
ctx := eval.NewContext(rt, nil)
expr, err := convert.GoTypeToExpr(ctx, x)
if err != nil {
expr = &adt.Bottom{Err: err}
}
n := &adt.Vertex{}
n.AddConjunct(adt.MakeRootConjunct(nil, expr))
return r.Encode(n)
}

// EvalExpr evaluates an expression within an existing struct value.
// Identifiers only resolve to values defined within the struct.
//
// func Make(r *runtime.Runtime, v *adt.Vertex) cue.Value {
// return cue.Value{}
// }
// Expressions may refer to builtin packages if they can be uniquely identified
func EvalExpr(value cue.Value, expr ast.Expr) cue.Value {
r, scope := ToInternal(value)
ctx := eval.NewContext(r, nil)

cfg := &compile.Config{
Scope: scope,
Imports: func(x *ast.Ident) (pkgPath string) {
if !isBuiltin(x.Name) {
return ""
}
return x.Name
},
}

// func MakeError(r *runtime.Runtime, err error) cue.Value {
// return cue.Value{}
// }
c, err := compile.Expr(cfg, ctx, pkgID(), expr)
if err != nil {
return MakeError(r, err)
}
v := adt.Resolve(ctx, c)

return (*cue.Context)(r).Encode(v)
}

func isBuiltin(s string) bool {
return runtime.SharedRuntime.IsBuiltinPackage(s)
}

// pkgID reports a package path that can never resolve to a valid package.
func pkgID() string {
return "_"
}
Loading

0 comments on commit 1f78a8d

Please sign in to comment.