Add comment to interface method (#28)
This commit is contained in:
parent
440b92a742
commit
0a1d5c8545
12 changed files with 124 additions and 190 deletions
internal
|
@ -19,29 +19,27 @@ func ExtractComponents(f *ast.File) File {
|
|||
}
|
||||
|
||||
for _, spec := range genDecl.Specs {
|
||||
importSpec, ok := spec.(*ast.ImportSpec)
|
||||
if ok {
|
||||
switch spec := spec.(type) {
|
||||
case *ast.ImportSpec:
|
||||
var imp Import
|
||||
if importSpec.Name != nil {
|
||||
imp.Name = importSpec.Name.Name
|
||||
if spec.Name != nil {
|
||||
imp.Name = spec.Name.Name
|
||||
}
|
||||
importPath, err := strconv.Unquote(importSpec.Path.Value)
|
||||
importPath, err := strconv.Unquote(spec.Path.Value)
|
||||
if err != nil {
|
||||
fmt.Printf("cannot unquote import %s : %s \n", importSpec.Path.Value, err)
|
||||
fmt.Printf("cannot unquote import %s : %s \n", spec.Path.Value, err)
|
||||
continue
|
||||
}
|
||||
imp.Path = importPath
|
||||
|
||||
file.Imports = append(file.Imports, imp)
|
||||
}
|
||||
|
||||
typeSpec, ok := spec.(*ast.TypeSpec)
|
||||
if ok {
|
||||
switch t := typeSpec.Type.(type) {
|
||||
case *ast.TypeSpec:
|
||||
switch t := spec.Type.(type) {
|
||||
case *ast.StructType:
|
||||
file.Structs = append(file.Structs, extractStructType(typeSpec.Name.Name, t))
|
||||
file.Structs = append(file.Structs, extractStructType(spec.Name.Name, t))
|
||||
case *ast.InterfaceType:
|
||||
file.Interfaces = append(file.Interfaces, extractInterfaceType(typeSpec.Name.Name, t))
|
||||
file.Interfaces = append(file.Interfaces, extractInterfaceType(spec.Name.Name, t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +86,16 @@ func extractInterfaceType(name string, interfaceType *ast.InterfaceType) Interfa
|
|||
break
|
||||
}
|
||||
|
||||
meth := extractFunction(name, funcType)
|
||||
var comments []string
|
||||
if method.Doc != nil {
|
||||
for _, comment := range method.Doc.List {
|
||||
commentRunes := []rune(comment.Text)
|
||||
commentText := strings.TrimSpace(string(commentRunes[2:]))
|
||||
comments = append(comments, commentText)
|
||||
}
|
||||
}
|
||||
|
||||
meth := extractFunction(name, comments, funcType)
|
||||
|
||||
intf.Methods = append(intf.Methods, meth)
|
||||
}
|
||||
|
@ -118,9 +125,10 @@ func extractStructTag(tagValue string) map[string][]string {
|
|||
return tags
|
||||
}
|
||||
|
||||
func extractFunction(name string, funcType *ast.FuncType) Method {
|
||||
func extractFunction(name string, comments []string, funcType *ast.FuncType) Method {
|
||||
meth := Method{
|
||||
Name: name,
|
||||
Name: name,
|
||||
Comments: comments,
|
||||
}
|
||||
for _, param := range funcType.Params.List {
|
||||
paramType := getType(param.Type)
|
||||
|
@ -173,25 +181,7 @@ func getType(expr ast.Expr) Type {
|
|||
return MapType{KeyType: keyType, ValueType: valueType}
|
||||
|
||||
case *ast.InterfaceType:
|
||||
var methods []Method
|
||||
for _, method := range expr.Methods.List {
|
||||
funcType, ok := method.Type.(*ast.FuncType)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
var name string
|
||||
for _, n := range method.Names {
|
||||
name = n.Name
|
||||
break
|
||||
}
|
||||
|
||||
methods = append(methods, extractFunction(name, funcType))
|
||||
}
|
||||
|
||||
return InterfaceType{
|
||||
Methods: methods,
|
||||
}
|
||||
return extractInterfaceType("", expr)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -65,10 +65,10 @@ type UserModel struct {
|
|||
ExpectedOutput: code.File{
|
||||
PackageName: "user",
|
||||
Structs: code.Structs{
|
||||
{
|
||||
code.Struct{
|
||||
Name: "UserModel",
|
||||
Fields: code.StructFields{
|
||||
{
|
||||
code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{
|
||||
|
@ -76,7 +76,7 @@ type UserModel struct {
|
|||
"json": {"id"},
|
||||
},
|
||||
},
|
||||
{
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.SimpleType("string"),
|
||||
Tags: map[string][]string{
|
||||
|
@ -99,6 +99,7 @@ type UserRepository interface {
|
|||
FindByAgeBetween(ctx context.Context, fromAge, toAge int) ([]*UserModel, error)
|
||||
InsertOne(ctx context.Context, user *UserModel) (interface{}, error)
|
||||
UpdateAgreementByID(ctx context.Context, agreement map[string]bool, id primitive.ObjectID) (bool, error)
|
||||
// CustomMethod does custom things.
|
||||
CustomMethod(interface {
|
||||
Run(arg1 int)
|
||||
}) interface {
|
||||
|
@ -108,7 +109,7 @@ type UserRepository interface {
|
|||
ExpectedOutput: code.File{
|
||||
PackageName: "user",
|
||||
Interfaces: code.Interfaces{
|
||||
{
|
||||
code.InterfaceType{
|
||||
Name: "UserRepository",
|
||||
Methods: []code.Method{
|
||||
{
|
||||
|
@ -168,7 +169,8 @@ type UserRepository interface {
|
|||
},
|
||||
},
|
||||
{
|
||||
Name: "CustomMethod",
|
||||
Name: "CustomMethod",
|
||||
Comments: []string{"CustomMethod does custom things."},
|
||||
Params: []code.Param{
|
||||
{
|
||||
Type: code.InterfaceType{
|
||||
|
@ -228,10 +230,10 @@ type UserRepository interface {
|
|||
{Path: "go.mongodb.org/mongo-driver/bson/primitive"},
|
||||
},
|
||||
Structs: code.Structs{
|
||||
{
|
||||
code.Struct{
|
||||
Name: "UserModel",
|
||||
Fields: code.StructFields{
|
||||
{
|
||||
code.StructField{
|
||||
Name: "ID",
|
||||
Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"},
|
||||
Tags: map[string][]string{
|
||||
|
@ -239,7 +241,7 @@ type UserRepository interface {
|
|||
"json": {"id"},
|
||||
},
|
||||
},
|
||||
{
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.SimpleType("string"),
|
||||
Tags: map[string][]string{
|
||||
|
@ -251,7 +253,7 @@ type UserRepository interface {
|
|||
},
|
||||
},
|
||||
Interfaces: code.Interfaces{
|
||||
{
|
||||
code.InterfaceType{
|
||||
Name: "UserRepository",
|
||||
Methods: []code.Method{
|
||||
{
|
||||
|
|
|
@ -95,9 +95,10 @@ func (intf InterfaceType) IsNumber() bool {
|
|||
|
||||
// Method is a definition of the method inside the interface
|
||||
type Method struct {
|
||||
Name string
|
||||
Params []Param
|
||||
Returns []Type
|
||||
Name string
|
||||
Comments []string
|
||||
Params []Param
|
||||
Returns []Type
|
||||
}
|
||||
|
||||
// Param is a model of method parameter
|
||||
|
|
|
@ -11,8 +11,8 @@ func TestStructsByName(t *testing.T) {
|
|||
userStruct := code.Struct{
|
||||
Name: "UserModel",
|
||||
Fields: code.StructFields{
|
||||
{Name: "ID", Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}},
|
||||
{Name: "Username", Type: code.SimpleType("string")},
|
||||
code.StructField{Name: "ID", Type: code.ExternalType{PackageAlias: "primitive", Name: "ObjectID"}},
|
||||
code.StructField{Name: "Username", Type: code.SimpleType("string")},
|
||||
},
|
||||
}
|
||||
structs := code.Structs{userStruct}
|
||||
|
|
|
@ -32,7 +32,7 @@ func TestGenerateMongoRepository(t *testing.T) {
|
|||
Name: "UserModel",
|
||||
Fields: code.StructFields{
|
||||
idField,
|
||||
{
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.SimpleType("string"),
|
||||
Tags: map[string][]string{"bson": {"username"}},
|
||||
|
|
|
@ -57,7 +57,7 @@ var userModel = code.Struct{
|
|||
Name: "UserModel",
|
||||
Fields: code.StructFields{
|
||||
idField,
|
||||
{
|
||||
code.StructField{
|
||||
Name: "Username",
|
||||
Type: code.SimpleType("string"),
|
||||
Tags: map[string][]string{"bson": {"username"}},
|
||||
|
@ -989,7 +989,7 @@ func (r *UserRepositoryMongo) UpdateByID(arg0 context.Context, arg1 *UserModel,
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -1030,7 +1030,7 @@ func (r *UserRepositoryMongo) UpdateAgeByID(arg0 context.Context, arg1 int, arg2
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -1071,7 +1071,7 @@ func (r *UserRepositoryMongo) UpdateAgeByGender(arg0 context.Context, arg1 int,
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -1112,7 +1112,7 @@ func (r *UserRepositoryMongo) UpdateConsentHistoryPushByID(arg0 context.Context,
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -1154,8 +1154,8 @@ func (r *UserRepositoryMongo) UpdateAgeIncByID(arg0 context.Context, arg1 int, a
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -1199,7 +1199,7 @@ func (r *UserRepositoryMongo) UpdateEnabledAndConsentHistoryPushByID(arg0 contex
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -2081,7 +2081,7 @@ func TestGenerateMethod_Invalid(t *testing.T) {
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{accessTokenField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{accessTokenField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
@ -2133,7 +2133,7 @@ func TestGenerateMethod_Invalid(t *testing.T) {
|
|||
},
|
||||
Operation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: "APPEND"},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: "APPEND"},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{
|
||||
|
|
|
@ -60,10 +60,12 @@ func TestError(t *testing.T) {
|
|||
},
|
||||
{
|
||||
Name: "IncompatibleUpdateOperatorError",
|
||||
Error: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorInc, spec.FieldReference{{
|
||||
Name: "City",
|
||||
Type: code.SimpleType("string"),
|
||||
}}),
|
||||
Error: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorInc, spec.FieldReference{
|
||||
code.StructField{
|
||||
Name: "City",
|
||||
Type: code.SimpleType("string"),
|
||||
},
|
||||
}),
|
||||
ExpectedString: "cannot use update operator INC with struct field 'City' of type 'string'",
|
||||
},
|
||||
}
|
||||
|
|
|
@ -705,7 +705,7 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -729,7 +729,7 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -753,7 +753,7 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{nameField, firstNameField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -778,8 +778,8 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
{FieldReference: spec.FieldReference{cityField}, ParamIndex: 2, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{genderField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{cityField}, ParamIndex: 2, Operator: spec.UpdateOperatorSet},
|
||||
},
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -803,7 +803,7 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 1, Operator: spec.UpdateOperatorPush},
|
||||
},
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -827,7 +827,7 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{ageField}, ParamIndex: 1, Operator: spec.UpdateOperatorInc},
|
||||
},
|
||||
Mode: spec.QueryModeOne,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -852,8 +852,8 @@ func TestParseInterfaceMethod_Update(t *testing.T) {
|
|||
},
|
||||
ExpectedOperation: spec.UpdateOperation{
|
||||
Update: spec.UpdateFields{
|
||||
{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{enabledField}, ParamIndex: 1, Operator: spec.UpdateOperatorSet},
|
||||
spec.UpdateField{FieldReference: spec.FieldReference{consentHistoryField}, ParamIndex: 2, Operator: spec.UpdateOperatorPush},
|
||||
},
|
||||
Mode: spec.QueryModeMany,
|
||||
Query: spec.QuerySpec{Predicates: []spec.Predicate{
|
||||
|
@ -1741,10 +1741,12 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
|
|||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorPush, spec.FieldReference{{
|
||||
Name: "Gender",
|
||||
Type: code.SimpleType("Gender"),
|
||||
}}),
|
||||
ExpectedError: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorPush, spec.FieldReference{
|
||||
code.StructField{
|
||||
Name: "Gender",
|
||||
Type: code.SimpleType("Gender"),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: "inc operator in non-number field",
|
||||
|
@ -1760,10 +1762,12 @@ func TestParseInterfaceMethod_Update_Invalid(t *testing.T) {
|
|||
code.SimpleType("error"),
|
||||
},
|
||||
},
|
||||
ExpectedError: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorInc, spec.FieldReference{{
|
||||
Name: "City",
|
||||
Type: code.SimpleType("string"),
|
||||
}}),
|
||||
ExpectedError: spec.NewIncompatibleUpdateOperatorError(spec.UpdateOperatorInc, spec.FieldReference{
|
||||
code.StructField{
|
||||
Name: "City",
|
||||
Type: code.SimpleType("string"),
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
Name: "update method without query",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue