101 lines
2.3 KiB
Go
101 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
"strings"
|
|
)
|
|
|
|
type Symbol struct {
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Package string `json:"package"`
|
|
Exported bool `json:"exported"`
|
|
Position Position `json:"position"`
|
|
}
|
|
|
|
func findSymbols(dir string, pattern string) ([]Symbol, error) {
|
|
var symbols []Symbol
|
|
|
|
err := walkGoFiles(dir, func(path string, src []byte, file *ast.File, fset *token.FileSet) error {
|
|
if strings.HasSuffix(path, "_test.go") && !strings.Contains(pattern, "Test") {
|
|
return nil
|
|
}
|
|
|
|
pkgName := file.Name.Name
|
|
|
|
ast.Inspect(file, func(n ast.Node) bool {
|
|
switch decl := n.(type) {
|
|
case *ast.FuncDecl:
|
|
name := decl.Name.Name
|
|
if matchesPattern(name, pattern) {
|
|
pos := fset.Position(decl.Pos())
|
|
symbols = append(symbols, Symbol{
|
|
Name: name,
|
|
Type: "function",
|
|
Package: pkgName,
|
|
Exported: ast.IsExported(name),
|
|
Position: newPosition(pos),
|
|
})
|
|
}
|
|
|
|
case *ast.GenDecl:
|
|
for _, spec := range decl.Specs {
|
|
switch s := spec.(type) {
|
|
case *ast.TypeSpec:
|
|
name := s.Name.Name
|
|
if matchesPattern(name, pattern) {
|
|
pos := fset.Position(s.Pos())
|
|
kind := "type"
|
|
switch s.Type.(type) {
|
|
case *ast.InterfaceType:
|
|
kind = "interface"
|
|
case *ast.StructType:
|
|
kind = "struct"
|
|
}
|
|
symbols = append(symbols, Symbol{
|
|
Name: name,
|
|
Type: kind,
|
|
Package: pkgName,
|
|
Exported: ast.IsExported(name),
|
|
Position: newPosition(pos),
|
|
})
|
|
}
|
|
|
|
case *ast.ValueSpec:
|
|
for _, name := range s.Names {
|
|
if matchesPattern(name.Name, pattern) {
|
|
pos := fset.Position(name.Pos())
|
|
kind := "variable"
|
|
if decl.Tok == token.CONST {
|
|
kind = "constant"
|
|
}
|
|
symbols = append(symbols, Symbol{
|
|
Name: name.Name,
|
|
Type: kind,
|
|
Package: pkgName,
|
|
Exported: ast.IsExported(name.Name),
|
|
Position: newPosition(pos),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
})
|
|
|
|
return nil
|
|
})
|
|
|
|
return symbols, err
|
|
}
|
|
|
|
func matchesPattern(name, pattern string) bool {
|
|
if pattern == "" {
|
|
return true
|
|
}
|
|
pattern = strings.ToLower(pattern)
|
|
name = strings.ToLower(name)
|
|
return strings.Contains(name, pattern)
|
|
} |