Skip to content

Commit e4e6d68

Browse files
committed
cmd/cue: use fewer go/types.Type.String calls
Reimplement the same logic without roundtrips to the String method, which makes our logic more precise and less error prone, and also avoids the relatively expensive String call with its buffer and printer allocations and added complexity. More String method calls remain; these were the lowest hanging fruit. Also tweak the TODO about []byte and []uint8. Signed-off-by: Daniel Martí <[email protected]> Change-Id: Ifedcf04f1c492b69b23760f5b8e8858fe3cd99bc Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1185034 TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Roger Peppe <[email protected]>
1 parent abc8bb1 commit e4e6d68

File tree

1 file changed

+23
-19
lines changed

1 file changed

+23
-19
lines changed

cmd/cue/cmd/get_go.go

+23-19
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,11 @@ func (e *extractor) usedPkg(pkg string) {
281281
}
282282

283283
var (
284-
typeAny = types.NewInterfaceType(nil, nil).Complete() // interface{}
285-
typeBytes = types.NewSlice(types.Typ[types.Byte]) // []byte
286-
typeError = types.Universe.Lookup("error").Type() // error
284+
typeAny = types.Universe.Lookup("any").Type() // any or interface{}
285+
typeByte = types.Universe.Lookup("byte").Type() // byte
286+
typeBytes = types.NewSlice(typeByte) // []byte
287+
typeString = types.Universe.Lookup("string").Type() // string
288+
typeError = types.Universe.Lookup("error").Type() // error
287289
)
288290

289291
// Note that we can leave positions, packages, and parameter/result names empty.
@@ -804,12 +806,13 @@ func (e *extractor) reportDecl(x *ast.GenDecl) (a []cueast.Decl) {
804806
}
805807

806808
typ := e.pkg.TypesInfo.TypeOf(name)
807-
if s := typ.String(); !strings.Contains(s, "untyped") {
808-
switch s {
809-
case "byte", "string", "error":
810-
default:
811-
cv = cueast.NewBinExpr(cuetoken.AND, e.makeType(typ), cv)
809+
switch typ {
810+
case typeByte, typeString, typeError:
811+
default:
812+
if basic, ok := typ.(*types.Basic); ok && basic.Info()&types.IsUntyped != 0 {
813+
break // untyped basic types do not make valid identifiers
812814
}
815+
cv = cueast.NewBinExpr(cuetoken.AND, e.makeType(typ), cv)
813816
}
814817

815818
f.Value = cv
@@ -963,7 +966,7 @@ func supportedType(stack []types.Type, t types.Type) (ok bool) {
963966
t = t.Underlying()
964967
switch x := t.(type) {
965968
case *types.Basic:
966-
return x.String() != "invalid type"
969+
return x.Kind() != types.Invalid
967970
case *types.Named:
968971
return true
969972
case *types.Pointer:
@@ -1042,9 +1045,8 @@ func (e *extractor) makeType(expr types.Type) (result cueast.Expr) {
10421045
return e.ident("_", false)
10431046
}
10441047
// Check for builtin packages.
1045-
// TODO: replace these literal types with a reference to the fixed
1046-
switch obj.Type().String() {
1047-
case "time.Time":
1048+
switch {
1049+
case obj.Pkg().Path() == "time" && obj.Name() == "Time":
10481050
ref := e.ident(e.pkgNames[obj.Pkg().Path()].name, false)
10491051
var name *cueast.Ident
10501052
if ref.Name != "time" {
@@ -1053,7 +1055,7 @@ func (e *extractor) makeType(expr types.Type) (result cueast.Expr) {
10531055
ref.Node = cueast.NewImport(name, "time")
10541056
return cueast.NewSel(ref, obj.Name())
10551057

1056-
case "math/big.Int":
1058+
case obj.Pkg().Path() == "math/big" && obj.Name() == "Int":
10571059
return e.ident("int", false)
10581060

10591061
default:
@@ -1151,16 +1153,18 @@ func (e *extractor) makeType(expr types.Type) (result cueast.Expr) {
11511153
return st
11521154

11531155
case *types.Slice:
1154-
// TODO: should this be x.Elem().Underlying().String()? One could
1155-
// argue either way.
1156-
if x.Elem().String() == "byte" {
1156+
// Note that []byte is treated different from []uint8,
1157+
// even though byte is an alias for the basic type uint8.
1158+
// TODO: reconsider this; both encoding/json and the future v2
1159+
// encode []uint8, or anything assignable to []byte, as bytes.
1160+
if x.Elem() == typeByte {
11571161
return e.ident("bytes", false)
11581162
}
11591163
return cueast.NewList(&cueast.Ellipsis{Type: e.makeType(x.Elem())})
11601164

11611165
case *types.Array:
1162-
if x.Elem().String() == "byte" {
1163-
// TODO: no way to constraint lengths of bytes for now, as regexps
1166+
if x.Elem() == typeByte {
1167+
// TODO: no way to constrain lengths of bytes for now, as regexps
11641168
// operate on Unicode, not bytes. So we need
11651169
// fmt.Fprint(e.w, fmt.Sprintf("=~ '^\C{%d}$'", x.Len())),
11661170
// but regexp does not support that.
@@ -1202,7 +1206,7 @@ func (e *extractor) makeType(expr types.Type) (result cueast.Expr) {
12021206
case types.Complex64, types.Complex128:
12031207
return e.ident("_", false)
12041208
}
1205-
return e.ident(x.String(), false)
1209+
return e.ident(x.Name(), false)
12061210

12071211
case *types.Union:
12081212
var exprs []cueast.Expr

0 commit comments

Comments
 (0)