Skip to content

Commit 1b2d1bd

Browse files
committed
gopls/internal/lsp/cache: improve precision of cache key
Use the new typerefs algorithm to improve the precision of our cache key, by excluding from the package key any dependencies that are known not to affect the results of type-checking. This makes building the package key more expensive. In particular, we must be more careful to avoid duplicate building of package keys due to races. To address this concern, the evaluation of package handles is turned a concurrent batch operation. Also fix a few bugs/oversights in the typerefs package encountered while using gopls built with this change. For golang/go#57987 Change-Id: Iec6d183b91dcd1223db0f6b64ca5231d42975c3e Reviewed-on: https://go-review.googlesource.com/c/tools/+/477455 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Robert Findley <[email protected]> Reviewed-by: Alan Donovan <[email protected]> gopls-CI: kokoro <[email protected]>
1 parent b6f4d07 commit 1b2d1bd

File tree

14 files changed

+608
-260
lines changed

14 files changed

+608
-260
lines changed

gopls/internal/astutil/util.go

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
// Copyright 2023 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
package astutil
6+
7+
import (
8+
"go/ast"
9+
10+
"golang.org/x/tools/internal/typeparams"
11+
)
12+
13+
// UnpackRecv unpacks a receiver type expression, reporting whether it is a
14+
// pointer recever, along with the type name identifier and any receiver type
15+
// parameter identifiers.
16+
//
17+
// Copied (with modifications) from go/types.
18+
func UnpackRecv(rtyp ast.Expr) (ptr bool, rname *ast.Ident, tparams []*ast.Ident) {
19+
L: // unpack receiver type
20+
// This accepts invalid receivers such as ***T and does not
21+
// work for other invalid receivers, but we don't care. The
22+
// validity of receiver expressions is checked elsewhere.
23+
for {
24+
switch t := rtyp.(type) {
25+
case *ast.ParenExpr:
26+
rtyp = t.X
27+
case *ast.StarExpr:
28+
ptr = true
29+
rtyp = t.X
30+
default:
31+
break L
32+
}
33+
}
34+
35+
// unpack type parameters, if any
36+
switch rtyp.(type) {
37+
case *ast.IndexExpr, *typeparams.IndexListExpr:
38+
var indices []ast.Expr
39+
rtyp, _, indices, _ = typeparams.UnpackIndexExpr(rtyp)
40+
for _, arg := range indices {
41+
var par *ast.Ident
42+
switch arg := arg.(type) {
43+
case *ast.Ident:
44+
par = arg
45+
default:
46+
// ignore errors
47+
}
48+
if par == nil {
49+
par = &ast.Ident{NamePos: arg.Pos(), Name: "_"}
50+
}
51+
tparams = append(tparams, par)
52+
}
53+
}
54+
55+
// unpack receiver name
56+
if name, _ := rtyp.(*ast.Ident); name != nil {
57+
rname = name
58+
}
59+
60+
return
61+
}

0 commit comments

Comments
 (0)