Skip to content

Commit 143be90

Browse files
committed
pkg: replace some string handling with go/types logic
The logic is a bit less repetitive and principled this way; for example, we don't need to detect lists and maps by string prefix, and we restrict the use of strings.Title on basic type names. Be more defensive in the adtKind method by failing if we reach the default switch case, so that we don't end up on adt.TopKind by accident. Give the two methods slightly better names and some documentation too. While here, remove switch cases which are entirely unused and cannot be used because we don't have support for them in CallCtxt, such as *big.Rat and time.Time. Signed-off-by: Daniel Martí <[email protected]> Change-Id: I0ff8df76358fd558f97d3ba711d19f4d69b1b843 Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/1201035 TryBot-Result: CUEcueckoo <[email protected]> Unity-Result: CUE porcuepine <[email protected]> Reviewed-by: Roger Peppe <[email protected]>
1 parent a558a4b commit 143be90

File tree

1 file changed

+60
-69
lines changed

1 file changed

+60
-69
lines changed

pkg/gen.go

+60-69
Original file line numberDiff line numberDiff line change
@@ -329,9 +329,9 @@ func (g *generator) genFunc(fn *types.Func) {
329329
kind := []string{}
330330
for i := 0; i < params.Len(); i++ {
331331
param := params.At(i)
332-
typ := strings.Title(g.goKind(param.Type()))
333-
argKind := g.goToCUE(param.Type())
334-
vals = append(vals, fmt.Sprintf("c.%s(%d)", typ, len(args)))
332+
methodName := g.callCtxtGetter(param.Type())
333+
argKind := g.adtKind(param.Type())
334+
vals = append(vals, fmt.Sprintf("c.%s(%d)", methodName, len(args)))
335335
args = append(args, param.Name())
336336
kind = append(kind, argKind)
337337
}
@@ -342,7 +342,7 @@ func (g *generator) genFunc(fn *types.Func) {
342342
}
343343
fmt.Fprintf(g.w, "\n},\n")
344344

345-
fmt.Fprintf(g.w, "Result: %s,\n", g.goToCUE(results.At(0).Type()))
345+
fmt.Fprintf(g.w, "Result: %s,\n", g.adtKind(results.At(0).Type()))
346346
if g.nonConcrete {
347347
fmt.Fprintf(g.w, "NonConcrete: true,\n")
348348
}
@@ -369,85 +369,76 @@ func (g *generator) genFunc(fn *types.Func) {
369369
}
370370
}
371371

372-
// TODO(mvdan): goKind and goToCUE still use a lot of strings; simplify.
373-
374-
func (g *generator) goKind(typ types.Type) string {
375-
switch str := types.TypeString(typ, nil); str {
372+
// callCtxtGetter returns the name of the [cuelang.org/go/internal/pkg.CallCtxt] method
373+
// which can be used to fetch a parameter of the given type.
374+
func (g *generator) callCtxtGetter(typ types.Type) string {
375+
switch typ := typ.(type) {
376+
case *types.Basic:
377+
return strings.Title(typ.String()) // "int" turns into "Int"
378+
case *types.Map:
379+
return "Struct"
380+
case *types.Slice:
381+
switch typ.Elem().String() {
382+
case "byte":
383+
return "Bytes"
384+
case "string":
385+
return "StringList"
386+
case "*cuelang.org/go/internal.Decimal":
387+
return "DecimalList"
388+
}
389+
return "List"
390+
}
391+
switch typ.String() {
376392
case "*math/big.Int":
377-
return "bigInt"
393+
return "BigInt"
378394
case "*math/big.Float":
379-
return "bigFloat"
380-
case "*math/big.Rat":
381-
return "bigRat"
382-
case "cuelang.org/go/internal/core/adt.Bottom":
383-
return "error"
395+
return "BigFloat"
384396
case "*cuelang.org/go/internal.Decimal":
385-
return "decimal"
397+
return "Decimal"
386398
case "cuelang.org/go/internal/pkg.List":
387-
return "cueList"
399+
return "CueList"
388400
case "cuelang.org/go/internal/pkg.Struct":
389-
return "struct"
390-
case "[]*cuelang.org/go/internal.Decimal":
391-
return "decimalList"
392-
case "cuelang.org/go/cue.Value":
393-
return "value"
401+
return "Struct"
402+
case "cuelang.org/go/cue.Value",
403+
"cuelang.org/go/cue/ast.Expr":
404+
return "Value"
394405
case "cuelang.org/go/internal/pkg.Schema":
395406
g.nonConcrete = true
396-
return "schema"
397-
case "cuelang.org/go/cue.List":
398-
return "list"
399-
case "[]string":
400-
return "stringList"
401-
case "[]byte":
402-
return "bytes"
403-
case "[]cuelang.org/go/cue.Value":
404-
return "list"
407+
return "Schema"
405408
case "io.Reader":
406-
return "reader"
407-
case "time.Time":
408-
return "string"
409-
default:
410-
return str
409+
return "Reader"
410+
case "error":
411+
return "Bottom" // for [generator.cueTypeExpression]
411412
}
413+
return "Value" // for [generator.cueTypeExpression]
412414
}
413415

414-
func (g *generator) goToCUE(typ types.Type) (cueKind string) {
416+
// adtKind provides a Go expression string which describes
417+
// a [cuelang.org/go/internal/core/adt.Kind] value for the given type.
418+
func (g *generator) adtKind(typ types.Type) string {
415419
// TODO: detect list and structs types for return values.
416-
switch k := g.goKind(typ); k {
417-
case "error":
418-
cueKind += "adt.BottomKind"
419-
case "bool":
420-
cueKind += "adt.BoolKind"
421-
case "bytes", "reader":
422-
cueKind += "adt.BytesKind|adt.StringKind"
423-
case "string":
424-
cueKind += "adt.StringKind"
425-
case "int", "int8", "int16", "int32", "rune", "int64",
426-
"uint", "byte", "uint8", "uint16", "uint32", "uint64",
427-
"bigInt":
428-
cueKind += "adt.IntKind"
429-
case "float64", "bigRat", "bigFloat", "decimal":
430-
cueKind += "adt.NumberKind"
431-
case "list", "decimalList", "stringList", "cueList":
432-
cueKind += "adt.ListKind"
433-
case "struct":
434-
cueKind += "adt.StructKind"
435-
case "value":
436-
// Must use callCtxt.value method for these types and resolve manually.
437-
cueKind += "adt.TopKind" // TODO: can be more precise
420+
switch name := g.callCtxtGetter(typ); name {
421+
case "Bottom", "Bool", "String", "Struct", "Int", "List":
422+
return "adt." + name + "Kind"
423+
case "Int8", "Int16", "Int32", "Rune", "Int64",
424+
"Uint", "Byte", "Uint8", "Uint16", "Uint32", "Uint64",
425+
"BigInt":
426+
return "adt.IntKind"
427+
case "Float64", "BigFloat", "Decimal":
428+
return "adt.NumberKind"
429+
case "Complex128":
430+
return "adt.TopKind" // TODO(mvdan): what should we return here?
431+
case "DecimalList", "StringList", "CueList":
432+
return "adt.ListKind"
433+
case "Bytes", "Reader":
434+
return "adt.BytesKind | adt.StringKind"
435+
case "Value", "Schema":
436+
// Must use the CallCtxt.Value method for these types and resolve manually.
437+
return "adt.TopKind" // TODO: can be more precise
438438
default:
439-
switch {
440-
case strings.HasPrefix(k, "[]"):
441-
cueKind += "adt.ListKind"
442-
case strings.HasPrefix(k, "map["):
443-
cueKind += "adt.StructKind"
444-
default:
445-
// log.Println("Unknown type:", k)
446-
// Must use callCtxt.value method for these types and resolve manually.
447-
cueKind += "adt.TopKind" // TODO: can be more precise
448-
}
439+
log.Fatal("unknown CallCtxt type: ", name)
440+
return ""
449441
}
450-
return cueKind
451442
}
452443

453444
var errNoCUEFiles = errors.New("no CUE files in directory")

0 commit comments

Comments
 (0)