Skip to content

Commit

Permalink
refactor: Remove the need for the flux_test_gen files
Browse files Browse the repository at this point in the history
  • Loading branch information
Markus Westerlind committed May 12, 2022
1 parent 095dea7 commit 2af280a
Show file tree
Hide file tree
Showing 55 changed files with 195 additions and 658,208 deletions.
200 changes: 6 additions & 194 deletions internal/cmd/builtin/cmd/generate.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ import (
"os"
"path"
"path/filepath"
"reflect"
"strings"
"time"

"github.com/dave/jennifer/jen"
"github.com/influxdata/flux/ast"
Expand Down Expand Up @@ -174,7 +172,11 @@ func generate(cmd *cobra.Command, args []string) error {

// Write the import file
f := jen.NewFile(path.Base(pkgName))
f.HeaderComment("// DO NOT EDIT: This file is autogenerated via the builtin command.")
f.HeaderComment(`// DO NOT EDIT: This file is autogenerated via the builtin command.
//
// The imports in this file ensures that all the init functions runs and registers
// the builtins for the flux runtime
`)
f.Anon(goPackages...)
return f.Save(filepath.Join(rootDir, importFile))
}
Expand Down Expand Up @@ -212,31 +214,13 @@ func generateTestPkgList(imports []string) error {

file := jen.NewFile(path.Base(pkgName))
file.HeaderComment("// DO NOT EDIT: This file is autogenerated via the builtin command.")
// var FluxTestPackages = func() []*ast.Package {
// statements ...
// }
file.
Var().
Id("FluxTestPackages").
Op("=").
Func().
Params().
Index().
Op("*").
Qual("github.com/influxdata/flux/ast", "Package").
Block(stmts...).
Call()
file.Anon(imports...)
return file.Save(filepath.Join(rootDir, "test_packages.go"))
}

func generateTestASTFile(dir, pkg string, pkgs []*ast.Package) error {
file := jen.NewFile(pkg)
file.HeaderComment("// DO NOT EDIT: This file is autogenerated via the builtin command.")
v, err := constructValue(reflect.ValueOf(pkgs))
if err != nil {
return err
}
file.Var().Id("FluxTestPackages").Op("=").Add(v)
return file.Save(filepath.Join(dir, "flux_test_gen.go"))
}

Expand Down Expand Up @@ -284,175 +268,3 @@ func walkDirs(path string, f func(dir string) error) error {
}
return nil
}

// indirectType returns a code statement that represents the type expression
// for the given type.
func indirectType(typ reflect.Type) *jen.Statement {
switch typ.Kind() {
case reflect.Map:
c := jen.Index(indirectType(typ.Key()))
c.Add(indirectType(typ.Elem()))
return c
case reflect.Ptr:
c := jen.Op("*")
c.Add(indirectType(typ.Elem()))
return c
case reflect.Array, reflect.Slice:
c := jen.Index()
c.Add(indirectType(typ.Elem()))
return c
default:
return jen.Qual(typ.PkgPath(), typ.Name())
}
}

// constructValue returns a Code value for the given value.
func constructValue(v reflect.Value) (jen.Code, error) {
switch v.Kind() {
case reflect.Array:
s := indirectType(v.Type())
values := make([]jen.Code, v.Len())
for i := 0; i < v.Len(); i++ {
val, err := constructValue(v.Index(i))
if err != nil {
return nil, err
}
values[i] = val
}
s.Values(values...)
return s, nil
case reflect.Slice:
if v.IsNil() {
return jen.Nil(), nil
}
s := indirectType(v.Type())
values := make([]jen.Code, v.Len())
for i := 0; i < v.Len(); i++ {
val, err := constructValue(v.Index(i))
if err != nil {
return nil, err
}
values[i] = val
}
s.Values(values...)
return s, nil
case reflect.Interface:
if v.IsNil() {
return jen.Nil(), nil
}
return constructValue(v.Elem())
case reflect.Ptr:
if v.IsNil() {
return jen.Nil(), nil
}
s := jen.Op("&")
val, err := constructValue(reflect.Indirect(v))
if err != nil {
return nil, err
}
return s.Add(val), nil
case reflect.Map:
if v.IsNil() {
return jen.Nil(), nil
}
s := indirectType(v.Type())
keys := v.MapKeys()
values := make(jen.Dict, v.Len())
for _, k := range keys {
key, err := constructValue(k)
if err != nil {
return nil, err
}
val, err := constructValue(v.MapIndex(k))
if err != nil {
return nil, err
}
values[key] = val
}
s.Values(values)
return s, nil
case reflect.Struct:
switch v.Type().Name() {
case "DateTimeLiteral":
lit := v.Interface().(ast.DateTimeLiteral)
fmtTime := lit.Value.Format(time.RFC3339Nano)
return constructStructValue(v, map[string]*jen.Statement{
"Value": jen.Qual("github.com/influxdata/flux/internal/parser", "MustParseTime").Call(jen.Lit(fmtTime)),
})
case "RegexpLiteral":
lit := v.Interface().(ast.RegexpLiteral)
regexString := lit.Value.String()
return constructStructValue(v, map[string]*jen.Statement{
"Value": jen.Qual("regexp", "MustCompile").Call(jen.Lit(regexString)),
})
}
return constructStructValue(v, nil)
case reflect.Bool,
reflect.Int,
reflect.Int8,
reflect.Int16,
reflect.Int32,
reflect.Int64,
reflect.Uint,
reflect.Uint8,
reflect.Uint16,
reflect.Uint32,
reflect.Uint64,
reflect.Uintptr,
reflect.Float32,
reflect.Float64,
reflect.Complex64,
reflect.Complex128,
reflect.String:
typ := types[v.Kind()]
cv := v.Convert(typ)
return jen.Lit(cv.Interface()), nil
default:
return nil, fmt.Errorf("unsupport value kind %v", v.Kind())
}
}

func constructStructValue(v reflect.Value, replace map[string]*jen.Statement) (*jen.Statement, error) {
typ := v.Type()
s := indirectType(typ)
values := make(jen.Dict, v.NumField())
for i := 0; i < v.NumField(); i++ {
field := v.Field(i)
name := typ.Field(i).Name
if !field.CanInterface() {
// Ignore private fields
continue
}
if s, ok := replace[name]; ok {
values[jen.Id(name)] = s
continue
}
val, err := constructValue(field)
if err != nil {
return nil, err
}
values[jen.Id(name)] = val
}
return s.Values(values), nil
}

// types is map of reflect.Kind to reflect.Type for the primitive types
var types = map[reflect.Kind]reflect.Type{
reflect.Bool: reflect.TypeOf(false),
reflect.Int: reflect.TypeOf(int(0)),
reflect.Int8: reflect.TypeOf(int8(0)),
reflect.Int16: reflect.TypeOf(int16(0)),
reflect.Int32: reflect.TypeOf(int32(0)),
reflect.Int64: reflect.TypeOf(int64(0)),
reflect.Uint: reflect.TypeOf(uint(0)),
reflect.Uint8: reflect.TypeOf(uint8(0)),
reflect.Uint16: reflect.TypeOf(uint16(0)),
reflect.Uint32: reflect.TypeOf(uint32(0)),
reflect.Uint64: reflect.TypeOf(uint64(0)),
reflect.Uintptr: reflect.TypeOf(uintptr(0)),
reflect.Float32: reflect.TypeOf(float32(0)),
reflect.Float64: reflect.TypeOf(float64(0)),
reflect.Complex64: reflect.TypeOf(complex64(0)),
reflect.Complex128: reflect.TypeOf(complex128(0)),
reflect.String: reflect.TypeOf(""),
}
Loading

0 comments on commit 2af280a

Please sign in to comment.