如何获取Go语言SSA中方法对应的*ssa.Function实例
获取Go SSA中的方法对应的*ssa.Function实例
你已经能通过res.Func(name)获取包级普通函数,但方法属于类型的成员,无法直接用该方式获取。需要通过定位目标类型,再从类型关联的方法集合中查找对应的*ssa.Function实例,具体实现如下:
核心思路
- SSA包的
res.Types字段存储了包内所有类型的SSA表示,先定位到目标类型(比如*scene.China)。 - 从目标类型的
Methods集合中,根据方法名找到对应的方法,进而获取其*ssa.Function实例。
代码实现
新增方法查找函数
可以单独封装一个函数来处理方法查找逻辑:
import "fmt" func GetMethod(pkg *ssa.Package, typeName string, methodName string) (*ssa.Function, error) { // 遍历包内所有类型,匹配目标类型 for t, ssaType := range pkg.Types { if t.String() == typeName { // 遍历该类型的所有方法,匹配目标方法名 for _, m := range ssaType.Methods { if m.Name() == methodName { return m.Func, nil } } return nil, fmt.Errorf("方法%s在类型%s中不存在", methodName, typeName) } } return nil, fmt.Errorf("包中不存在类型%s", typeName) }
在原有代码中调用
在你现有的GenBlockGraph函数中,完成ssautil.BuildPackage之后,即可调用上述函数获取目标方法:
// ... 原有BuildPackage逻辑 ... // 获取*scene.China的Speak方法 method, err := GetMethod(res, "*scene.China", "Speak") if err != nil { log.LogError.Println(err) } else { method.WriteTo(os.Stdout) return method // 如果需要返回该方法的ssa.Function }
更精确的类型匹配(可选)
如果想避免字符串匹配可能出现的歧义(比如不同包存在同名类型),可以通过types.Type的精确相等性判断来定位类型:
// 在类型检查阶段,获取*China的types.Type实例 chinaTypeName := pkg.Scope().Lookup("China").(*types.TypeName) chinaPtrType := types.NewPointer(chinaTypeName.Type()) // 遍历pkg.Types查找对应SSA类型 for t, ssaType := range res.Types { if types.Identical(t, chinaPtrType) { // 查找目标方法 for _, m := range ssaType.Methods { if m.Name() == "Speak" { // 找到对应的ssa.Function method := m.Func method.WriteTo(os.Stdout) } } } }
内容的提问来源于stack exchange,提问作者user2712836
相关产品推荐
相关产品推荐

