-
-
Notifications
You must be signed in to change notification settings - Fork 8
Fix code generation to support pointer embedding of gorm.Model and include base fields #16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d19bb8b
920459e
a05330a
488a768
8c24a60
590632f
ae1324f
30c6e4f
09eff32
698ac24
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,145 @@ | ||
| # Binaries for programs and plugins | ||
| *.exe | ||
| *.exe~ | ||
| *.dll | ||
| *.so | ||
| *.dylib | ||
|
|
||
| # Test binary, built with `go test -c` | ||
| *.test | ||
|
|
||
| # Output of the go coverage tool, specifically when used with LiteIDE | ||
| *.out | ||
|
|
||
| # Dependency directories (remove the comment below to include it) | ||
| # vendor/ | ||
|
|
||
| # Go workspace file | ||
| go.work | ||
|
|
||
| # Build output | ||
| g | ||
| gorm | ||
| /bin/ | ||
| /build/ | ||
| /dist/ | ||
|
|
||
| # IDE and Editor files | ||
| .idea/ | ||
| .vscode/ | ||
| *.swp | ||
| *.swo | ||
| *~ | ||
|
|
||
| # OS generated files | ||
| .DS_Store | ||
| .DS_Store? | ||
| ._* | ||
| .Spotlight-V100 | ||
| .Trashes | ||
| ehthumbs.db | ||
| Thumbs.db | ||
|
|
||
| # Log files | ||
| *.log | ||
|
|
||
| # Runtime data | ||
| pids | ||
| *.pid | ||
| *.seed | ||
| *.pid.lock | ||
|
|
||
| # Coverage directory used by tools like istanbul | ||
| coverage/ | ||
|
|
||
| # nyc test coverage | ||
| .nyc_output | ||
|
|
||
| # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) | ||
| .grunt | ||
|
|
||
| # Bower dependency directory (https://bower.io/) | ||
| bower_components | ||
|
|
||
| # node_modules (if using Node.js tools) | ||
| node_modules/ | ||
|
|
||
| # Temporary folders | ||
| tmp/ | ||
| temp/ | ||
|
|
||
| # Go module download cache | ||
| $GOPATH/pkg/mod/ | ||
|
|
||
| # Go build cache | ||
| $GOCACHE/ | ||
|
|
||
| # Air live reload | ||
| tmp/ | ||
|
|
||
| # Local environment variables | ||
| .env | ||
| .env.local | ||
| .env.*.local | ||
|
|
||
| # Database files | ||
| *.db | ||
| *.sqlite | ||
| *.sqlite3 | ||
|
|
||
| # Compiled Object files, Static and Dynamic libs (Shared Objects) | ||
| *.o | ||
| *.a | ||
|
|
||
| # Folders | ||
| _obj | ||
| _test | ||
|
|
||
| # Architecture specific extensions/prefixes | ||
| *.[568vq] | ||
| [568vq].out | ||
|
|
||
| # cgo generated files | ||
| _cgo_gotypes.go | ||
| _cgo_export.* | ||
|
|
||
| # test generated files | ||
| *_test_gen.go | ||
|
|
||
| # Ignore generated documentation | ||
| *.html | ||
|
|
||
| # Ignore backup files | ||
| *.bak | ||
| *.backup | ||
| *.orig | ||
|
|
||
| # Ignore profiling files | ||
| *.prof | ||
| cpu.out | ||
| mem.out | ||
| profile.out | ||
|
|
||
| # Ignore security sensitive files | ||
| *.pem | ||
| *.key | ||
| *.crt | ||
| *.p12 | ||
|
|
||
| # Docker files (if not needed in repo) | ||
| # Dockerfile | ||
| # docker-compose.yml | ||
| # .dockerignore | ||
|
|
||
| # Kubernetes files (if not needed in repo) | ||
| # *.yaml | ||
| # *.yml | ||
|
|
||
| # Generated code (if applicable) | ||
| # *_gen.go | ||
| # *.pb.go | ||
|
|
||
| # Config files with sensitive data | ||
| config.json | ||
| secrets.yaml | ||
| secrets.yml | ||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -37,6 +37,7 @@ type ( | |
| applicableConfigs []*genconfig.Config | ||
| inputPath string | ||
| relPath string | ||
| goModDir string | ||
| Generator *Generator | ||
| } | ||
| Import struct { | ||
|
|
@@ -243,6 +244,7 @@ func (g *Generator) processFile(inputFile, inputRoot string) error { | |
| Package: f.Name.Name, | ||
| inputPath: inputFile, | ||
| relPath: relPath, | ||
| goModDir: findGoModDir(inputFile), | ||
| Generator: g, | ||
| } | ||
|
|
||
|
|
@@ -426,7 +428,7 @@ func (f Field) Type() string { | |
| return fmt.Sprintf("field.Number[%s]", goType) | ||
| } | ||
|
|
||
| if typ := loadNamedType(findGoModDir(f.file.inputPath), f.file.getFullImportPath(pkgName), typName); typ != nil { | ||
| if typ := loadNamedType(f.file.goModDir, f.file.getFullImportPath(pkgName), typName); typ != nil { | ||
| if ImplementsAllowedInterfaces(typ) { // For interface-implementing types, use generic Field | ||
| return fmt.Sprintf("field.Field[%s]", filepath.Base(goType)) | ||
| } | ||
|
|
@@ -730,33 +732,48 @@ func (p *File) getFullImportPath(shortName string) string { | |
|
|
||
| // handleAnonymousEmbedding processes anonymous embedded fields and returns true if handled | ||
| func (p *File) handleAnonymousEmbedding(field *ast.Field, pkgName string, s *Struct) bool { | ||
| switch t := field.Type.(type) { | ||
| // Helper function to add fields from embedded struct | ||
| addEmbeddedFields := func(structType *ast.StructType, typeName, embeddedPkgName string) bool { | ||
| sub := p.processStructType(&ast.TypeSpec{Name: &ast.Ident{Name: typeName}}, structType, embeddedPkgName) | ||
| s.Fields = append(s.Fields, sub.Fields...) | ||
| return true | ||
| } | ||
|
Comment on lines
+735
to
+740
|
||
|
|
||
| // Helper function to load and process external struct type | ||
| loadAndProcessExternalStruct := func(pkgName, typeName string) bool { | ||
| st, err := loadNamedStructType(p.goModDir, p.getFullImportPath(pkgName), typeName) | ||
| if err != nil || st == nil { | ||
| return false | ||
| } | ||
| return addEmbeddedFields(st, typeName, pkgName) | ||
| } | ||
|
Comment on lines
+742
to
+749
|
||
|
|
||
| // Unwrap pointer types to get the underlying type | ||
| fieldType := field.Type | ||
| if starExpr, ok := fieldType.(*ast.StarExpr); ok { | ||
| fieldType = starExpr.X | ||
| } | ||
|
|
||
| switch t := fieldType.(type) { | ||
| case *ast.Ident: | ||
| // Local type embedding | ||
| // Local type embedding (e.g., BaseStruct or *BaseStruct) | ||
| if t.Obj != nil { | ||
| if ts, ok := t.Obj.Decl.(*ast.TypeSpec); ok { | ||
| if st, ok := ts.Type.(*ast.StructType); ok { | ||
| sub := p.processStructType(ts, st, pkgName) | ||
| s.Fields = append(s.Fields, sub.Fields...) | ||
| return true | ||
| return addEmbeddedFields(st, t.Name, pkgName) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| case *ast.SelectorExpr: | ||
| // External package type embedding | ||
| // External package type embedding (e.g., pkg.BaseStruct or *pkg.BaseStruct) | ||
| if pkgIdent, ok := t.X.(*ast.Ident); ok { | ||
| st, err := loadNamedStructType(findGoModDir(p.inputPath), p.getFullImportPath(pkgIdent.Name), t.Sel.Name) | ||
| if err == nil && st != nil { | ||
| sub := p.processStructType(&ast.TypeSpec{Name: &ast.Ident{Name: t.Sel.Name}}, st, pkgIdent.Name) | ||
| s.Fields = append(s.Fields, sub.Fields...) | ||
| return true | ||
| } | ||
| return loadAndProcessExternalStruct(pkgIdent.Name, t.Sel.Name) | ||
| } | ||
|
|
||
| case *ast.StructType: | ||
| // Anonymous inline struct embedding | ||
| sub := p.processStructType(&ast.TypeSpec{Name: &ast.Ident{Name: "AnonymousStruct"}}, t, pkgName) | ||
| s.Fields = append(s.Fields, sub.Fields...) | ||
| return true | ||
| // Anonymous inline struct embedding (e.g., struct{...}) | ||
| return addEmbeddedFields(t, "AnonymousStruct", pkgName) | ||
| } | ||
|
|
||
| return false | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[NitPick]
Duplicate
tmp/entry on lines 68 and 78. The Air live reload entry is redundant since temporary folders are already ignored above.Context for Agents