internal: add ToFile and ToExpr
Also fixes cue/gen.go
Change-Id: I6497649e3863dbacd896d0246661ef2c9780f84e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5560
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go
index 14d579b..6618a02 100644
--- a/internal/encoding/encoding.go
+++ b/internal/encoding/encoding.go
@@ -37,6 +37,7 @@
"cuelang.org/go/encoding/jsonschema"
"cuelang.org/go/encoding/openapi"
"cuelang.org/go/encoding/protobuf"
+ "cuelang.org/go/internal"
"cuelang.org/go/internal/filetypes"
"cuelang.org/go/internal/third_party/yaml"
)
@@ -91,25 +92,11 @@
}
func toFile(x ast.Expr) *ast.File {
- switch x := x.(type) {
- case nil:
- return nil
- case *ast.StructLit:
- return &ast.File{Decls: x.Elts}
- default:
- return &ast.File{Decls: []ast.Decl{&ast.EmbedDecl{Expr: x}}}
- }
+ return internal.ToFile(x)
}
func valueToFile(v cue.Value) *ast.File {
- switch x := v.Syntax().(type) {
- case *ast.File:
- return x
- case ast.Expr:
- return toFile(x)
- default:
- panic("unrreachable")
- }
+ return internal.ToFile(v.Syntax())
}
func (i *Decoder) File() *ast.File {
diff --git a/internal/internal.go b/internal/internal.go
index f12f267..63ec888 100644
--- a/internal/internal.go
+++ b/internal/internal.go
@@ -146,6 +146,53 @@
return &ast.Attribute{Text: buf.String()}
}
+// ToExpr converts a node to an expression. If it is a file, it will return
+// it as a struct. If is an expression, it will return it as is. Otherwise
+// it panics.
+func ToExpr(n ast.Node) ast.Expr {
+ switch x := n.(type) {
+ case nil:
+ return nil
+
+ case ast.Expr:
+ return x
+
+ case *ast.File:
+ start := 0
+ outer:
+ for i, d := range x.Decls {
+ switch d.(type) {
+ case *ast.Package, *ast.ImportDecl:
+ start = i + 1
+ case *ast.CommentGroup, *ast.Attribute:
+ default:
+ break outer
+ }
+ }
+ return &ast.StructLit{Elts: x.Decls[start:]}
+
+ default:
+ panic(fmt.Sprintf("Unsupported node type %T", x))
+ }
+}
+
+// ToFile converts an expression to a file.
+//
+// Adjusts the spacing of x when needed.
+func ToFile(n ast.Node) *ast.File {
+ switch x := n.(type) {
+ case nil:
+ return nil
+ case *ast.StructLit:
+ return &ast.File{Decls: x.Elts}
+ case ast.Expr:
+ ast.SetRelPos(x, token.NoSpace)
+ return &ast.File{Decls: []ast.Decl{&ast.EmbedDecl{Expr: x}}}
+ default:
+ panic(fmt.Sprintf("Unsupported node type %T", x))
+ }
+}
+
// IsEllipsis reports whether the declaration can be represented as an ellipsis.
func IsEllipsis(x ast.Decl) bool {
// ...