From d8e476a434e3729141fcbcf2965f1df17bd8f53c Mon Sep 17 00:00:00 2001 From: sunboyy Date: Thu, 11 Feb 2021 22:17:21 +0700 Subject: [PATCH] Refactor code extractor --- README.md | 3 + codecov.yml | 2 +- go.sum | 2 + internal/code/extractor.go | 133 ++++++++++++++++++------------------- 4 files changed, 71 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index 027a317..51c6728 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ + + + Repogen is a code generator for database repository in Golang inspired by Spring Data JPA. (WIP) diff --git a/codecov.yml b/codecov.yml index 4b6e28e..4c5b5bb 100644 --- a/codecov.yml +++ b/codecov.yml @@ -6,4 +6,4 @@ coverage: threshold: 4% patch: default: - target: 60% + target: 75% diff --git a/go.sum b/go.sum index 0fd29d4..be08c7e 100644 --- a/go.sum +++ b/go.sum @@ -95,6 +95,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= @@ -129,6 +130,7 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c h1:VwygUrnw9jn88c4u8GD3rZQbq golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= diff --git a/internal/code/extractor.go b/internal/code/extractor.go index 8ddc438..cf52c74 100644 --- a/internal/code/extractor.go +++ b/internal/code/extractor.go @@ -37,53 +37,11 @@ func ExtractComponents(f *ast.File) File { typeSpec, ok := spec.(*ast.TypeSpec) if ok { - structType, ok := typeSpec.Type.(*ast.StructType) - if ok { - str := Struct{ - Name: typeSpec.Name.Name, - } - - for _, field := range structType.Fields.List { - var strField StructField - for _, name := range field.Names { - strField.Name = name.Name - break - } - strField.Type = getType(field.Type) - if field.Tag != nil { - strField.Tags = extractStructTag(field.Tag.Value) - } - - str.Fields = append(str.Fields, strField) - } - - file.Structs = append(file.Structs, str) - } - - interfaceType, ok := typeSpec.Type.(*ast.InterfaceType) - if ok { - intf := InterfaceType{ - Name: typeSpec.Name.Name, - } - - for _, method := range interfaceType.Methods.List { - funcType, ok := method.Type.(*ast.FuncType) - if !ok { - continue - } - - var name string - for _, n := range method.Names { - name = n.Name - break - } - - meth := extractFunction(name, funcType) - - intf.Methods = append(intf.Methods, meth) - } - - file.Interfaces = append(file.Interfaces, intf) + switch t := typeSpec.Type.(type) { + case *ast.StructType: + file.Structs = append(file.Structs, extractStructType(typeSpec.Name.Name, t)) + case *ast.InterfaceType: + file.Interfaces = append(file.Interfaces, extractInterfaceType(typeSpec.Name.Name, t)) } } } @@ -91,6 +49,53 @@ func ExtractComponents(f *ast.File) File { return file } +func extractStructType(name string, structType *ast.StructType) Struct { + str := Struct{ + Name: name, + } + + for _, field := range structType.Fields.List { + var strField StructField + for _, name := range field.Names { + strField.Name = name.Name + break + } + strField.Type = getType(field.Type) + if field.Tag != nil { + strField.Tags = extractStructTag(field.Tag.Value) + } + + str.Fields = append(str.Fields, strField) + } + + return str +} + +func extractInterfaceType(name string, interfaceType *ast.InterfaceType) InterfaceType { + intf := InterfaceType{ + Name: name, + } + + for _, method := range interfaceType.Methods.List { + funcType, ok := method.Type.(*ast.FuncType) + if !ok { + continue + } + + var name string + for _, n := range method.Names { + name = n.Name + break + } + + meth := extractFunction(name, funcType) + + intf.Methods = append(intf.Methods, meth) + } + + return intf +} + func extractStructTag(tagValue string) map[string][]string { tagTokens := strings.Fields(tagValue[1 : len(tagValue)-1]) @@ -143,36 +148,28 @@ func extractFunction(name string, funcType *ast.FuncType) Method { } func getType(expr ast.Expr) Type { - identExpr, ok := expr.(*ast.Ident) - if ok { - return SimpleType(identExpr.Name) - } + switch expr := expr.(type) { + case *ast.Ident: + return SimpleType(expr.Name) - selectorExpr, ok := expr.(*ast.SelectorExpr) - if ok { - xExpr, ok := selectorExpr.X.(*ast.Ident) + case *ast.SelectorExpr: + xExpr, ok := expr.X.(*ast.Ident) if !ok { - return ExternalType{Name: selectorExpr.Sel.Name} + return ExternalType{Name: expr.Sel.Name} } - return ExternalType{PackageAlias: xExpr.Name, Name: selectorExpr.Sel.Name} - } + return ExternalType{PackageAlias: xExpr.Name, Name: expr.Sel.Name} - starExpr, ok := expr.(*ast.StarExpr) - if ok { - containedType := getType(starExpr.X) + case *ast.StarExpr: + containedType := getType(expr.X) return PointerType{ContainedType: containedType} - } - arrayType, ok := expr.(*ast.ArrayType) - if ok { - containedType := getType(arrayType.Elt) + case *ast.ArrayType: + containedType := getType(expr.Elt) return ArrayType{containedType} - } - intfType, ok := expr.(*ast.InterfaceType) - if ok { + case *ast.InterfaceType: var methods []Method - for _, method := range intfType.Methods.List { + for _, method := range expr.Methods.List { funcType, ok := method.Type.(*ast.FuncType) if !ok { continue