From c57cde593630fd5a93970282e7147a47874d8238 Mon Sep 17 00:00:00 2001 From: rafal-slominskii Date: Thu, 26 Jan 2023 17:27:13 +0100 Subject: [PATCH 1/4] fix simple aliased types --- compiler/example/datamodel/config/config.go | 7 +++++++ compiler/pkg/generator/template_renderers.go | 2 +- compiler/pkg/generator/types_generator.go | 16 +++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/compiler/example/datamodel/config/config.go b/compiler/example/datamodel/config/config.go index 12943e4b9..e2d6a2cae 100644 --- a/compiler/example/datamodel/config/config.go +++ b/compiler/example/datamodel/config/config.go @@ -109,7 +109,14 @@ type TestValMarkers struct { type SomeStruct struct{} +type AliasedField gns.MyStr +type AliasedFieldMap map[string]gns.MyStr +type AliasedFieldList []gns.MyStr + type StructWithEmbeddedField struct { SomeStruct gns.MyStr + ExplicitField gns.MyStr + AliasedFieldMap AliasedFieldMap + AliasedFieldList AliasedFieldList } diff --git a/compiler/pkg/generator/template_renderers.go b/compiler/pkg/generator/template_renderers.go index 3ffdc471e..8e1207e79 100644 --- a/compiler/pkg/generator/template_renderers.go +++ b/compiler/pkg/generator/template_renderers.go @@ -313,7 +313,7 @@ func RenderTypesTemplate(crdModulePath string, pkg parser.Package) (*bytes.Buffe vars.Imports = parsePackageImports(pkg, aliasNameMap) vars.CRDTypes = parsePackageCRDs(pkg, aliasNameMap) vars.Structs = parsePackageStructs(pkg, aliasNameMap) - vars.Types = parsePackageTypes(pkg) + vars.Types = parsePackageTypes(pkg, aliasNameMap) vars.Consts = parsePackageConsts(pkg) vars.CommonImport = util.GetInternalImport(crdModulePath, "common") diff --git a/compiler/pkg/generator/types_generator.go b/compiler/pkg/generator/types_generator.go index 6f1158745..7607a00e2 100644 --- a/compiler/pkg/generator/types_generator.go +++ b/compiler/pkg/generator/types_generator.go @@ -297,19 +297,33 @@ type {{.Name}} struct { return b.String() } -func parsePackageTypes(pkg parser.Package) string { +func parsePackageTypes(pkg parser.Package, aliasNameMap map[string]string) string { var output string for _, node := range pkg.GetTypes() { t, err := pkg.GenDeclToString(&node) if err != nil { log.Fatalf("failed to translate type gen decl to string: %v", err) } + t = constructPackageType(t, aliasNameMap) output += t + "\n" } return output } +func constructPackageType(t string, aliasNameMap map[string]string) string { + lastInd := strings.LastIndex(t, " ") + name := t[:lastInd] + typee := t[lastInd+1:] + parts := strings.Split(typee, ".") + + if len(parts) > 1 { + parts = ConstructTypeParts(aliasNameMap, parts) + t = fmt.Sprintf("%s %s.%s", name, parts[0], parts[1]) + } + return t +} + func parsePackageConsts(pkg parser.Package) string { var c struct { Consts string From 69d4020dfdf51eb9b9003064d44fd9c0c199673e Mon Sep 17 00:00:00 2001 From: rafal-slominskii Date: Fri, 27 Jan 2023 09:29:04 +0100 Subject: [PATCH 2/4] use existing logic in ConstructType create wrapper --- compiler/example/datamodel/config/config.go | 1 + compiler/pkg/generator/resolver_generator.go | 4 +- compiler/pkg/generator/types_generator.go | 41 ++++++++++---------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/compiler/example/datamodel/config/config.go b/compiler/example/datamodel/config/config.go index e2d6a2cae..834e45110 100644 --- a/compiler/example/datamodel/config/config.go +++ b/compiler/example/datamodel/config/config.go @@ -117,6 +117,7 @@ type StructWithEmbeddedField struct { SomeStruct gns.MyStr ExplicitField gns.MyStr + AliasedField AliasedField AliasedFieldMap AliasedFieldMap AliasedFieldList AliasedFieldList } diff --git a/compiler/pkg/generator/resolver_generator.go b/compiler/pkg/generator/resolver_generator.go index fa0824c6e..e79af7fb3 100644 --- a/compiler/pkg/generator/resolver_generator.go +++ b/compiler/pkg/generator/resolver_generator.go @@ -279,7 +279,7 @@ func processNonNexusFields(aliasNameMap map[string]string, node *ast.TypeSpec, fieldProp FieldProperty err error ) - typeString := ConstructType(aliasNameMap, f) + typeString := ConstructTypeWrapper(aliasNameMap, f) // populate each field properties if len(f.Names) > 0 { fieldProp.FieldName, err = parser.GetNodeFieldName(f) @@ -424,7 +424,7 @@ func processNexusFields(pkg parser.Package, aliasNameMap map[string]string, node } // nexus link field - typeString := ConstructType(aliasNameMap, nf) + typeString := ConstructTypeWrapper(aliasNameMap, nf) if parser.IsOnlyLinkField(nf) { schemaTypeName, resolverTypeName := ValidateImportPkg(nodeProp.PkgName, typeString, importMap, pkgs) // `type:string` annotation used to consider the type as string `nexus-graphql:"type:string"` diff --git a/compiler/pkg/generator/types_generator.go b/compiler/pkg/generator/types_generator.go index 7607a00e2..3475b19cd 100644 --- a/compiler/pkg/generator/types_generator.go +++ b/compiler/pkg/generator/types_generator.go @@ -169,7 +169,7 @@ type {{.Name}}Spec struct { } } specDef.Fields += "\t" + name + " " - typeString := ConstructType(aliasNameMap, field) + typeString := ConstructTypeWrapper(aliasNameMap, field) specDef.Fields += typeString specDef.Fields += " " + getTag(field, name, false) + "\n" } @@ -272,7 +272,7 @@ type {{.Name}} struct { } } specDef.Fields += "\t" + name + " " - typeString := ConstructType(aliasNameMap, field) + typeString := ConstructTypeWrapper(aliasNameMap, field) currentTags := parser.GetFieldTags(field) currentTags = parser.FillEmptyTag(currentTags, name, "json") @@ -304,24 +304,19 @@ func parsePackageTypes(pkg parser.Package, aliasNameMap map[string]string) strin if err != nil { log.Fatalf("failed to translate type gen decl to string: %v", err) } - t = constructPackageType(t, aliasNameMap) - output += t + "\n" - } + isMap := strings.Contains(t, "map[") + isArray := strings.Contains(t, "[]") - return output -} + lastSpace := strings.LastIndex(t, " ") + name := t[:lastSpace] + typeT := t[lastSpace+1:] -func constructPackageType(t string, aliasNameMap map[string]string) string { - lastInd := strings.LastIndex(t, " ") - name := t[:lastInd] - typee := t[lastInd+1:] - parts := strings.Split(typee, ".") + t = fmt.Sprintf("%s %s", name, ConstructType(aliasNameMap, typeT, isMap, isArray)) - if len(parts) > 1 { - parts = ConstructTypeParts(aliasNameMap, parts) - t = fmt.Sprintf("%s %s.%s", name, parts[0], parts[1]) + output += t + "\n" } - return t + + return output } func parsePackageConsts(pkg parser.Package) string { @@ -421,14 +416,20 @@ func constructImports(inputAlias, inputImportPath string) (string, string) { return aliasName, importPath } +func ConstructTypeWrapper(aliasNameMap map[string]string, field *ast.Field) string { + typeString := types.ExprString(field.Type) + isArray := parser.IsArrayField(field) + isMap := parser.IsMapField(field) + return ConstructType(aliasNameMap, typeString, isMap, isArray) +} + // TODO: https://jira.eng.vmware.com/browse/NPT-296 // Support cross-package imports for the following additional types: // 1. map[gns.MyStr][]gns.MyStr // 2. map[string]map[string]gns.MyStr // 3. []map[string]gns.MyStr // 4. **gns.MyStr -func ConstructType(aliasNameMap map[string]string, field *ast.Field) string { - typeString := types.ExprString(field.Type) +func ConstructType(aliasNameMap map[string]string, typeString string, isMap, isArray bool) string { // Check if the field is imported from a different package. if !strings.Contains(typeString, ".") { @@ -436,7 +437,7 @@ func ConstructType(aliasNameMap map[string]string, field *ast.Field) string { } switch { - case parser.IsMapField(field): + case isMap: // TODO: Check if the function GetFieldType(field) can be reused for cases other than: // map[string]gns.MyStr // https://jira.eng.vmware.com/browse/NPT-296 @@ -452,7 +453,7 @@ func ConstructType(aliasNameMap map[string]string, field *ast.Field) string { types = append(types, val) } typeString = fmt.Sprintf("map[%s]%s", types[0], types[1]) - case parser.IsArrayField(field): + case isArray: arr := regexp.MustCompile(`^(\[])`).ReplaceAllString(typeString, "") parts := strings.Split(arr, ".") if len(parts) > 1 { From fd7ff755449bf4ee56bfe49aa02cfb758e84d2a3 Mon Sep 17 00:00:00 2001 From: rafal-slominskii Date: Fri, 27 Jan 2023 10:01:32 +0100 Subject: [PATCH 3/4] add generated files --- .../config.tsm.tanzu.vmware.com/v1/types.go | 7 +++ .../v1/zz_generated.deepcopy.go | 54 +++++++++++++++++++ compiler/pkg/generator/types_generator.go | 5 +- compiler/pkg/parser/pkg.go | 28 ++++++++++ 4 files changed, 92 insertions(+), 2 deletions(-) diff --git a/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/types.go b/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/types.go index 48f7f832a..c98899b38 100644 --- a/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/types.go +++ b/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/types.go @@ -227,9 +227,16 @@ type SomeStruct struct { type StructWithEmbeddedField struct { SomeStruct gnstsmtanzuvmwarecomv1.MyStr + ExplicitField gnstsmtanzuvmwarecomv1.MyStr `json:"explicitField" yaml:"explicitField"` + AliasedField AliasedField `json:"aliasedField" yaml:"aliasedField"` + AliasedFieldMap AliasedFieldMap `json:"aliasedFieldMap" yaml:"aliasedFieldMap"` + AliasedFieldList AliasedFieldList `json:"aliasedFieldList" yaml:"aliasedFieldList"` } type AMap map[string]string type BArray []string type CInt uint8 type DFloat float32 +type AliasedField gnstsmtanzuvmwarecomv1.MyStr +type AliasedFieldMap map[string]gnstsmtanzuvmwarecomv1.MyStr +type AliasedFieldList []gnstsmtanzuvmwarecomv1.MyStr diff --git a/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/zz_generated.deepcopy.go b/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/zz_generated.deepcopy.go index 3c9297dd9..c8f36d769 100644 --- a/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/zz_generated.deepcopy.go +++ b/compiler/example/output/generated/apis/config.tsm.tanzu.vmware.com/v1/zz_generated.deepcopy.go @@ -49,6 +49,48 @@ func (in AMap) DeepCopy() AMap { return *out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in AliasedFieldList) DeepCopyInto(out *AliasedFieldList) { + { + in := &in + *out = make(AliasedFieldList, len(*in)) + copy(*out, *in) + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasedFieldList. +func (in AliasedFieldList) DeepCopy() AliasedFieldList { + if in == nil { + return nil + } + out := new(AliasedFieldList) + in.DeepCopyInto(out) + return *out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in AliasedFieldMap) DeepCopyInto(out *AliasedFieldMap) { + { + in := &in + *out = make(AliasedFieldMap, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + return + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AliasedFieldMap. +func (in AliasedFieldMap) DeepCopy() AliasedFieldMap { + if in == nil { + return nil + } + out := new(AliasedFieldMap) + in.DeepCopyInto(out) + return *out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in BArray) DeepCopyInto(out *BArray) { { @@ -665,6 +707,18 @@ func (in *SomeStruct) DeepCopy() *SomeStruct { func (in *StructWithEmbeddedField) DeepCopyInto(out *StructWithEmbeddedField) { *out = *in out.SomeStruct = in.SomeStruct + if in.AliasedFieldMap != nil { + in, out := &in.AliasedFieldMap, &out.AliasedFieldMap + *out = make(AliasedFieldMap, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.AliasedFieldList != nil { + in, out := &in.AliasedFieldList, &out.AliasedFieldList + *out = make(AliasedFieldList, len(*in)) + copy(*out, *in) + } return } diff --git a/compiler/pkg/generator/types_generator.go b/compiler/pkg/generator/types_generator.go index 3475b19cd..dacc35be7 100644 --- a/compiler/pkg/generator/types_generator.go +++ b/compiler/pkg/generator/types_generator.go @@ -304,8 +304,9 @@ func parsePackageTypes(pkg parser.Package, aliasNameMap map[string]string) strin if err != nil { log.Fatalf("failed to translate type gen decl to string: %v", err) } - isMap := strings.Contains(t, "map[") - isArray := strings.Contains(t, "[]") + + isMap := parser.IsDeclMapField(&node) + isArray := parser.IsDeclArrayField(&node) lastSpace := strings.LastIndex(t, " ") name := t[:lastSpace] diff --git a/compiler/pkg/parser/pkg.go b/compiler/pkg/parser/pkg.go index fec0edc3b..95b969a6b 100644 --- a/compiler/pkg/parser/pkg.go +++ b/compiler/pkg/parser/pkg.go @@ -517,6 +517,34 @@ func IsArrayField(f *ast.Field) bool { return false } +func IsDeclArrayField(f *ast.GenDecl) bool { + if f == nil { + return false + } + ts, ok := f.Specs[0].(*ast.TypeSpec) + if !ok { + return false + } + if _, ok = ts.Type.(*ast.ArrayType); ok { + return true + } + return false +} + +func IsDeclMapField(f *ast.GenDecl) bool { + if f == nil { + return false + } + ts, ok := f.Specs[0].(*ast.TypeSpec) + if !ok { + return false + } + if _, ok = ts.Type.(*ast.MapType); ok { + return true + } + return false +} + func IsAggregateKind(f *ast.Field) bool { return IsArrayField(f) || IsMapField(f) } From 9d3dc3c9d3f48ca314133bcd0a539ce4c1a7ebcc Mon Sep 17 00:00:00 2001 From: rafal-slominskii Date: Fri, 10 Feb 2023 23:35:03 +0100 Subject: [PATCH 4/4] add rendered templates --- .../apis/config.tsm.tanzu.vmware.com/v1/types.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/example/output/_rendered_templates/apis/config.tsm.tanzu.vmware.com/v1/types.go b/compiler/example/output/_rendered_templates/apis/config.tsm.tanzu.vmware.com/v1/types.go index a5760cb96..a225a7f4d 100644 --- a/compiler/example/output/_rendered_templates/apis/config.tsm.tanzu.vmware.com/v1/types.go +++ b/compiler/example/output/_rendered_templates/apis/config.tsm.tanzu.vmware.com/v1/types.go @@ -227,9 +227,16 @@ type SomeStruct struct { type StructWithEmbeddedField struct { SomeStruct gnstsmtanzuvmwarecomv1.MyStr + ExplicitField gnstsmtanzuvmwarecomv1.MyStr `json:"explicitField" yaml:"explicitField"` + AliasedField AliasedField `json:"aliasedField" yaml:"aliasedField"` + AliasedFieldMap AliasedFieldMap `json:"aliasedFieldMap" yaml:"aliasedFieldMap"` + AliasedFieldList AliasedFieldList `json:"aliasedFieldList" yaml:"aliasedFieldList"` } type AMap map[string]string type BArray []string type CInt uint8 type DFloat float32 +type AliasedField gnstsmtanzuvmwarecomv1.MyStr +type AliasedFieldMap map[string]gnstsmtanzuvmwarecomv1.MyStr +type AliasedFieldList []gnstsmtanzuvmwarecomv1.MyStr