cmd/cue/cmd: import: use astutil
this simplifies the code, but, more importantly, now
passes correct code to CompileExpr. This, in turn,
will allow enabling of stricter error checking.
Change-Id: I5e9d3ca0c71805bf4760e02fd83d3903ac27ee7a
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3761
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cmd/cue/cmd/import.go b/cmd/cue/cmd/import.go
index 8f6bab2..814c37d 100644
--- a/cmd/cue/cmd/import.go
+++ b/cmd/cue/cmd/import.go
@@ -27,6 +27,7 @@
"cuelang.org/go/cue"
"cuelang.org/go/cue/ast"
+ "cuelang.org/go/cue/ast/astutil"
"cuelang.org/go/cue/encoding"
"cuelang.org/go/cue/errors"
"cuelang.org/go/cue/format"
@@ -402,16 +403,23 @@
f := &ast.File{}
- h := hoister{
- fields: map[string]bool{},
- altNames: map[string]*ast.Ident{},
+ if flagRecursive.Bool(cmd) {
+ h := hoister{fields: map[string]bool{}}
+
+ imports := &ast.ImportDecl{}
+
+ h.hoist(&ast.File{Decls: []ast.Decl{
+ imports,
+ &ast.EmbedDecl{Expr: &ast.ListLit{Elts: objs}},
+ }})
+
+ if len(imports.Specs) > 0 {
+ f.Decls = append(f.Decls, imports)
+ }
}
index := newIndex()
for _, expr := range objs {
- if flagRecursive.Bool(cmd) {
- h.hoist(expr)
- }
// Compute a path different from root.
var pathElems []ast.Label
@@ -477,25 +485,6 @@
}
}
- if len(h.altNames) > 0 {
- imports := &ast.ImportDecl{}
-
- for _, enc := range encoding.All() {
- if ident, ok := h.altNames[enc.Name()]; ok {
- short := enc.Name()
- name := h.uniqueName(short, "", "")
- ident.Name = name
- if name == short {
- ident = nil
- }
-
- imports.Specs = append(imports.Specs,
- ast.NewImport(ident, "encoding/"+short))
- }
- }
- f.Decls = append([]ast.Decl{imports}, f.Decls...)
- }
-
if pkg != "" {
p := &ast.Package{Name: ast.NewIdent(pkg)}
f.Decls = append([]ast.Decl{p}, f.Decls...)
@@ -638,12 +627,11 @@
}
type hoister struct {
- fields map[string]bool
- altNames map[string]*ast.Ident
+ fields map[string]bool
}
-func (h *hoister) hoist(expr ast.Expr) {
- ast.Walk(expr, nil, func(n ast.Node) {
+func (h *hoister) hoist(f *ast.File) {
+ ast.Walk(f, nil, func(n ast.Node) {
name := ""
switch x := n.(type) {
case *ast.Field:
@@ -656,65 +644,55 @@
}
})
- ast.Walk(expr, func(n ast.Node) bool {
+ _ = astutil.Apply(f, func(c astutil.Cursor) bool {
+ n := c.Node()
switch n.(type) {
case *ast.Comprehension:
return false
}
return true
- }, func(n ast.Node) {
- obj, ok := n.(*ast.StructLit)
- if !ok {
- return
- }
- for i := 0; i < len(obj.Elts); i++ {
- f, ok := obj.Elts[i].(*ast.Field)
- if !ok {
- continue
- }
-
+ }, func(c astutil.Cursor) bool {
+ switch f := c.Node().(type) {
+ case *ast.Field:
name, ident := internal.LabelName(f.Label)
if name == "" || !ident {
- continue
+ return false
}
lit, ok := f.Value.(*ast.BasicLit)
if !ok || lit.Kind != token.STRING {
- continue
+ return false
}
str, err := literal.Unquote(lit.Value)
if err != nil {
- continue
+ return false
}
expr, enc := tryParse(str)
if expr == nil {
- continue
+ return false
}
- if h.altNames[enc.typ] == nil {
- h.altNames[enc.typ] = &ast.Ident{Name: "_cue"} // set name later
+ pkg := c.Import("encoding/" + enc.typ)
+ if pkg == nil {
+ return false
}
// found a replacable string
dataField := h.uniqueName(name, "_", "cue_")
f.Value = ast.NewCall(
- ast.NewSel(h.altNames[enc.typ], "Marshal"),
+ ast.NewSel(pkg, "Marshal"),
ast.NewIdent(dataField))
- obj.Elts = append(obj.Elts, nil)
- copy(obj.Elts[i+1:], obj.Elts[i:])
-
- obj.Elts[i+1] = &ast.Alias{
+ c.InsertAfter(astutil.ApplyRecursively(&ast.Alias{
Ident: ast.NewIdent(dataField),
Expr: expr,
- }
-
- h.hoist(expr)
+ }))
}
+ return true
})
}
diff --git a/cmd/cue/cmd/testdata/script/import_hoiststr.txt b/cmd/cue/cmd/testdata/script/import_hoiststr.txt
index 266e99e..e821f07 100644
--- a/cmd/cue/cmd/testdata/script/import_hoiststr.txt
+++ b/cmd/cue/cmd/testdata/script/import_hoiststr.txt
@@ -1,7 +1,7 @@
cue import -o - -f --list -l '"\(strings.ToLower(kind))" "\(name)"' --recursive ./import
cmp stdout expect-stdout
-- expect-stdout --
-import xjson "encoding/json"
+import json656e63 "encoding/json"
service: {
booster: [{
@@ -14,7 +14,7 @@
supplement
foo
"""
- json: xjson.Marshal(_cue_json)
+ json: json656e63.Marshal(_cue_json)
_cue_json = [1, 2]
}]
}
diff --git a/doc/tutorial/kubernetes/quick/services/mon/alertmanager/configmap.cue b/doc/tutorial/kubernetes/quick/services/mon/alertmanager/configmap.cue
index a8b8d62..e641eed 100644
--- a/doc/tutorial/kubernetes/quick/services/mon/alertmanager/configmap.cue
+++ b/doc/tutorial/kubernetes/quick/services/mon/alertmanager/configmap.cue
@@ -1,12 +1,12 @@
package kube
-import "encoding/yaml"
+import yaml656e63 "encoding/yaml"
configMap alertmanager: {
apiVersion: "v1"
kind: "ConfigMap"
data: {
- "alerts.yaml": yaml.Marshal(_cue_alerts_yaml)
+ "alerts.yaml": yaml656e63.Marshal(_cue_alerts_yaml)
_cue_alerts_yaml = {
receivers: [{
name: "pager"
diff --git a/doc/tutorial/kubernetes/quick/services/mon/prometheus/configmap.cue b/doc/tutorial/kubernetes/quick/services/mon/prometheus/configmap.cue
index 4ef2755..c73acf7 100644
--- a/doc/tutorial/kubernetes/quick/services/mon/prometheus/configmap.cue
+++ b/doc/tutorial/kubernetes/quick/services/mon/prometheus/configmap.cue
@@ -1,12 +1,12 @@
package kube
-import "encoding/yaml"
+import yaml656e63 "encoding/yaml"
configMap prometheus: {
apiVersion: "v1"
kind: "ConfigMap"
data: {
- "alert.rules": yaml.Marshal(_cue_alert_rules)
+ "alert.rules": yaml656e63.Marshal(_cue_alert_rules)
_cue_alert_rules = {
groups: [{
name: "rules.yaml"
@@ -48,7 +48,7 @@
}]
}
- "prometheus.yml": yaml.Marshal(_cue_prometheus_yml)
+ "prometheus.yml": yaml656e63.Marshal(_cue_prometheus_yml)
_cue_prometheus_yml = {
global scrape_interval: "15s"
rule_files: [