зеркало из https://github.com/golang/tools.git
internal/typeparams: delete OriginMethod
Use Func.Origin instead. Change-Id: Ie4d29f2bd319a46901ce137107689e37d8e1edfa Reviewed-on: https://go-review.googlesource.com/c/tools/+/569316 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Tim King <taking@google.com> Auto-Submit: Alan Donovan <adonovan@google.com>
This commit is contained in:
Родитель
070fcfb90b
Коммит
9a6aed93ab
|
@ -8,8 +8,6 @@ import (
|
|||
"fmt"
|
||||
"go/types"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// A generic records information about a generic origin function,
|
||||
|
@ -80,7 +78,7 @@ func createInstance(fn *Function, targs []types.Type, cr *creator) *Function {
|
|||
if prog.mode&InstantiateGenerics != 0 && !prog.parameterized.anyParameterized(targs) {
|
||||
synthetic = fmt.Sprintf("instance of %s", fn.Name())
|
||||
if fn.syntax != nil {
|
||||
scope := typeparams.OriginMethod(obj).Scope()
|
||||
scope := obj.Origin().Scope()
|
||||
subst = makeSubster(prog.ctxt, scope, fn.typeparams, targs, false)
|
||||
build = (*builder).buildFromSyntax
|
||||
} else {
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
|
||||
"golang.org/x/tools/go/types/typeutil"
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// MethodValue returns the Function implementing method sel, building
|
||||
|
@ -103,7 +102,7 @@ func (prog *Program) objectMethod(obj *types.Func, cr *creator) *Function {
|
|||
}
|
||||
|
||||
// Instantiation of generic?
|
||||
if originObj := typeparams.OriginMethod(obj); originObj != obj {
|
||||
if originObj := obj.Origin(); originObj != obj {
|
||||
origin := prog.objectMethod(originObj, cr)
|
||||
assert(origin.typeparams.Len() > 0, "origin is not generic")
|
||||
targs := receiverTypeArgs(obj)
|
||||
|
|
|
@ -14,8 +14,6 @@ import (
|
|||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// EnclosingFunction returns the function that contains the syntax
|
||||
|
@ -122,7 +120,7 @@ func findNamedFunc(pkg *Package, pos token.Pos) *Function {
|
|||
obj := mset.At(i).Obj().(*types.Func)
|
||||
if obj.Pos() == pos {
|
||||
// obj from MethodSet may not be the origin type.
|
||||
m := typeparams.OriginMethod(obj)
|
||||
m := obj.Origin()
|
||||
return pkg.objects[m].(*Function)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ import (
|
|||
"strings"
|
||||
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
|
@ -395,7 +394,7 @@ func (enc *Encoder) concreteMethod(meth *types.Func) (Path, bool) {
|
|||
// of objectpath will only be giving us origin methods, anyway, as referring
|
||||
// to instantiated methods is usually not useful.
|
||||
|
||||
if typeparams.OriginMethod(meth) != meth {
|
||||
if meth.Origin() != meth {
|
||||
return "", false
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"golang.org/x/tools/go/analysis/passes/inspect"
|
||||
"golang.org/x/tools/go/ast/inspector"
|
||||
"golang.org/x/tools/internal/analysisinternal"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
//go:embed doc.go
|
||||
|
@ -67,8 +66,8 @@ func checkDeprecated(pass *analysis.Pass) (interface{}, error) {
|
|||
}
|
||||
|
||||
obj := pass.TypesInfo.ObjectOf(sel.Sel)
|
||||
if obj_, ok := obj.(*types.Func); ok {
|
||||
obj = typeparams.OriginMethod(obj_)
|
||||
if fn, ok := obj.(*types.Func); ok {
|
||||
obj = fn.Origin()
|
||||
}
|
||||
if obj == nil || obj.Pkg() == nil {
|
||||
// skip invalid sel.Sel.
|
||||
|
|
|
@ -54,7 +54,6 @@ import (
|
|||
"golang.org/x/tools/go/types/objectpath"
|
||||
"golang.org/x/tools/gopls/internal/util/frob"
|
||||
"golang.org/x/tools/gopls/internal/util/safetoken"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// An Index records the non-empty method sets of all package-level
|
||||
|
@ -229,7 +228,7 @@ func (b *indexBuilder) build(fset *token.FileSet, pkg *types.Package) *Index {
|
|||
|
||||
// Instantiations of generic methods don't have an
|
||||
// object path, so we use the generic.
|
||||
if p, err := objectpathFor(typeparams.OriginMethod(method)); err != nil {
|
||||
if p, err := objectpathFor(method.Origin()); err != nil {
|
||||
panic(err) // can't happen for a method of a package-level type
|
||||
} else {
|
||||
m.ObjectPath = b.string(string(p))
|
||||
|
|
|
@ -19,7 +19,6 @@ import (
|
|||
"golang.org/x/tools/gopls/internal/protocol"
|
||||
"golang.org/x/tools/gopls/internal/util/frob"
|
||||
"golang.org/x/tools/gopls/internal/util/typesutil"
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
)
|
||||
|
||||
// Index constructs a serializable index of outbound cross-references
|
||||
|
@ -68,7 +67,7 @@ func Index(files []*parsego.File, pkg *types.Package, info *types.Info) []byte {
|
|||
// For instantiations of generic methods,
|
||||
// use the generic object (see issue #60622).
|
||||
if fn, ok := obj.(*types.Func); ok {
|
||||
obj = typeparams.OriginMethod(fn)
|
||||
obj = fn.Origin()
|
||||
}
|
||||
|
||||
objects := getObjects(obj.Pkg())
|
||||
|
|
|
@ -13,13 +13,11 @@
|
|||
package typeparams
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/token"
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/internal/aliases"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
// UnpackIndexExpr extracts data from AST nodes that represent index
|
||||
|
@ -71,57 +69,6 @@ func IsTypeParam(t types.Type) bool {
|
|||
return ok
|
||||
}
|
||||
|
||||
// OriginMethod returns the origin method associated with the method fn.
|
||||
// For methods on a non-generic receiver base type, this is just
|
||||
// fn. However, for methods with a generic receiver, OriginMethod returns the
|
||||
// corresponding method in the method set of the origin type.
|
||||
//
|
||||
// As a special case, if fn is not a method (has no receiver), OriginMethod
|
||||
// returns fn.
|
||||
func OriginMethod(fn *types.Func) *types.Func {
|
||||
recv := fn.Type().(*types.Signature).Recv()
|
||||
if recv == nil {
|
||||
return fn
|
||||
}
|
||||
_, named := typesinternal.ReceiverNamed(recv)
|
||||
if named == nil {
|
||||
// Receiver is a *types.Interface.
|
||||
return fn
|
||||
}
|
||||
if named.TypeParams().Len() == 0 {
|
||||
// Receiver base has no type parameters, so we can avoid the lookup below.
|
||||
return fn
|
||||
}
|
||||
orig := named.Origin()
|
||||
gfn, _, _ := types.LookupFieldOrMethod(orig, true, fn.Pkg(), fn.Name())
|
||||
|
||||
// This is a fix for a gopls crash (#60628) due to a go/types bug (#60634). In:
|
||||
// package p
|
||||
// type T *int
|
||||
// func (*T) f() {}
|
||||
// LookupFieldOrMethod(T, true, p, f)=nil, but NewMethodSet(*T)={(*T).f}.
|
||||
// Here we make them consistent by force.
|
||||
// (The go/types bug is general, but this workaround is reached only
|
||||
// for generic T thanks to the early return above.)
|
||||
if gfn == nil {
|
||||
mset := types.NewMethodSet(types.NewPointer(orig))
|
||||
for i := 0; i < mset.Len(); i++ {
|
||||
m := mset.At(i)
|
||||
if m.Obj().Id() == fn.Id() {
|
||||
gfn = m.Obj()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In golang/go#61196, we observe another crash, this time inexplicable.
|
||||
if gfn == nil {
|
||||
panic(fmt.Sprintf("missing origin method for %s.%s; named == origin: %t, named.NumMethods(): %d, origin.NumMethods(): %d", named, fn, named == orig, named.NumMethods(), orig.NumMethods()))
|
||||
}
|
||||
|
||||
return gfn.(*types.Func)
|
||||
}
|
||||
|
||||
// GenericAssignableTo is a generalization of types.AssignableTo that
|
||||
// implements the following rule for uninstantiated generic types:
|
||||
//
|
||||
|
|
|
@ -39,7 +39,7 @@ func TestGetIndexExprData(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestOriginMethodRecursive(t *testing.T) {
|
||||
func TestFuncOriginRecursive(t *testing.T) {
|
||||
src := `package p
|
||||
|
||||
type N[A any] int
|
||||
|
@ -104,13 +104,13 @@ func (r *N[C]) n() { }
|
|||
}
|
||||
|
||||
for _, test := range tests {
|
||||
if got := OriginMethod(test.input); got != test.want {
|
||||
t.Errorf("OriginMethod(%q) = %v, want %v", test.name, test.input, test.want)
|
||||
if got := test.input.Origin(); got != test.want {
|
||||
t.Errorf("Origin(%q) = %v, want %v", test.name, test.input, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOriginMethodUses(t *testing.T) {
|
||||
func TestFuncOriginUses(t *testing.T) {
|
||||
|
||||
tests := []string{
|
||||
`type T interface { m() }; func _(t T) { t.m() }`,
|
||||
|
@ -147,7 +147,7 @@ func TestOriginMethodUses(t *testing.T) {
|
|||
if call, ok := n.(*ast.CallExpr); ok {
|
||||
sel := call.Fun.(*ast.SelectorExpr)
|
||||
use := info.Uses[sel.Sel].(*types.Func)
|
||||
orig := OriginMethod(use)
|
||||
orig := use.Origin()
|
||||
if orig != m {
|
||||
t.Errorf("%s:\nUses[%v] = %v, want %v", src, types.ExprString(sel), use, m)
|
||||
}
|
||||
|
@ -160,8 +160,8 @@ func TestOriginMethodUses(t *testing.T) {
|
|||
// Issue #60628 was a crash in gopls caused by inconsistency (#60634) between
|
||||
// LookupFieldOrMethod and NewFileSet for methods with an illegal
|
||||
// *T receiver type, where T itself is a pointer.
|
||||
// This is a regression test for the workaround in OriginMethod.
|
||||
func TestOriginMethod60628(t *testing.T) {
|
||||
// This is a regression test for the workaround in the (now deleted) OriginMethod.
|
||||
func TestFuncOrigin60628(t *testing.T) {
|
||||
const src = `package p; type T[P any] *int; func (r *T[A]) f() {}`
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, "p.go", src, 0)
|
||||
|
@ -199,8 +199,8 @@ func TestOriginMethod60628(t *testing.T) {
|
|||
}
|
||||
|
||||
// Check the workaround.
|
||||
if OriginMethod(m) == nil {
|
||||
t.Errorf("OriginMethod(%v) = nil", m)
|
||||
if m.Origin() == nil {
|
||||
t.Errorf("Origin(%v) = nil", m)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче