-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gopls/internal/analysis/stdversion: set RunDespiteErrors
This change enables RunDespiteErrors, after auditing the code. This should give more timely feedback while editing. Also, it moves the vet/gopls common code (DisallowedSymbols) to typesinternal.TooNewStdSymbols, out of the gopls module, in anticipation of adding this analyzer to vet. Updates golang/go#46136 Change-Id: I8d742bf543c9146376d43ae94f7adae3b453e471 Reviewed-on: https://go-review.googlesource.com/c/tools/+/570138 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Alan Donovan <adonovan@google.com> Reviewed-by: Robert Findley <rfindley@google.com>
- Loading branch information
Showing
6 changed files
with
120 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
// Copyright 2024 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package typesinternal | ||
|
||
import ( | ||
"go/types" | ||
|
||
"golang.org/x/tools/internal/stdlib" | ||
"golang.org/x/tools/internal/versions" | ||
) | ||
|
||
// TooNewStdSymbols computes the set of package-level symbols | ||
// exported by pkg that are not available at the specified version. | ||
// The result maps each symbol to its minimum version. | ||
// | ||
// The pkg is allowed to contain type errors. | ||
func TooNewStdSymbols(pkg *types.Package, version string) map[types.Object]string { | ||
disallowed := make(map[types.Object]string) | ||
|
||
// Pass 1: package-level symbols. | ||
symbols := stdlib.PackageSymbols[pkg.Path()] | ||
for _, sym := range symbols { | ||
symver := sym.Version.String() | ||
if versions.Before(version, symver) { | ||
switch sym.Kind { | ||
case stdlib.Func, stdlib.Var, stdlib.Const, stdlib.Type: | ||
disallowed[pkg.Scope().Lookup(sym.Name)] = symver | ||
} | ||
} | ||
} | ||
|
||
// Pass 2: fields and methods. | ||
// | ||
// We allow fields and methods if their associated type is | ||
// disallowed, as otherwise we would report false positives | ||
// for compatibility shims. Consider: | ||
// | ||
// //go:build go1.22 | ||
// type T struct { F std.Real } // correct new API | ||
// | ||
// //go:build !go1.22 | ||
// type T struct { F fake } // shim | ||
// type fake struct { ... } | ||
// func (fake) M () {} | ||
// | ||
// These alternative declarations of T use either the std.Real | ||
// type, introduced in go1.22, or a fake type, for the field | ||
// F. (The fakery could be arbitrarily deep, involving more | ||
// nested fields and methods than are shown here.) Clients | ||
// that use the compatibility shim T will compile with any | ||
// version of go, whether older or newer than go1.22, but only | ||
// the newer version will use the std.Real implementation. | ||
// | ||
// Now consider a reference to method M in new(T).F.M() in a | ||
// module that requires a minimum of go1.21. The analysis may | ||
// occur using a version of Go higher than 1.21, selecting the | ||
// first version of T, so the method M is Real.M. This would | ||
// spuriously cause the analyzer to report a reference to a | ||
// too-new symbol even though this expression compiles just | ||
// fine (with the fake implementation) using go1.21. | ||
for _, sym := range symbols { | ||
symVersion := sym.Version.String() | ||
if !versions.Before(version, symVersion) { | ||
continue // allowed | ||
} | ||
|
||
var obj types.Object | ||
switch sym.Kind { | ||
case stdlib.Field: | ||
typename, name := sym.SplitField() | ||
if t := pkg.Scope().Lookup(typename); t != nil && disallowed[t] == "" { | ||
obj, _, _ = types.LookupFieldOrMethod(t.Type(), false, pkg, name) | ||
} | ||
|
||
case stdlib.Method: | ||
ptr, recvname, name := sym.SplitMethod() | ||
if t := pkg.Scope().Lookup(recvname); t != nil && disallowed[t] == "" { | ||
obj, _, _ = types.LookupFieldOrMethod(t.Type(), ptr, pkg, name) | ||
} | ||
} | ||
if obj != nil { | ||
disallowed[obj] = symVersion | ||
} | ||
} | ||
|
||
return disallowed | ||
} |