2 回答

TA貢獻1788條經(jīng)驗 獲得超4個贊
通過靜態(tài)分析查找表達式的類型非常重要,有時甚至是不可能的,有關詳細信息,請參閱Golang static identifier resolution。
用例是我有一個在整個(非常大的)代碼庫中常用的通用函數(shù),并且想引入該函數(shù)的新類型安全版本。為此,我希望自動確定函數(shù)的“類型”并相應地重構它:
// old
DB.InsertRow(person)
// new
Person.InsertRow(person)
僅出于重構目的,我認為不值得費心去實施它。
您可以做的是DB.InsertRow()臨時更改簽名以僅接受特定類型,例如int您確定未在任何地方使用的自定義類型(例如type tempFoo struct{})。
為了什么目的?這樣做,編譯器將為您完成艱苦的工作。您將看到錯誤消息準確顯示您的代碼庫試圖傳遞給的類型DB.InsertRow(),所以我想說任務已完成。
例如這段代碼編譯:
func doSomething(x interface{}) {}
func main() {
doSomething(image.Pt(1, 2))
doSomething("abc")
doSomething(image.Rect) // image.Rect is a function which we don't call,
// so we're passing a value of a function type here
}
如果我們改變doSomething():
func doSomething(x int) {}
我們從編譯器中得到我們正在尋找的類型:
./prog.go:10:14: 不能使用 image.Pt(1, 2)(image.Point類型的值)作為 doSomething 參數(shù)中的 int 類型
./prog.go:11:14: 不能在 doSomething 的參數(shù)中使用“abc”(無類型字符串常量)作為 int 值
./prog.go:12:14: 不能使用 image.Rect(類型func(x0 int, y0 int, x1 int, y1 int) image.Rectangle 的值)作為 doSomething 參數(shù)中的 int 類型

TA貢獻1876條經(jīng)驗 獲得超6個贊
使用Golang static identifier resolution to use的建議golang.org/x/tools/go/types
,我發(fā)現(xiàn)這對golang.org/x/tools/go/analysis
包來說非常簡單,它具有可用的類型信息以及解析的 ast。
這是我的解決方案:
package rewriter
import (
"go/ast"
"golang.org/x/tools/go/analysis"
"golang.org/x/tools/go/analysis/passes/inspect"
"golang.org/x/tools/go/ast/inspector"
)
func run(pass *analysis.Pass) (interface{}, error) {
inspect := pass.ResultOf[inspect.Analyzer].(*inspector.Inspector)
nodeFilter := []ast.Node{
(*ast.CallExpr)(nil),
}
inspect.Nodes(nodeFilter, func(node ast.Node, push bool) bool {
callExpr, ok := node.(*ast.CallExpr)
if !ok {
return true
}
funcExpr, ok := callExpr.Fun.(*ast.SelectorExpr)
if !ok {
return true
}
// check method name
if funcExpr.Sel.Name != "doSomething" {
return true
}
for _, arg := range callExpr.Args {
// lookup type of the arg
argType := pass.TypesInfo.Types[arg].Type
if argType.String() == "*rewriter.Person" {
// do whatever you want here
}
}
return false
})
return nil, nil
}
可以擴充它以查看方法的接收者并根據(jù)需要添加重構邏輯(使用analysis.Diagnostic)。
- 2 回答
- 0 關注
- 110 瀏覽
添加回答
舉報