Last active
July 16, 2023 00:10
-
-
Save ecoshub/eeed3adc1ee9ee1c525bba8143343f61 to your computer and use it in GitHub Desktop.
get function info including comment / doc section
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"errors" | |
"fmt" | |
"go/ast" | |
"go/doc" | |
"go/parser" | |
"go/token" | |
"path/filepath" | |
"reflect" | |
"runtime" | |
"strings" | |
) | |
// Info minimal info struct for function | |
type Info struct { | |
FilePath string | |
FunctionName string | |
Comment string | |
FunctionLine int | |
} | |
// function main | |
// this is the first line of comment | |
// this is the second line of comment | |
func main() { | |
c, err := GetFunctionInfo(main) | |
if err != nil { | |
fmt.Println(err) | |
return | |
} | |
fmt.Println("FilePath:", c.FilePath) | |
fmt.Println("FunctionName:", c.FunctionName) | |
fmt.Println("FunctionLine:", c.FunctionLine) | |
fmt.Println("Comment:", c.Comment) | |
} | |
func GetFunctionInfo(f interface{}) (*Info, error) { | |
ffpc := runtime.FuncForPC(reflect.ValueOf(f).Pointer()) | |
if ffpc == nil { | |
return nil, errors.New("error. function program counter is nil") | |
} | |
filePath, functionLine := ffpc.FileLine(0) | |
fset := token.NewFileSet() | |
parsedAst, err := parser.ParseFile(fset, filePath, nil, parser.ParseComments) | |
if err != nil { | |
return nil, err | |
} | |
tokens := strings.Split(ffpc.Name(), ".") | |
if len(tokens) != 2 { | |
return nil, errors.New("error. func name split failed") | |
} | |
funcName := tokens[1] | |
importPath, err := filepath.Abs("/") | |
if err != nil { | |
return nil, err | |
} | |
pkg := &ast.Package{ | |
Files: map[string]*ast.File{filePath: parsedAst}, | |
} | |
myDoc := doc.New(pkg, importPath, doc.AllDecls) | |
for _, theFunc := range myDoc.Funcs { | |
if theFunc.Name == funcName { | |
return &Info{ | |
FilePath: filePath, | |
FunctionName: funcName, | |
Comment: theFunc.Doc, | |
FunctionLine: functionLine, | |
}, nil | |
} | |
} | |
return nil, nil | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment