internal/lsp: enable "ignoreFuncBodies" and fix caching

This change enables the trimmed ASTs behavior and fixes the broken
tests by caching parse errors along with the ASTs that are being reused.

Change-Id: Ia8e7cdb138c62a8be88659f801506e03f213fe8c
Reviewed-on: https://go-review.googlesource.com/c/tools/+/181357
Run-TryBot: Rebecca Stambler <rstambler@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Cottrell <iancottrell@google.com>
This commit is contained in:
Rebecca Stambler 2019-06-07 21:57:42 -04:00
parent e9a20a1396
commit f68ef2071d
3 changed files with 11 additions and 16 deletions

View File

@ -101,8 +101,7 @@ func (imp *importer) typeCheck(pkgPath string) (*pkg, error) {
} }
// Ignore function bodies for any dependency packages. // Ignore function bodies for any dependency packages.
// TODO: Enable this. ignoreFuncBodies := imp.topLevelPkgID != pkg.id
ignoreFuncBodies := false
// Don't type-check function bodies if we are not in the top-level package. // Don't type-check function bodies if we are not in the top-level package.
files, errs := imp.parseFiles(meta.files, ignoreFuncBodies) files, errs := imp.parseFiles(meta.files, ignoreFuncBodies)

View File

@ -22,6 +22,7 @@ type goFile struct {
type astFile struct { type astFile struct {
file *ast.File file *ast.File
err error // parse errors
isTrimmed bool isTrimmed bool
} }

View File

@ -41,11 +41,9 @@ func (imp *importer) parseFiles(filenames []string, ignoreFuncBodies bool) ([]*a
errors := make([]error, n) errors := make([]error, n)
for i, filename := range filenames { for i, filename := range filenames {
if imp.ctx.Err() != nil { if imp.ctx.Err() != nil {
parsed[i] = nil parsed[i], errors[i] = nil, imp.ctx.Err()
errors[i] = imp.ctx.Err()
continue continue
} }
// First, check if we have already cached an AST for this file. // First, check if we have already cached an AST for this file.
f, err := imp.view.findFile(span.FileURI(filename)) f, err := imp.view.findFile(span.FileURI(filename))
if err != nil || f == nil { if err != nil || f == nil {
@ -57,7 +55,6 @@ func (imp *importer) parseFiles(filenames []string, ignoreFuncBodies bool) ([]*a
parsed[i], errors[i] = nil, fmt.Errorf("non-Go file in parse call: %v", filename) parsed[i], errors[i] = nil, fmt.Errorf("non-Go file in parse call: %v", filename)
continue continue
} }
wg.Add(1) wg.Add(1)
go func(i int, filename string) { go func(i int, filename string) {
ioLimit <- true // wait ioLimit <- true // wait
@ -68,17 +65,15 @@ func (imp *importer) parseFiles(filenames []string, ignoreFuncBodies bool) ([]*a
// If we already have a cached AST, reuse it. // If we already have a cached AST, reuse it.
// If the AST is trimmed, only use it if we are ignoring function bodies. // If the AST is trimmed, only use it if we are ignoring function bodies.
if gof.astIsTrimmed() && ignoreFuncBodies { if gof.ast != nil && gof.ast.isTrimmed == ignoreFuncBodies {
parsed[i], errors[i] = gof.ast, nil parsed[i], errors[i] = gof.ast, gof.ast.err
return
} else if gof.ast != nil && !gof.ast.isTrimmed && !ignoreFuncBodies {
parsed[i], errors[i] = gof.ast, nil
return return
} }
// We don't have a cached AST for this file, so we read its content and parse it. // We don't have a cached AST for this file, so we read its content and parse it.
data, _, err := gof.Handle(imp.ctx).Read(imp.ctx) data, _, err := gof.Handle(imp.ctx).Read(imp.ctx)
if err != nil { if err != nil {
parsed[i], errors[i] = nil, err
return return
} }
src := data src := data
@ -89,20 +84,20 @@ func (imp *importer) parseFiles(filenames []string, ignoreFuncBodies bool) ([]*a
// ParseFile may return a partial AST and an error. // ParseFile may return a partial AST and an error.
f, err := parseFile(imp.fset, filename, src) f, err := parseFile(imp.fset, filename, src)
parsed[i], errors[i] = &astFile{
file: f,
err: err,
isTrimmed: ignoreFuncBodies,
}, err
if ignoreFuncBodies { if ignoreFuncBodies {
trimAST(f) trimAST(f)
} }
// Fix any badly parsed parts of the AST. // Fix any badly parsed parts of the AST.
if f != nil { if f != nil {
tok := imp.fset.File(f.Pos()) tok := imp.fset.File(f.Pos())
imp.view.fix(imp.ctx, f, tok, src) imp.view.fix(imp.ctx, f, tok, src)
} }
parsed[i] = &astFile{f, ignoreFuncBodies}
errors[i] = err
}(i, filename) }(i, filename)
} }
wg.Wait() wg.Wait()