Skip to content

Commit

Permalink
support generate var-declared function doc
Browse files Browse the repository at this point in the history
Signed-off-by: book987 <[email protected]>
  • Loading branch information
book987 committed Aug 24, 2023
1 parent 8ebf32f commit 55741e1
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 8 deletions.
37 changes: 31 additions & 6 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -975,19 +975,44 @@ func matchExtension(extensionToMatch string, comments []*ast.Comment) (match boo
return true
}

func getFuncDoc(decl any) (*ast.CommentGroup, bool) {
switch astDecl := decl.(type) {
case *ast.FuncDecl: // func name() {}
return astDecl.Doc, true
case *ast.GenDecl: // var name = namePointToFuncDirectlyOrIndirectly
if astDecl.Tok != token.VAR {
return nil, false
}
varSpec, ok := astDecl.Specs[0].(*ast.ValueSpec)
if !ok || len(varSpec.Values) != 1 {
return nil, false
}
_, ok = getFuncDoc(varSpec)
return astDecl.Doc, ok
case *ast.ValueSpec:
value, ok := astDecl.Values[0].(*ast.Ident)
if !ok || value == nil {
return nil, false
}
_, ok = getFuncDoc(value.Obj.Decl)
return astDecl.Doc, ok
}
return nil, false
}

// ParseRouterAPIInfo parses router api info for given astFile.
func (parser *Parser) ParseRouterAPIInfo(fileInfo *AstFileInfo) error {
for _, astDescription := range fileInfo.File.Decls {
for _, decl := range fileInfo.File.Decls {
if (fileInfo.ParseFlag & ParseOperations) == ParseNone {
continue
}
astDeclaration, ok := astDescription.(*ast.FuncDecl)
if ok && astDeclaration.Doc != nil && astDeclaration.Doc.List != nil {
if parser.matchTags(astDeclaration.Doc.List) &&
matchExtension(parser.parseExtension, astDeclaration.Doc.List) {
funcDoc, ok := getFuncDoc(decl)
if ok && funcDoc != nil && funcDoc.List != nil {
if parser.matchTags(funcDoc.List) &&
matchExtension(parser.parseExtension, funcDoc.List) {
// for per 'function' comment, create a new 'Operation' object
operation := NewOperation(parser, SetCodeExampleFilesDirectory(parser.codeExampleFilesDir))
for _, comment := range astDeclaration.Doc.List {
for _, comment := range funcDoc.List {
err := operation.ParseComment(comment.Text, fileInfo.File)
if err != nil {
return fmt.Errorf("ParseComment error in file %s :%+v", fileInfo.Path, err)
Expand Down
38 changes: 36 additions & 2 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2153,7 +2153,7 @@ func TestParseTypeOverrides(t *testing.T) {
assert.NoError(t, err)

b, _ := json.MarshalIndent(p.swagger, "", " ")
//windows will fail: \r\n \n
// windows will fail: \r\n \n
assert.Equal(t, string(expected), string(b))
}

Expand Down Expand Up @@ -2234,7 +2234,7 @@ func TestParseExternalModels(t *testing.T) {
err := p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth)
assert.NoError(t, err)
b, _ := json.MarshalIndent(p.swagger, "", " ")
//ioutil.WriteFile("./testdata/external_models/main/expected.json",b,0777)
// ioutil.WriteFile("./testdata/external_models/main/expected.json",b,0777)
expected, err := os.ReadFile(filepath.Join(searchDir, "expected.json"))
assert.NoError(t, err)
assert.Equal(t, string(expected), string(b))
Expand Down Expand Up @@ -3636,6 +3636,40 @@ func Fun() {
assert.Empty(t, childName)
}

func TestParser_genVarDefinedFuncDoc(t *testing.T) {
t.Parallel()

src := `
package main
func f() {}
// @Summary generate var-defined functions' doc
// @Router /test [get]
var Func = f
// @Summary generate indirectly pointing
// @Router /test2 [get]
var Func2 = Func
`
p := New()
err := p.packages.ParseFile("api", "api/api.go", src, ParseAll)
assert.NoError(t, err)
_, _ = p.packages.ParseTypes()
err = p.packages.RangeFiles(p.ParseRouterAPIInfo)
assert.NoError(t, err)

val, ok := p.swagger.Paths.Paths["/test"]
assert.True(t, ok)
assert.NotNil(t, val.Get)
assert.Equal(t, val.Get.OperationProps.Summary, "generate var-defined functions' doc")

val2, ok := p.swagger.Paths.Paths["/test2"]
assert.True(t, ok)
assert.NotNil(t, val2.Get)
assert.Equal(t, val2.Get.OperationProps.Summary, "generate indirectly pointing")
}

func TestDefineTypeOfExample(t *testing.T) {

t.Run("String type", func(t *testing.T) {
Expand Down

0 comments on commit 55741e1

Please sign in to comment.