internal: replace internal.CoreValue with more type-safe variant
CoreValue is now typed throught the internal/{value|types} packages.
Change-Id: I4b2df582a21fff2aaa83df61735141de11b6acbf
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9366
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/custom.go b/cmd/cue/cmd/custom.go
index ac5d554..ead236c 100644
--- a/cmd/cue/cmd/custom.go
+++ b/cmd/cue/cmd/custom.go
@@ -30,8 +30,8 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
"cuelang.org/go/internal"
- "cuelang.org/go/internal/core/adt"
itask "cuelang.org/go/internal/task"
+ "cuelang.org/go/internal/value"
_ "cuelang.org/go/pkg/tool/cli" // Register tasks
_ "cuelang.org/go/pkg/tool/exec"
_ "cuelang.org/go/pkg/tool/file"
@@ -76,8 +76,7 @@
// TODO: remove this block to allow commands to be defined in any file.
outer:
for _, v := range []cue.Value{tools.Lookup(typ), o} {
- _, vv := internal.CoreValue(v)
- w := vv.(*adt.Vertex)
+ _, w := value.ToInternal(v)
for _, c := range w.Conjuncts {
src := c.Source()
if src == nil {
diff --git a/cue/build.go b/cue/build.go
index 61f9f81..5900e89 100644
--- a/cue/build.go
+++ b/cue/build.go
@@ -56,13 +56,6 @@
}
return &Runtime{idx: newIndex()}
}
-
- internal.CoreValue = func(value interface{}) (runtime, vertex interface{}) {
- if v, ok := value.(Value); ok && v.v != nil {
- return v.idx, v.v
- }
- return nil, nil
- }
}
func dummyLoad(token.Pos, string) *build.Instance { return nil }
diff --git a/cue/types.go b/cue/types.go
index 1d1d844..a0e3d95 100644
--- a/cue/types.go
+++ b/cue/types.go
@@ -40,6 +40,7 @@
"cuelang.org/go/internal/core/runtime"
"cuelang.org/go/internal/core/subsume"
"cuelang.org/go/internal/core/validate"
+ "cuelang.org/go/internal/types"
)
// Kind determines the underlying type of a Value.
@@ -564,6 +565,14 @@
v *adt.Vertex
}
+type hiddenValue = Value
+
+// Core is for internal use only.
+func (v hiddenValue) Core(x *types.Value) {
+ x.V = v.v
+ x.R = v.idx
+}
+
func newErrValue(v Value, b *adt.Bottom) Value {
node := &adt.Vertex{BaseValue: b}
if v.v != nil {
diff --git a/internal/core/convert/go.go b/internal/core/convert/go.go
index 5191467..5c4d646 100644
--- a/internal/core/convert/go.go
+++ b/internal/core/convert/go.go
@@ -33,10 +33,9 @@
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/parser"
"cuelang.org/go/cue/token"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/compile"
- "cuelang.org/go/internal/core/runtime"
+ "cuelang.org/go/internal/types"
)
// This file contains functionality for converting Go to CUE.
@@ -225,14 +224,9 @@
}
func convertRec(ctx *adt.OpContext, nilIsTop bool, x interface{}) adt.Value {
- if internal.CoreValue != nil {
- if ii, iv := internal.CoreValue(x); ii != nil {
- i := ii.(*runtime.Runtime)
- v := iv.(*adt.Vertex)
- // TODO: panic if nto the same runtime.
- _ = i
- return v
- }
+ if t := (&types.Value{}); types.CastValue(t, x) {
+ // TODO: panic if nto the same runtime.
+ return t.V
}
src := ctx.Source()
switch v := x.(type) {
diff --git a/internal/core/convert/go_test.go b/internal/core/convert/go_test.go
index 1a034c7..9d3a35f 100644
--- a/internal/core/convert/go_test.go
+++ b/internal/core/convert/go_test.go
@@ -23,7 +23,6 @@
"github.com/cockroachdb/apd/v2"
"github.com/google/go-cmp/cmp"
- _ "cuelang.org/go/cue" // set internal.CoreValue
"cuelang.org/go/cue/errors"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/convert"
diff --git a/internal/core/dep/dep_test.go b/internal/core/dep/dep_test.go
index 6fb476b..449279b 100644
--- a/internal/core/dep/dep_test.go
+++ b/internal/core/dep/dep_test.go
@@ -20,14 +20,13 @@
"testing"
"cuelang.org/go/cue"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/debug"
"cuelang.org/go/internal/core/dep"
"cuelang.org/go/internal/core/eval"
- "cuelang.org/go/internal/core/runtime"
"cuelang.org/go/internal/cuetest"
"cuelang.org/go/internal/cuetxtar"
+ "cuelang.org/go/internal/value"
)
func TestVisit(t *testing.T) {
@@ -45,8 +44,7 @@
t.Fatal(inst.Err())
}
- rx, nx := internal.CoreValue(inst)
- ctxt := eval.NewContext(rx.(*runtime.Runtime), nx.(*adt.Vertex))
+ ctxt := eval.NewContext(value.ToInternal(inst))
testCases := []struct {
name string
@@ -69,8 +67,7 @@
for _, tc := range testCases {
v := inst.LookupPath(cue.ParsePath(tc.root))
- _, nx = internal.CoreValue(v)
- n := nx.(*adt.Vertex)
+ _, n := value.ToInternal(v)
w := t.Writer(tc.name)
t.Run(tc.name, func(sub *testing.T) {
@@ -105,9 +102,7 @@
v := inst.Lookup("a")
- rx, nx := internal.CoreValue(v)
- r := rx.(*runtime.Runtime)
- n := nx.(*adt.Vertex)
+ r, n := value.ToInternal(v)
ctxt := eval.NewContext(r, n)
diff --git a/internal/internal.go b/internal/internal.go
index 7544d95..31112fe 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -70,10 +70,6 @@
// GetRuntime reports the runtime for an Instance or Value.
var GetRuntime func(instance interface{}) interface{}
-// CoreValue returns an *runtime.Index and *adt.Vertex for a cue.Value.
-// It returns nil if value is not a cue.Value.
-var CoreValue func(value interface{}) (runtime, vertex interface{})
-
// MakeInstance makes a new instance from a value.
var MakeInstance func(value interface{}) (instance interface{})
diff --git a/internal/task/task.go b/internal/task/task.go
index b0af1d1..1b43bb4 100644
--- a/internal/task/task.go
+++ b/internal/task/task.go
@@ -23,8 +23,7 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/token"
- "cuelang.org/go/internal"
- "cuelang.org/go/internal/core/adt"
+ "cuelang.org/go/internal/value"
)
// A Context provides context for running a task.
@@ -117,9 +116,9 @@
}
func (t *taskError) InputPositions() (a []token.Pos) {
- _, nx := internal.CoreValue(t.v)
+ _, nx := value.ToInternal(t.v)
- for _, x := range nx.(*adt.Vertex).Conjuncts {
+ for _, x := range nx.Conjuncts {
if src := x.Source(); src != nil {
a = append(a, src.Pos())
}
diff --git a/internal/types/value.go b/internal/types/value.go
new file mode 100644
index 0000000..7b0301f
--- /dev/null
+++ b/internal/types/value.go
@@ -0,0 +1,37 @@
+// Copyright 2021 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 types
+
+import (
+ "cuelang.org/go/internal/core/adt"
+ "cuelang.org/go/internal/core/runtime"
+)
+
+type Value struct {
+ R *runtime.Runtime
+ V *adt.Vertex
+}
+
+type Interface interface {
+ Core(v *Value)
+}
+
+func CastValue(t *Value, x interface{}) bool {
+ c, ok := x.(Interface)
+ if ok {
+ c.Core(t)
+ }
+ return ok
+}
diff --git a/internal/value/value.go b/internal/value/value.go
new file mode 100644
index 0000000..62a127d
--- /dev/null
+++ b/internal/value/value.go
@@ -0,0 +1,40 @@
+// Copyright 2021 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 value contains functions for converting values to internal types
+// and various other Value-related utilities.
+package value
+
+import (
+ "cuelang.org/go/cue"
+ "cuelang.org/go/internal/core/adt"
+ "cuelang.org/go/internal/core/runtime"
+ "cuelang.org/go/internal/types"
+)
+
+func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) {
+ var t types.Value
+ v.Core(&t)
+ return t.R, t.V
+}
+
+// TODO:
+//
+// func Make(r *runtime.Runtime, v *adt.Vertex) cue.Value {
+// return cue.Value{}
+// }
+
+// func MakeError(r *runtime.Runtime, err error) cue.Value {
+// return cue.Value{}
+// }
diff --git a/tools/flow/flow.go b/tools/flow/flow.go
index b8861b6..3669efa 100644
--- a/tools/flow/flow.go
+++ b/tools/flow/flow.go
@@ -71,11 +71,10 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/convert"
"cuelang.org/go/internal/core/eval"
- "cuelang.org/go/internal/core/runtime"
+ "cuelang.org/go/internal/value"
)
var (
@@ -197,8 +196,7 @@
// New creates a Controller for a given Instance and TaskFunc.
func New(cfg *Config, inst *cue.Instance, f TaskFunc) *Controller {
v := inst.Value()
- rx, nx := internal.CoreValue(v)
- ctx := eval.NewContext(rx.(*runtime.Runtime), nx.(*adt.Vertex))
+ ctx := eval.NewContext(value.ToInternal(v))
c := &Controller{
isTask: f,
@@ -335,8 +333,8 @@
}
func (t *Task) vertex() *adt.Vertex {
- _, x := internal.CoreValue(t.v)
- return x.(*adt.Vertex)
+ _, x := value.ToInternal(t.v)
+ return x
}
func (t *Task) addDep(path string, dep *Task) {
diff --git a/tools/flow/run.go b/tools/flow/run.go
index de0f55f..91336b1 100644
--- a/tools/flow/run.go
+++ b/tools/flow/run.go
@@ -28,15 +28,13 @@
import (
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/eval"
- "cuelang.org/go/internal/core/runtime"
+ "cuelang.org/go/internal/value"
)
func (c *Controller) runLoop() {
- _, x := internal.CoreValue(c.inst)
- root := x.(*adt.Vertex)
+ _, root := value.ToInternal(c.inst)
// Copy the initial conjuncts.
n := len(root.Conjuncts)
@@ -64,8 +62,7 @@
t.state = Running
c.updateTaskValue(t)
- rx, nx := internal.CoreValue(t.v)
- t.ctxt = eval.NewContext(rx.(*runtime.Runtime), nx.(*adt.Vertex))
+ t.ctxt = eval.NewContext(value.ToInternal(t.v))
go func(t *Task) {
if err := t.r.Run(t, nil); err != nil {
diff --git a/tools/flow/tasks.go b/tools/flow/tasks.go
index a20c0be..a09e680 100644
--- a/tools/flow/tasks.go
+++ b/tools/flow/tasks.go
@@ -20,9 +20,9 @@
import (
"cuelang.org/go/cue"
"cuelang.org/go/cue/errors"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/dep"
+ "cuelang.org/go/internal/value"
)
// initTasks takes the current configuration and adds tasks to the list of
@@ -82,8 +82,7 @@
// getTask finds and marks tasks that are descendents of v.
func (c *Controller) getTask(scope *Task, v cue.Value) *Task {
// Look up cached node.
- _, n := internal.CoreValue(v)
- w := n.(*adt.Vertex)
+ _, w := value.ToInternal(v)
if t, ok := c.nodes[w]; ok {
return t
}
diff --git a/tools/trim/trim.go b/tools/trim/trim.go
index 0199689..d2dea39 100644
--- a/tools/trim/trim.go
+++ b/tools/trim/trim.go
@@ -56,11 +56,10 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
"cuelang.org/go/cue/ast/astutil"
- "cuelang.org/go/internal"
"cuelang.org/go/internal/core/adt"
"cuelang.org/go/internal/core/debug"
- "cuelang.org/go/internal/core/runtime"
"cuelang.org/go/internal/core/subsume"
+ "cuelang.org/go/internal/value"
)
// Config configures trim options.
@@ -73,9 +72,7 @@
// Trimming is done on a best-effort basis and only when the removed field
// is clearly implied by another field, rather than equal sibling fields.
func Files(files []*ast.File, inst *cue.Instance, cfg *Config) error {
- rx, vx := internal.CoreValue(inst.Value())
- r := rx.(*runtime.Runtime)
- v := vx.(*adt.Vertex)
+ r, v := value.ToInternal(inst.Value())
t := &trimmer{
Config: *cfg,