diff --git a/go/types/api.go b/go/types/api.go index 341c8e42..6c8f7648 100644 --- a/go/types/api.go +++ b/go/types/api.go @@ -48,6 +48,10 @@ func Check(path string, fset *token.FileSet, files []*ast.File) (*Package, error // A Config specifies the configuration for type checking. // The zero value for Config is a ready-to-use default configuration. type Config struct { + // If IgnoreFuncBodies is set, function bodies are not + // type-checked. + IgnoreFuncBodies bool + // If Error != nil, it is called with each error found // during type checking. The error strings of errors with // detailed position information are formatted as follows: @@ -99,7 +103,9 @@ type Info struct { // If Objects != nil, it records the identifier and corresponding object // for each identifier that is type-checked (including package names, // dots "." of dot-imports, and blank "_" identifiers). For identifiers - // that were not declared due to an error, the corresponding object is nil. + // that are not declared (due to an error, or because they are symbolic + // as the t in t := x.(type) of a type switch header), the corresponding + // object is nil. // BUG(gri) Label identifiers in break, continue, or goto statements // are not recorded. Objects map[*ast.Ident]Object diff --git a/go/types/resolver.go b/go/types/resolver.go index 6c4cd089..4e8ae7e0 100644 --- a/go/types/resolver.go +++ b/go/types/resolver.go @@ -71,7 +71,7 @@ type funcInfo struct { // later appends a function with non-empty body to check.funcList. func (check *checker) later(f *Func, sig *Signature, body *ast.BlockStmt) { // functions implemented elsewhere (say in assembly) have no body - if body != nil { + if !check.conf.IgnoreFuncBodies && body != nil { check.funcList = append(check.funcList, funcInfo{f, sig, body}) } } diff --git a/go/types/self_test.go b/go/types/self_test.go index 3e0ea49e..befc46bc 100644 --- a/go/types/self_test.go +++ b/go/types/self_test.go @@ -42,9 +42,15 @@ func TestSelf(t *testing.T) { return // skip benchmark in short mode } + benchmark(fset, files, false) + benchmark(fset, files, true) +} + +func benchmark(fset *token.FileSet, files []*ast.File, full bool) { b := testing.Benchmark(func(b *testing.B) { for i := 0; i < b.N; i++ { - Check("go/types", fset, files) + conf := Config{IgnoreFuncBodies: !full} + conf.Check("go/types", fset, files, nil) } })