Update go version
This commit is contained in:
47
vendor/golang.org/x/tools/go/ssa/wrappers.go
generated
vendored
47
vendor/golang.org/x/tools/go/ssa/wrappers.go
generated
vendored
@@ -26,6 +26,7 @@ import (
|
||||
"go/types"
|
||||
|
||||
"golang.org/x/tools/internal/typeparams"
|
||||
"golang.org/x/tools/internal/typesinternal"
|
||||
)
|
||||
|
||||
// -- wrappers -----------------------------------------------------------
|
||||
@@ -40,14 +41,14 @@ import (
|
||||
// following axes of variation when making changes:
|
||||
// - optional receiver indirection
|
||||
// - optional implicit field selections
|
||||
// - optional method type arguments
|
||||
// - meth.Obj() may denote a concrete or an interface method
|
||||
// - the result may be a thunk or a wrapper.
|
||||
func createWrapper(prog *Program, sel *selection) *Function {
|
||||
obj := sel.obj.(*types.Func) // the declared function
|
||||
sig := sel.typ.(*types.Signature) // type of this wrapper
|
||||
func createWrapper(prog *Program, sel *selection, targs []types.Type) *Function {
|
||||
obj := sel.obj.(*types.Func) // the declared function
|
||||
name, sig := maybeInstance(prog, obj.Name(), sel.typ.(*types.Signature), targs)
|
||||
|
||||
var recv *types.Var // wrapper's receiver or thunk's params[0]
|
||||
name := obj.Name()
|
||||
var description string
|
||||
if sel.kind == types.MethodExpr {
|
||||
name += "$thunk"
|
||||
@@ -58,7 +59,7 @@ func createWrapper(prog *Program, sel *selection) *Function {
|
||||
recv = sig.Recv()
|
||||
}
|
||||
|
||||
description = fmt.Sprintf("%s for %s", description, sel.obj)
|
||||
description = fmt.Sprintf("%s for %s", description, obj)
|
||||
if prog.mode&LogSource != 0 {
|
||||
defer logStack("create %s to (%s)", description, recv.Type())()
|
||||
}
|
||||
@@ -71,6 +72,7 @@ func createWrapper(prog *Program, sel *selection) *Function {
|
||||
Synthetic: description,
|
||||
Prog: prog,
|
||||
pos: obj.Pos(),
|
||||
typeargs: targs,
|
||||
// wrappers have no syntax
|
||||
build: (*builder).buildWrapper,
|
||||
syntax: nil,
|
||||
@@ -79,6 +81,20 @@ func createWrapper(prog *Program, sel *selection) *Function {
|
||||
}
|
||||
}
|
||||
|
||||
// maybeInstance returns name and sig instantiated to reflect any type arguments in targs.
|
||||
func maybeInstance(prog *Program, name string, sig *types.Signature, targs []types.Type) (string, *types.Signature) {
|
||||
if len(targs) > 0 {
|
||||
name = fmt.Sprintf("%s%s", name, targstr(targs))
|
||||
instSig, err := types.Instantiate(prog.ctxt, sig, targs, false)
|
||||
if err != nil {
|
||||
// validate was false, we should never get an error
|
||||
panic(err)
|
||||
}
|
||||
sig = prog.canon.Type(instSig).(*types.Signature)
|
||||
}
|
||||
return name, sig
|
||||
}
|
||||
|
||||
// buildWrapper builds fn.Body for a method wrapper.
|
||||
func (b *builder) buildWrapper(fn *Function) {
|
||||
var recv *types.Var // wrapper's receiver or thunk's params[0]
|
||||
@@ -103,10 +119,12 @@ func (b *builder) buildWrapper(fn *Function) {
|
||||
// For simple indirection wrappers, perform an informative nil-check:
|
||||
// "value method (T).f called using nil *T pointer"
|
||||
if len(indices) == 1 && !isPointer(recvType(fn.object)) {
|
||||
params := typesinternal.TupleOf(fn.method.recv, tString, tString)
|
||||
results := typesinternal.TupleOf(fn.method.recv)
|
||||
var c Call
|
||||
c.Call.Value = &Builtin{
|
||||
name: "ssa:wrapnilchk",
|
||||
sig: types.NewSignatureType(nil, nil, nil, types.NewTuple(anonVar(fn.method.recv), anonVar(tString), anonVar(tString)), types.NewTuple(anonVar(fn.method.recv)), false),
|
||||
sig: types.NewSignatureType(nil, nil, nil, params, results, false),
|
||||
}
|
||||
c.Call.Args = []Value{
|
||||
v,
|
||||
@@ -137,7 +155,7 @@ func (b *builder) buildWrapper(fn *Function) {
|
||||
if !isPointer(r) {
|
||||
v = emitLoad(fn, v)
|
||||
}
|
||||
c.Call.Value = fn.Prog.objectMethod(fn.object, b)
|
||||
c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b)
|
||||
c.Call.Args = append(c.Call.Args, v)
|
||||
} else {
|
||||
c.Call.Method = fn.object
|
||||
@@ -184,19 +202,22 @@ func createParams(fn *Function, start int) {
|
||||
// Unlike createWrapper, createBound need perform no indirection or field
|
||||
// selections because that can be done before the closure is
|
||||
// constructed.
|
||||
func createBound(prog *Program, obj *types.Func) *Function {
|
||||
func createBound(prog *Program, obj *types.Func, targs []types.Type) *Function {
|
||||
description := fmt.Sprintf("bound method wrapper for %s", obj)
|
||||
if prog.mode&LogSource != 0 {
|
||||
defer logStack("%s", description)()
|
||||
}
|
||||
name, sig := maybeInstance(prog, obj.Name(), obj.Type().(*types.Signature), targs)
|
||||
|
||||
/* bound method wrapper */
|
||||
fn := &Function{
|
||||
name: obj.Name() + "$bound",
|
||||
name: name + "$bound",
|
||||
object: obj,
|
||||
Signature: changeRecv(obj.Type().(*types.Signature), nil), // drop receiver
|
||||
Signature: changeRecv(sig, nil), // drop receiver
|
||||
Synthetic: description,
|
||||
Prog: prog,
|
||||
pos: obj.Pos(),
|
||||
typeargs: targs,
|
||||
// wrappers have no syntax
|
||||
build: (*builder).buildBound,
|
||||
syntax: nil,
|
||||
@@ -215,7 +236,7 @@ func (b *builder) buildBound(fn *Function) {
|
||||
|
||||
recv := fn.FreeVars[0]
|
||||
if !types.IsInterface(recvType(fn.object)) { // concrete
|
||||
c.Call.Value = fn.Prog.objectMethod(fn.object, b)
|
||||
c.Call.Value = fn.Prog.objectMethod(fn.object, fn.typeargs, b)
|
||||
c.Call.Args = []Value{recv}
|
||||
} else {
|
||||
c.Call.Method = fn.object
|
||||
@@ -246,12 +267,12 @@ func (b *builder) buildBound(fn *Function) {
|
||||
// f is a synthetic wrapper defined as if by:
|
||||
//
|
||||
// f := func(t T) { return t.meth() }
|
||||
func createThunk(prog *Program, sel *selection) *Function {
|
||||
func createThunk(prog *Program, sel *selection, targs []types.Type) *Function {
|
||||
if sel.kind != types.MethodExpr {
|
||||
panic(sel)
|
||||
}
|
||||
|
||||
fn := createWrapper(prog, sel)
|
||||
fn := createWrapper(prog, sel, targs)
|
||||
if fn.Signature.Recv() != nil {
|
||||
panic(fn) // unexpected receiver
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user