I want to get the function call graph information in a self-developed Go language project through the “golang.org/x/tools/go/analysis” tool, the following is the code obtained, but when it runs, pass. There is only one main.go file in the root directory in Files, I don’t know what causes it? I want to get the function call graph information in a self-developed Go language project through the “golang.org/x/tools/go/analysis” tool, the following is the code obtained, but when it runs, pass. There is only one main.go file in the root directory in Files, I don’t know what causes it?Please advise
var Analyzer = &analysis.Analyzer{
Name: "functionCallGraph",
Doc: "Generates a call graph with function details",
Run: run,
Requires: []*analysis.Analyzer{
inspect.Analyzer, // 添加依赖分析器
},
FactTypes: []analysis.Fact{},
RunDespiteErrors: true,
//Requires: []*analysis.Analyzer{config.Analyzer, accumulation.Analyzer},
}
type FunctionInfo struct {
Name string
FilePath string
Line int
Parameters []string
Returns []string
Calls []CallInfo
}
type CallInfo struct {
TargetName string
TargetPackage string
TargetVersion string
TargetFile string
TargetLine int
}
func run(pass *analysis.Pass) (interface{}, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
//inspect := getInspector()
funcInfos := []FunctionInfo{}
nodeFilter := []ast.Node{
(*ast.FuncDecl)(nil),
(*ast.CallExpr)(nil),
}
// Map to store function info by name
funcMap := map[string]*FunctionInfo{}
inspect.Preorder(nodeFilter, func(node ast.Node) {
switch n := node.(type) {
case *ast.FuncDecl:
// Process function declarations
pos := pass.Fset.Position(n.Pos())
funcInfo := FunctionInfo{
Name: n.Name.Name,
FilePath: pos.Filename,
Line: pos.Line,
Parameters: getParameters(pass.TypesInfo, n),
Returns: getReturns(pass.TypesInfo, n),
}
funcInfos = append(funcInfos, funcInfo)
funcMap[funcInfo.Name] = &funcInfo
case *ast.CallExpr:
// Process function calls
//pos := pass.Fset.Position(n.Pos())
if callerFunc := findEnclosingFunc(pass, n.Pos()); callerFunc != nil {
callInfo := processCallExpr(pass, n)
if callInfo != nil {
funcMap[callerFunc.Name].Calls = append(funcMap[callerFunc.Name].Calls, *callInfo)
}
}
}
})
// Print results
for _, info := range funcInfos {
fmt.Printf("Function %s at %s:%dn", info.Name, info.FilePath, info.Line)
fmt.Printf(" Parameters:n")
for _, param := range info.Parameters {
fmt.Printf(" - %sn", param)
}
fmt.Printf(" Returns:n")
for _, ret := range info.Returns {
fmt.Printf(" - %sn", ret)
}
fmt.Printf(" Calls:n")
for _, call := range info.Calls {
fmt.Printf(" -> %s (Package: %s, File: %s:%d)n",
call.TargetName, call.TargetPackage, call.TargetFile, call.TargetLine)
}
fmt.Println()
}
return nil, nil
}
func main() {
err := os.Chdir(os.Args[1])
if err != nil {
fmt.Printf("not find : %vn", err)
return
}
singlechecker.Main(Analyzer)
}