go.tools/go/types: cleanup: more consistent exported predicate names
Renamed predicates: IsIdentical -> Identical IsAssignableTo -> AssignableTo Signature.IsVariadic -> Signature.Variadic Object.IsExported -> Object.Exported LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/53370043
This commit is contained in:
parent
aea9f68811
commit
ebfa4efbc4
|
@ -221,7 +221,7 @@ func (f *File) checkShadowing(ident *ast.Ident) {
|
|||
}
|
||||
}
|
||||
// Don't complain if the types differ: that implies the programmer really wants two variables.
|
||||
if types.IsIdentical(obj.Type(), shadowed.Type()) {
|
||||
if types.Identical(obj.Type(), shadowed.Type()) {
|
||||
f.Badf(ident.Pos(), "declaration of %s shadows declaration at %s", obj.Name(), f.loc(shadowed.Pos()))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
|
|||
|
||||
case *types.Array:
|
||||
// Same as slice.
|
||||
if types.IsIdentical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
|
||||
if types.Identical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
|
||||
return true // %s matches []byte
|
||||
}
|
||||
// Recur: []int matches %d.
|
||||
|
@ -140,7 +140,7 @@ func (f *File) matchArgTypeInternal(t printfArgType, typ types.Type, arg ast.Exp
|
|||
|
||||
case *types.Slice:
|
||||
// Same as array.
|
||||
if types.IsIdentical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
|
||||
if types.Identical(typ.Elem().Underlying(), types.Typ[types.Byte]) && t&argString != 0 {
|
||||
return true // %s matches []byte
|
||||
}
|
||||
// Recur: []int matches %d. But watch out for
|
||||
|
@ -269,7 +269,7 @@ func (f *File) isErrorMethodCall(call *ast.CallExpr) bool {
|
|||
typ := f.pkg.types[call]
|
||||
if typ != nil {
|
||||
// We know it's called "Error", so just check the function signature.
|
||||
return types.IsIdentical(f.pkg.types[call.Fun], stringerMethodType)
|
||||
return types.Identical(f.pkg.types[call.Fun], stringerMethodType)
|
||||
}
|
||||
// Without types, we can still check by hand.
|
||||
// Is it a selector expression? Otherwise it's a function call, not a method call.
|
||||
|
|
|
@ -384,7 +384,7 @@ func (p *exporter) signature(sig *types.Signature) {
|
|||
}
|
||||
p.tuple(sig.Params())
|
||||
p.tuple(sig.Results())
|
||||
if sig.IsVariadic() {
|
||||
if sig.Variadic() {
|
||||
p.int(1)
|
||||
} else {
|
||||
p.int(0)
|
||||
|
|
|
@ -63,7 +63,7 @@ func (c *rVBytesConstraint) solve(a *analysis, _ *node, delta nodeset) {
|
|||
}
|
||||
|
||||
tSlice, ok := tDyn.Underlying().(*types.Slice)
|
||||
if ok && types.IsIdentical(tSlice.Elem(), types.Typ[types.Uint8]) {
|
||||
if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
|
||||
if a.onlineCopy(c.result, slice) {
|
||||
changed = true
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ func (c *rVSetBytesConstraint) solve(a *analysis, _ *node, delta nodeset) {
|
|||
}
|
||||
|
||||
tSlice, ok := tDyn.Underlying().(*types.Slice)
|
||||
if ok && types.IsIdentical(tSlice.Elem(), types.Typ[types.Uint8]) {
|
||||
if ok && types.Identical(tSlice.Elem(), types.Typ[types.Uint8]) {
|
||||
if a.onlineCopy(slice, c.x) {
|
||||
a.addWork(slice)
|
||||
}
|
||||
|
@ -1559,7 +1559,7 @@ func changeRecv(sig *types.Signature) *types.Signature {
|
|||
for i := 0; i < n; i++ {
|
||||
p2[i+1] = params.At(i)
|
||||
}
|
||||
return types.NewSignature(nil, nil, types.NewTuple(p2...), sig.Results(), sig.IsVariadic())
|
||||
return types.NewSignature(nil, nil, types.NewTuple(p2...), sig.Results(), sig.Variadic())
|
||||
}
|
||||
|
||||
func (c *rtypeMethodByNameConstraint) solve(a *analysis, _ *node, delta nodeset) {
|
||||
|
|
|
@ -268,7 +268,7 @@ func (c *typeFilterConstraint) solve(a *analysis, n *node, delta nodeset) {
|
|||
panic("indirect tagged object")
|
||||
}
|
||||
|
||||
if types.IsAssignableTo(tDyn, c.typ) {
|
||||
if types.AssignableTo(tDyn, c.typ) {
|
||||
if a.addLabel(c.dst, ifaceObj) {
|
||||
a.addWork(c.dst)
|
||||
}
|
||||
|
@ -277,9 +277,9 @@ func (c *typeFilterConstraint) solve(a *analysis, n *node, delta nodeset) {
|
|||
}
|
||||
|
||||
func (c *untagConstraint) solve(a *analysis, n *node, delta nodeset) {
|
||||
predicate := types.IsAssignableTo
|
||||
predicate := types.AssignableTo
|
||||
if c.exact {
|
||||
predicate = types.IsIdentical
|
||||
predicate = types.Identical
|
||||
}
|
||||
for ifaceObj := range delta {
|
||||
tDyn, v, indirect := a.taggedValue(ifaceObj)
|
||||
|
|
|
@ -843,7 +843,7 @@ func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallEx
|
|||
|
||||
// Actual->formal assignability conversions for normal parameters.
|
||||
np := sig.Params().Len() // number of normal parameters
|
||||
if sig.IsVariadic() {
|
||||
if sig.Variadic() {
|
||||
np--
|
||||
}
|
||||
for i := 0; i < np; i++ {
|
||||
|
@ -852,7 +852,7 @@ func (b *builder) emitCallArgs(fn *Function, sig *types.Signature, e *ast.CallEx
|
|||
|
||||
// Actual->formal assignability conversions for variadic parameter,
|
||||
// and construction of slice.
|
||||
if sig.IsVariadic() {
|
||||
if sig.Variadic() {
|
||||
varargs := args[offset+np:]
|
||||
st := sig.Params().At(np).Type().(*types.Slice)
|
||||
vt := st.Elem()
|
||||
|
@ -2177,7 +2177,7 @@ func (p *Package) Build() {
|
|||
// TODO(adonovan): ideally belongs in memberFromObject, but
|
||||
// that would require package creation in topological order.
|
||||
for obj := range p.values {
|
||||
if obj.IsExported() {
|
||||
if obj.Exported() {
|
||||
p.needMethodsOf(obj.Type())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
|
|||
}
|
||||
}
|
||||
|
||||
if types.IsIdentical(xt, yt) {
|
||||
if types.Identical(xt, yt) {
|
||||
// no conversion necessary
|
||||
} else if _, ok := xt.(*types.Interface); ok {
|
||||
y = emitConv(f, y, x.Type())
|
||||
|
@ -147,7 +147,7 @@ func emitCompare(f *Function, op token.Token, x, y Value, pos token.Pos) Value {
|
|||
//
|
||||
func isValuePreserving(ut_src, ut_dst types.Type) bool {
|
||||
// Identical underlying types?
|
||||
if types.IsIdentical(ut_dst, ut_src) {
|
||||
if types.Identical(ut_dst, ut_src) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -179,7 +179,7 @@ func emitConv(f *Function, val Value, typ types.Type) Value {
|
|||
t_src := val.Type()
|
||||
|
||||
// Identical types? Conversion is a no-op.
|
||||
if types.IsIdentical(t_src, typ) {
|
||||
if types.Identical(t_src, typ) {
|
||||
return val
|
||||
}
|
||||
|
||||
|
|
|
@ -520,7 +520,7 @@ func writeSignature(w io.Writer, pkg *types.Package, name string, sig *types.Sig
|
|||
}
|
||||
io.WriteString(w, v.Name())
|
||||
io.WriteString(w, " ")
|
||||
if sig.IsVariadic() && i == len(params)-1 {
|
||||
if sig.Variadic() && i == len(params)-1 {
|
||||
io.WriteString(w, "...")
|
||||
io.WriteString(w, relType(v.Type().Underlying().(*types.Slice).Elem(), pkg))
|
||||
} else {
|
||||
|
|
|
@ -875,7 +875,7 @@ func typeAssert(i *interpreter, instr *ssa.TypeAssert, itf iface) value {
|
|||
v = itf
|
||||
err = checkInterface(i, idst, itf)
|
||||
|
||||
} else if types.IsIdentical(itf.t, instr.AssertedType) {
|
||||
} else if types.Identical(itf.t, instr.AssertedType) {
|
||||
v = copyVal(itf.v) // extract value
|
||||
|
||||
} else {
|
||||
|
|
|
@ -96,7 +96,7 @@ var (
|
|||
)
|
||||
|
||||
// hashType returns a hash for t such that
|
||||
// types.IsIdentical(x, y) => hashType(x) == hashType(y).
|
||||
// types.Identical(x, y) => hashType(x) == hashType(y).
|
||||
func hashType(t types.Type) int {
|
||||
mu.Lock()
|
||||
h := int(hasher.Hash(t))
|
||||
|
@ -169,12 +169,12 @@ func (x structure) hash(t types.Type) int {
|
|||
return h
|
||||
}
|
||||
|
||||
// nil-tolerant variant of types.IsIdentical.
|
||||
// nil-tolerant variant of types.Identical.
|
||||
func sameType(x, y types.Type) bool {
|
||||
if x == nil {
|
||||
return y == nil
|
||||
}
|
||||
return y != nil && types.IsIdentical(x, y)
|
||||
return y != nil && types.Identical(x, y)
|
||||
}
|
||||
|
||||
func (x iface) eq(t types.Type, _y interface{}) bool {
|
||||
|
@ -191,7 +191,7 @@ func (x rtype) hash(_ types.Type) int {
|
|||
}
|
||||
|
||||
func (x rtype) eq(_ types.Type, y interface{}) bool {
|
||||
return types.IsIdentical(x.t, y.(rtype).t)
|
||||
return types.Identical(x.t, y.(rtype).t)
|
||||
}
|
||||
|
||||
// equals returns true iff x and y are equal according to Go's
|
||||
|
|
|
@ -120,7 +120,7 @@ func printCall(v *CallCommon, prefix string, instr Instruction) string {
|
|||
}
|
||||
b.WriteString(relName(arg, instr))
|
||||
}
|
||||
if v.Signature().IsVariadic() {
|
||||
if v.Signature().Variadic() {
|
||||
b.WriteString("...")
|
||||
}
|
||||
b.WriteString(")")
|
||||
|
|
|
@ -284,7 +284,7 @@ func createParams(fn *Function) {
|
|||
for i, n := 0, tparams.Len(); i < n; i++ {
|
||||
last = fn.addParamObj(tparams.At(i))
|
||||
}
|
||||
if fn.Signature.IsVariadic() {
|
||||
if fn.Signature.Variadic() {
|
||||
last.typ = types.NewSlice(last.typ)
|
||||
}
|
||||
}
|
||||
|
@ -415,5 +415,5 @@ func boundMethodWrapper(prog *Program, obj *types.Func) *Function {
|
|||
}
|
||||
|
||||
func changeRecv(s *types.Signature, recv *types.Var) *types.Signature {
|
||||
return types.NewSignature(nil, recv, s.Params(), s.Results(), s.IsVariadic())
|
||||
return types.NewSignature(nil, recv, s.Params(), s.Results(), s.Variadic())
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func checkFuncValue(t *testing.T, prog *ssa.Program, obj *types.Func) {
|
|||
obj, fnobj, fn.Name())
|
||||
return
|
||||
}
|
||||
if !types.IsIdentical(fn.Type(), obj.Type()) {
|
||||
if !types.Identical(fn.Type(), obj.Type()) {
|
||||
t.Errorf("FuncValue(%s).Type() == %s", obj, fn.Type())
|
||||
return
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ func checkConstValue(t *testing.T, prog *ssa.Program, obj *types.Const) {
|
|||
t.Errorf("ConstValue(%s) == nil", obj)
|
||||
return
|
||||
}
|
||||
if !types.IsIdentical(c.Type(), obj.Type()) {
|
||||
if !types.Identical(c.Type(), obj.Type()) {
|
||||
t.Errorf("ConstValue(%s).Type() == %s", obj, c.Type())
|
||||
return
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ func checkVarValue(t *testing.T, prog *ssa.Program, pkg *ssa.Package, ref []ast.
|
|||
} else if gotAddr {
|
||||
t.Errorf("%s: got address, want value", prefix)
|
||||
}
|
||||
if !types.IsIdentical(v.Type(), expType) {
|
||||
if !types.Identical(v.Type(), expType) {
|
||||
t.Errorf("%s.Type() == %s, want %s", prefix, v.Type(), expType)
|
||||
}
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ func TestValueForExpr(t *testing.T) {
|
|||
if gotAddr {
|
||||
T = T.Underlying().(*types.Pointer).Elem() // deref
|
||||
}
|
||||
if !types.IsIdentical(T, mainInfo.TypeOf(e)) {
|
||||
if !types.Identical(T, mainInfo.TypeOf(e)) {
|
||||
t.Errorf("%s: got type %s, want %s", position, mainInfo.TypeOf(e), T)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1271,7 +1271,7 @@ type anInstruction struct {
|
|||
// go invoke t3.Run(t2)
|
||||
// defer invoke t4.Handle(...t5)
|
||||
//
|
||||
// For all calls to variadic functions (Signature().IsVariadic()),
|
||||
// For all calls to variadic functions (Signature().Variadic()),
|
||||
// the last element of Args is a slice.
|
||||
//
|
||||
type CallCommon struct {
|
||||
|
|
|
@ -150,7 +150,7 @@ func testMainSlice(fn *Function, expfuncs []*Function, prefix string, slice type
|
|||
|
||||
var testfuncs []*Function
|
||||
for _, f := range expfuncs {
|
||||
if isTest(f.Name(), prefix) && types.IsIdentical(f.Signature, tFunc) {
|
||||
if isTest(f.Name(), prefix) && types.Identical(f.Signature, tFunc) {
|
||||
testfuncs = append(testfuncs, f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,10 +219,10 @@ func (conf *Config) Check(path string, fset *token.FileSet, files []*ast.File, i
|
|||
return pkg, err
|
||||
}
|
||||
|
||||
// IsAssignableTo reports whether a value of type V is assignable to a variable of type T.
|
||||
func IsAssignableTo(V, T Type) bool {
|
||||
// AssignableTo reports whether a value of type V is assignable to a variable of type T.
|
||||
func AssignableTo(V, T Type) bool {
|
||||
x := operand{mode: value, typ: V}
|
||||
return x.isAssignableTo(nil, T) // config not needed for non-constant x
|
||||
return x.assignableTo(nil, T) // config not needed for non-constant x
|
||||
}
|
||||
|
||||
// Implements reports whether a value of type V implements T, as follows:
|
||||
|
|
|
@ -64,7 +64,7 @@ func (check *checker) assignment(x *operand, T Type) bool {
|
|||
// spec: "If a left-hand side is the blank identifier, any typed or
|
||||
// non-constant value except for the predeclared identifier nil may
|
||||
// be assigned to it."
|
||||
return T == nil || x.isAssignableTo(check.conf, T)
|
||||
return T == nil || x.assignableTo(check.conf, T)
|
||||
}
|
||||
|
||||
func (check *checker) initConst(lhs *Const, x *operand) {
|
||||
|
|
|
@ -81,7 +81,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
// spec: "As a special case, append also accepts a first argument assignable
|
||||
// to type []byte with a second argument of string type followed by ... .
|
||||
// This form appends the bytes of the string.
|
||||
if nargs == 2 && call.Ellipsis.IsValid() && x.isAssignableTo(check.conf, NewSlice(universeByte)) {
|
||||
if nargs == 2 && call.Ellipsis.IsValid() && x.assignableTo(check.conf, NewSlice(universeByte)) {
|
||||
arg(x, 1)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
|
@ -89,7 +89,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
if isString(x.typ) {
|
||||
if check.Types != nil {
|
||||
sig := makeSig(S, S, NewSlice(universeByte))
|
||||
sig.isVariadic = true
|
||||
sig.variadic = true
|
||||
check.recordBuiltinType(call.Fun, sig)
|
||||
}
|
||||
x.mode = value
|
||||
|
@ -102,7 +102,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
|
||||
// check general case by creating custom signature
|
||||
sig := makeSig(S, S, NewSlice(T)) // []T required for variadic signature
|
||||
sig.isVariadic = true
|
||||
sig.variadic = true
|
||||
check.arguments(x, call, sig, func(x *operand, i int) {
|
||||
// only evaluate arguments that have not been evaluated before
|
||||
if i < len(alist) {
|
||||
|
@ -209,7 +209,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
return
|
||||
}
|
||||
|
||||
if !IsIdentical(x.typ, y.typ) {
|
||||
if !Identical(x.typ, y.typ) {
|
||||
check.invalidArg(x.pos(), "mismatched types %s and %s", x.typ, y.typ)
|
||||
return
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
return
|
||||
}
|
||||
|
||||
if !IsIdentical(dst, src) {
|
||||
if !Identical(dst, src) {
|
||||
check.invalidArg(x.pos(), "arguments to copy %s and %s have different element types %s and %s", x, &y, dst, src)
|
||||
return
|
||||
}
|
||||
|
@ -309,7 +309,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
|||
return
|
||||
}
|
||||
|
||||
if !x.isAssignableTo(check.conf, m.key) {
|
||||
if !x.assignableTo(check.conf, m.key) {
|
||||
check.invalidArg(x.pos(), "%s is not assignable to %s", x, m.key)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -167,7 +167,7 @@ func (check *checker) arguments(x *operand, call *ast.CallExpr, sig *Signature,
|
|||
passSlice := false
|
||||
if call.Ellipsis.IsValid() {
|
||||
// last argument is of the form x...
|
||||
if sig.isVariadic {
|
||||
if sig.variadic {
|
||||
passSlice = true
|
||||
} else {
|
||||
check.errorf(call.Ellipsis, "cannot use ... in call to non-variadic %s", call.Fun)
|
||||
|
@ -184,7 +184,7 @@ func (check *checker) arguments(x *operand, call *ast.CallExpr, sig *Signature,
|
|||
}
|
||||
|
||||
// check argument count
|
||||
if sig.isVariadic {
|
||||
if sig.variadic {
|
||||
// a variadic function accepts an "empty"
|
||||
// last argument: count one extra
|
||||
n++
|
||||
|
@ -205,7 +205,7 @@ func (check *checker) argument(sig *Signature, i int, x *operand, passSlice bool
|
|||
switch {
|
||||
case i < n:
|
||||
typ = sig.params.vars[i].typ
|
||||
case sig.isVariadic:
|
||||
case sig.variadic:
|
||||
typ = sig.params.vars[n-1].typ
|
||||
if debug {
|
||||
if _, ok := typ.(*Slice); !ok {
|
||||
|
@ -227,7 +227,7 @@ func (check *checker) argument(sig *Signature, i int, x *operand, passSlice bool
|
|||
check.errorf(x.pos(), "cannot use %s as parameter of type %s", x, typ)
|
||||
return
|
||||
}
|
||||
} else if sig.isVariadic && i >= n-1 {
|
||||
} else if sig.variadic && i >= n-1 {
|
||||
// use the variadic parameter slice's element type
|
||||
typ = typ.(*Slice).elem
|
||||
}
|
||||
|
@ -261,7 +261,7 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) {
|
|||
}
|
||||
goto Error
|
||||
}
|
||||
if !exp.IsExported() {
|
||||
if !exp.Exported() {
|
||||
check.errorf(e.Pos(), "%s not exported by package %s", sel, ident)
|
||||
// ok to continue
|
||||
}
|
||||
|
@ -339,7 +339,7 @@ func (check *checker) selector(x *operand, e *ast.SelectorExpr) {
|
|||
x.typ = &Signature{
|
||||
params: NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "", x.typ)}, params...)...),
|
||||
results: sig.results,
|
||||
isVariadic: sig.isVariadic,
|
||||
variadic: sig.variadic,
|
||||
}
|
||||
|
||||
check.addDeclDep(m)
|
||||
|
|
|
@ -18,7 +18,7 @@ func (check *checker) conversion(x *operand, T Type) {
|
|||
case constArg && isConstType(T):
|
||||
// constant conversion
|
||||
switch t := T.Underlying().(*Basic); {
|
||||
case isRepresentableConst(x.val, check.conf, t.kind, &x.val):
|
||||
case representableConst(x.val, check.conf, t.kind, &x.val):
|
||||
ok = true
|
||||
case x.isInteger() && isString(t):
|
||||
codepoint := int64(-1)
|
||||
|
@ -65,7 +65,7 @@ func (check *checker) conversion(x *operand, T Type) {
|
|||
|
||||
func (x *operand) isConvertible(conf *Config, T Type) bool {
|
||||
// "x is assignable to T"
|
||||
if x.isAssignableTo(conf, T) {
|
||||
if x.assignableTo(conf, T) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -73,14 +73,14 @@ func (x *operand) isConvertible(conf *Config, T Type) bool {
|
|||
V := x.typ
|
||||
Vu := V.Underlying()
|
||||
Tu := T.Underlying()
|
||||
if IsIdentical(Vu, Tu) {
|
||||
if Identical(Vu, Tu) {
|
||||
return true
|
||||
}
|
||||
|
||||
// "x's type and T are unnamed pointer types and their pointer base types have identical underlying types"
|
||||
if V, ok := V.(*Pointer); ok {
|
||||
if T, ok := T.(*Pointer); ok {
|
||||
if IsIdentical(V.base.Underlying(), T.base.Underlying()) {
|
||||
if Identical(V.base.Underlying(), T.base.Underlying()) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ func testEval(t *testing.T, pkg *Package, scope *Scope, str string, typ Type, ty
|
|||
// compare types
|
||||
if typ != nil {
|
||||
// we have a type, check identity
|
||||
if !IsIdentical(gotTyp, typ) {
|
||||
if !Identical(gotTyp, typ) {
|
||||
t.Errorf("Eval(%q) got type %s, want %s", str, gotTyp, typ)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -127,7 +127,7 @@ func (check *checker) unary(x *operand, op token.Token) {
|
|||
// Typed constants must be representable in
|
||||
// their type after each constant operation.
|
||||
if isTyped(typ) {
|
||||
check.isRepresentableAs(x, typ)
|
||||
check.representable(x, typ)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -184,14 +184,14 @@ func roundFloat64(x exact.Value) exact.Value {
|
|||
return nil
|
||||
}
|
||||
|
||||
// isRepresentableConst reports whether x can be represented as
|
||||
// representableConst reports whether x can be represented as
|
||||
// value of the given basic type kind and for the configuration
|
||||
// provided (only needed for int/uint sizes).
|
||||
//
|
||||
// If rounded != nil, *rounded is set to the rounded value of x for
|
||||
// representable floating-point values; it is left alone otherwise.
|
||||
// It is ok to provide the addressof the first argument for rounded.
|
||||
func isRepresentableConst(x exact.Value, conf *Config, as BasicKind, rounded *exact.Value) bool {
|
||||
func representableConst(x exact.Value, conf *Config, as BasicKind, rounded *exact.Value) bool {
|
||||
switch x.Kind() {
|
||||
case exact.Unknown:
|
||||
return true
|
||||
|
@ -327,10 +327,10 @@ func isRepresentableConst(x exact.Value, conf *Config, as BasicKind, rounded *ex
|
|||
return false
|
||||
}
|
||||
|
||||
// isRepresentableAs checks that a constant operand is representable in the given basic type.
|
||||
func (check *checker) isRepresentableAs(x *operand, typ *Basic) {
|
||||
// representable checks that a constant operand is representable in the given basic type.
|
||||
func (check *checker) representable(x *operand, typ *Basic) {
|
||||
assert(x.mode == constant)
|
||||
if !isRepresentableConst(x.val, check.conf, typ.kind, &x.val) {
|
||||
if !representableConst(x.val, check.conf, typ.kind, &x.val) {
|
||||
var msg string
|
||||
if isNumeric(x.typ) && isNumeric(typ) {
|
||||
// numeric conversion : error msg
|
||||
|
@ -490,7 +490,7 @@ func (check *checker) convertUntyped(x *operand, target Type) {
|
|||
switch t := target.Underlying().(type) {
|
||||
case *Basic:
|
||||
if x.mode == constant {
|
||||
check.isRepresentableAs(x, t)
|
||||
check.representable(x, t)
|
||||
if x.mode == invalid {
|
||||
return
|
||||
}
|
||||
|
@ -563,7 +563,7 @@ func (check *checker) comparison(x, y *operand, op token.Token) {
|
|||
// spec: "In any comparison, the first operand must be assignable
|
||||
// to the type of the second operand, or vice versa."
|
||||
err := ""
|
||||
if x.isAssignableTo(check.conf, y.typ) || y.isAssignableTo(check.conf, x.typ) {
|
||||
if x.assignableTo(check.conf, y.typ) || y.assignableTo(check.conf, x.typ) {
|
||||
defined := false
|
||||
switch op {
|
||||
case token.EQL, token.NEQ:
|
||||
|
@ -616,7 +616,7 @@ func (check *checker) shift(x, y *operand, op token.Token) {
|
|||
|
||||
// The lhs must be of integer type or be representable
|
||||
// as an integer; otherwise the shift has no chance.
|
||||
if !isInteger(x.typ) && (!untypedx || !isRepresentableConst(x.val, nil, UntypedInt, nil)) {
|
||||
if !isInteger(x.typ) && (!untypedx || !representableConst(x.val, nil, UntypedInt, nil)) {
|
||||
check.invalidOp(x.pos(), "shifted operand %s must be integer", x)
|
||||
x.mode = invalid
|
||||
return
|
||||
|
@ -747,7 +747,7 @@ func (check *checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
|
|||
return
|
||||
}
|
||||
|
||||
if !IsIdentical(x.typ, y.typ) {
|
||||
if !Identical(x.typ, y.typ) {
|
||||
// only report an error if we have valid types
|
||||
// (otherwise we had an error reported elsewhere already)
|
||||
if x.typ != Typ[Invalid] && y.typ != Typ[Invalid] {
|
||||
|
@ -778,7 +778,7 @@ func (check *checker) binary(x *operand, lhs, rhs ast.Expr, op token.Token) {
|
|||
// Typed constants must be representable in
|
||||
// their type after each constant operation.
|
||||
if isTyped(typ) {
|
||||
check.isRepresentableAs(x, typ)
|
||||
check.representable(x, typ)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ var (
|
|||
want = Typ[UntypedNil]
|
||||
}
|
||||
}
|
||||
if want != nil && !IsIdentical(typ, want) {
|
||||
if want != nil && !Identical(typ, want) {
|
||||
t.Errorf("got %s; want %s", typ, want)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -261,7 +261,7 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
|
|||
if static {
|
||||
return m, false
|
||||
}
|
||||
case !IsIdentical(obj.Type(), m.typ):
|
||||
case !Identical(obj.Type(), m.typ):
|
||||
return m, true
|
||||
}
|
||||
}
|
||||
|
@ -285,7 +285,7 @@ func MissingMethod(V Type, T *Interface, static bool) (method *Func, wrongType b
|
|||
return m, false
|
||||
}
|
||||
|
||||
if !IsIdentical(obj.Type(), m.typ) {
|
||||
if !Identical(obj.Type(), m.typ) {
|
||||
return m, true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ type Object interface {
|
|||
Pkg() *Package // nil for objects in the Universe scope and labels
|
||||
Name() string // package local object name
|
||||
Type() Type // object type
|
||||
IsExported() bool // reports whether the name starts with a capital letter
|
||||
Exported() bool // reports whether the name starts with a capital letter
|
||||
Id() string // object id (see Id below)
|
||||
|
||||
// String returns a human-readable string of the object.
|
||||
|
@ -81,7 +81,7 @@ func (obj *object) Pos() token.Pos { return obj.pos }
|
|||
func (obj *object) Pkg() *Package { return obj.pkg }
|
||||
func (obj *object) Name() string { return obj.name }
|
||||
func (obj *object) Type() Type { return obj.typ }
|
||||
func (obj *object) IsExported() bool { return ast.IsExported(obj.name) }
|
||||
func (obj *object) Exported() bool { return ast.IsExported(obj.name) }
|
||||
func (obj *object) Id() string { return Id(obj.pkg, obj.name) }
|
||||
func (obj *object) String() string { panic("abstract") }
|
||||
|
||||
|
@ -98,7 +98,7 @@ func (obj *object) sameId(pkg *Package, name string) bool {
|
|||
return false
|
||||
}
|
||||
// obj.Name == name
|
||||
if obj.IsExported() {
|
||||
if obj.Exported() {
|
||||
return true
|
||||
}
|
||||
// not exported, so packages must be the same (pkg == nil for
|
||||
|
|
|
@ -194,12 +194,12 @@ func (x *operand) isNil() bool {
|
|||
return x.mode == value && x.typ == Typ[UntypedNil]
|
||||
}
|
||||
|
||||
// TODO(gri) The functions operand.isAssignableTo, checker.convertUntyped,
|
||||
// checker.isRepresentable, and checker.assignment are
|
||||
// TODO(gri) The functions operand.assignableTo, checker.convertUntyped,
|
||||
// checker.representable, and checker.assignment are
|
||||
// overlapping in functionality. Need to simplify and clean up.
|
||||
|
||||
// isAssignableTo reports whether x is assignable to a variable of type T.
|
||||
func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
||||
// assignableTo reports whether x is assignable to a variable of type T.
|
||||
func (x *operand) assignableTo(conf *Config, T Type) bool {
|
||||
if x.mode == invalid || T == Typ[Invalid] {
|
||||
return true // avoid spurious errors
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
|||
V := x.typ
|
||||
|
||||
// x's type is identical to T
|
||||
if IsIdentical(V, T) {
|
||||
if Identical(V, T) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
|||
|
||||
// x's type V and T have identical underlying types
|
||||
// and at least one of V or T is not a named type
|
||||
if IsIdentical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
|
||||
if Identical(Vu, Tu) && (!isNamed(V) || !isNamed(T)) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
|||
// type, x's type V and T have identical element types,
|
||||
// and at least one of V or T is not a named type
|
||||
if Vc, ok := Vu.(*Chan); ok && Vc.dir == SendRecv {
|
||||
if Tc, ok := Tu.(*Chan); ok && IsIdentical(Vc.elem, Tc.elem) {
|
||||
if Tc, ok := Tu.(*Chan); ok && Identical(Vc.elem, Tc.elem) {
|
||||
return !isNamed(V) || !isNamed(T)
|
||||
}
|
||||
}
|
||||
|
@ -253,12 +253,12 @@ func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
|||
|
||||
// x is an untyped constant representable by a value of type T
|
||||
// TODO(gri) This is borrowing from checker.convertUntyped and
|
||||
// checker.isRepresentable. Need to clean up.
|
||||
// checker.representable. Need to clean up.
|
||||
if isUntyped(Vu) {
|
||||
switch t := Tu.(type) {
|
||||
case *Basic:
|
||||
if x.mode == constant {
|
||||
return isRepresentableConst(x.val, conf, t.kind, nil)
|
||||
return representableConst(x.val, conf, t.kind, nil)
|
||||
}
|
||||
// The result of a comparison is an untyped boolean,
|
||||
// but may not be a constant.
|
||||
|
@ -279,5 +279,5 @@ func (x *operand) isAssignableTo(conf *Config, T Type) bool {
|
|||
func (x *operand) isInteger() bool {
|
||||
return x.mode == invalid ||
|
||||
isInteger(x.typ) ||
|
||||
x.mode == constant && isRepresentableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
|
||||
x.mode == constant && representableConst(x.val, nil, UntypedInt, nil) // no *Config required for UntypedInt
|
||||
}
|
||||
|
|
|
@ -108,9 +108,9 @@ func hasNil(typ Type) bool {
|
|||
return false
|
||||
}
|
||||
|
||||
// IsIdentical reports whether x and y are identical.
|
||||
func IsIdentical(x, y Type) bool {
|
||||
return isIdenticalInternal(x, y, nil)
|
||||
// Identical reports whether x and y are identical.
|
||||
func Identical(x, y Type) bool {
|
||||
return identicalInternal(x, y, nil)
|
||||
}
|
||||
|
||||
// An ifacePair is a node in a stack of interface type pairs compared for identity.
|
||||
|
@ -123,7 +123,7 @@ func (p *ifacePair) identical(q *ifacePair) bool {
|
|||
return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
|
||||
}
|
||||
|
||||
func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
||||
func identicalInternal(x, y Type, p *ifacePair) bool {
|
||||
if x == y {
|
||||
return true
|
||||
}
|
||||
|
@ -141,13 +141,13 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
// Two array types are identical if they have identical element types
|
||||
// and the same array length.
|
||||
if y, ok := y.(*Array); ok {
|
||||
return x.len == y.len && isIdenticalInternal(x.elem, y.elem, p)
|
||||
return x.len == y.len && identicalInternal(x.elem, y.elem, p)
|
||||
}
|
||||
|
||||
case *Slice:
|
||||
// Two slice types are identical if they have identical element types.
|
||||
if y, ok := y.(*Slice); ok {
|
||||
return isIdenticalInternal(x.elem, y.elem, p)
|
||||
return identicalInternal(x.elem, y.elem, p)
|
||||
}
|
||||
|
||||
case *Struct:
|
||||
|
@ -162,7 +162,7 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
if f.anonymous != g.anonymous ||
|
||||
x.Tag(i) != y.Tag(i) ||
|
||||
!f.sameId(g.pkg, g.name) ||
|
||||
!isIdenticalInternal(f.typ, g.typ, p) {
|
||||
!identicalInternal(f.typ, g.typ, p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -173,7 +173,7 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
case *Pointer:
|
||||
// Two pointer types are identical if they have identical base types.
|
||||
if y, ok := y.(*Pointer); ok {
|
||||
return isIdenticalInternal(x.base, y.base, p)
|
||||
return identicalInternal(x.base, y.base, p)
|
||||
}
|
||||
|
||||
case *Tuple:
|
||||
|
@ -184,7 +184,7 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
if x != nil {
|
||||
for i, v := range x.vars {
|
||||
w := y.vars[i]
|
||||
if !isIdenticalInternal(v.typ, w.typ, p) {
|
||||
if !identicalInternal(v.typ, w.typ, p) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -199,9 +199,9 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
// and either both functions are variadic or neither is. Parameter and result
|
||||
// names are not required to match.
|
||||
if y, ok := y.(*Signature); ok {
|
||||
return x.isVariadic == y.isVariadic &&
|
||||
isIdenticalInternal(x.params, y.params, p) &&
|
||||
isIdenticalInternal(x.results, y.results, p)
|
||||
return x.variadic == y.variadic &&
|
||||
identicalInternal(x.params, y.params, p) &&
|
||||
identicalInternal(x.results, y.results, p)
|
||||
}
|
||||
|
||||
case *Interface:
|
||||
|
@ -247,7 +247,7 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
}
|
||||
for i, f := range a {
|
||||
g := b[i]
|
||||
if f.Id() != g.Id() || !isIdenticalInternal(f.typ, g.typ, q) {
|
||||
if f.Id() != g.Id() || !identicalInternal(f.typ, g.typ, q) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -258,14 +258,14 @@ func isIdenticalInternal(x, y Type, p *ifacePair) bool {
|
|||
case *Map:
|
||||
// Two map types are identical if they have identical key and value types.
|
||||
if y, ok := y.(*Map); ok {
|
||||
return isIdenticalInternal(x.key, y.key, p) && isIdenticalInternal(x.elem, y.elem, p)
|
||||
return identicalInternal(x.key, y.key, p) && identicalInternal(x.elem, y.elem, p)
|
||||
}
|
||||
|
||||
case *Chan:
|
||||
// Two channel types are identical if they have identical value types
|
||||
// and the same direction.
|
||||
if y, ok := y.(*Chan); ok {
|
||||
return x.dir == y.dir && isIdenticalInternal(x.elem, y.elem, p)
|
||||
return x.dir == y.dir && identicalInternal(x.elem, y.elem, p)
|
||||
}
|
||||
|
||||
case *Named:
|
||||
|
|
|
@ -226,7 +226,7 @@ func (check *checker) resolveFiles(files []*ast.File) {
|
|||
for _, obj := range imp.scope.elems {
|
||||
// A package scope may contain non-exported objects,
|
||||
// do not import them!
|
||||
if obj.IsExported() {
|
||||
if obj.Exported() {
|
||||
// Note: This will change each imported object's scope!
|
||||
// May be an issue for type aliases.
|
||||
check.declare(fileScope, nil, obj)
|
||||
|
|
|
@ -183,7 +183,7 @@ L:
|
|||
// complain about duplicate types
|
||||
// TODO(gri) use a type hash to avoid quadratic algorithm
|
||||
for t, pos := range seen {
|
||||
if T == nil && t == nil || T != nil && t != nil && IsIdentical(T, t) {
|
||||
if T == nil && t == nil || T != nil && t != nil && Identical(T, t) {
|
||||
// talk about "case" rather than "type" because of nil case
|
||||
check.errorf(e.Pos(), "duplicate case in type switch")
|
||||
check.errorf(pos, "previous case %s", T)
|
||||
|
|
|
@ -68,7 +68,7 @@ func (m *M) Delete(key types.Type) bool {
|
|||
hash := m.hasher.Hash(key)
|
||||
bucket := m.table[hash]
|
||||
for i, e := range bucket {
|
||||
if e.key != nil && types.IsIdentical(key, e.key) {
|
||||
if e.key != nil && types.Identical(key, e.key) {
|
||||
// We can't compact the bucket as it
|
||||
// would disturb iterators.
|
||||
bucket[i] = entry{}
|
||||
|
@ -86,7 +86,7 @@ func (m *M) Delete(key types.Type) bool {
|
|||
func (m *M) At(key types.Type) interface{} {
|
||||
if m != nil && m.table != nil {
|
||||
for _, e := range m.table[m.hasher.Hash(key)] {
|
||||
if e.key != nil && types.IsIdentical(key, e.key) {
|
||||
if e.key != nil && types.Identical(key, e.key) {
|
||||
return e.value
|
||||
}
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ func (m *M) Set(key types.Type, value interface{}) (prev interface{}) {
|
|||
for i, e := range bucket {
|
||||
if e.key == nil {
|
||||
hole = &bucket[i]
|
||||
} else if types.IsIdentical(key, e.key) {
|
||||
} else if types.Identical(key, e.key) {
|
||||
prev = e.value
|
||||
bucket[i].value = value
|
||||
return
|
||||
|
@ -219,7 +219,7 @@ func MakeHasher() Hasher {
|
|||
}
|
||||
|
||||
// Hash computes a hash value for the given type t such that
|
||||
// IsIdentical(t, t') => Hash(t) == Hash(t').
|
||||
// Identical(t, t') => Hash(t) == Hash(t').
|
||||
func (h Hasher) Hash(t types.Type) uint32 {
|
||||
hash, ok := h.memo[t]
|
||||
if !ok {
|
||||
|
@ -241,7 +241,7 @@ func hashString(s string) uint32 {
|
|||
|
||||
// hashFor computes the hash of t.
|
||||
func (h Hasher) hashFor(t types.Type) uint32 {
|
||||
// See IsIdentical for rationale.
|
||||
// See Identical for rationale.
|
||||
switch t := t.(type) {
|
||||
case *types.Basic:
|
||||
return uint32(t.Kind())
|
||||
|
@ -270,7 +270,7 @@ func (h Hasher) hashFor(t types.Type) uint32 {
|
|||
|
||||
case *types.Signature:
|
||||
var hash uint32 = 9091
|
||||
if t.IsVariadic() {
|
||||
if t.Variadic() {
|
||||
hash *= 8863
|
||||
}
|
||||
return hash + 3*h.hashTuple(t.Params()) + 5*h.hashTuple(t.Results())
|
||||
|
|
|
@ -22,7 +22,7 @@ var (
|
|||
)
|
||||
|
||||
func checkEqualButNotIdentical(t *testing.T, x, y types.Type, comment string) {
|
||||
if !types.IsIdentical(x, y) {
|
||||
if !types.Identical(x, y) {
|
||||
t.Errorf("%s: not equal: %s, %s", comment, x, y)
|
||||
}
|
||||
if x == y {
|
||||
|
@ -113,7 +113,7 @@ func TestTypeMap(t *testing.T) {
|
|||
}
|
||||
|
||||
// Keys().
|
||||
I := types.IsIdentical
|
||||
I := types.Identical
|
||||
switch k := tmap.Keys(); {
|
||||
case I(k[0], tChanInt1) && I(k[1], tPStr1): // ok
|
||||
case I(k[1], tChanInt1) && I(k[0], tPStr1): // ok
|
||||
|
|
|
@ -205,17 +205,17 @@ type Signature struct {
|
|||
recv *Var // nil if not a method
|
||||
params *Tuple // (incoming) parameters from left to right; or nil
|
||||
results *Tuple // (outgoing) results from left to right; or nil
|
||||
isVariadic bool // true if the last parameter's type is of the form ...T
|
||||
variadic bool // true if the last parameter's type is of the form ...T
|
||||
}
|
||||
|
||||
// NewSignature returns a new function type for the given receiver, parameters,
|
||||
// and results, either of which may be nil. If isVariadic is set, the function
|
||||
// and results, either of which may be nil. If variadic is set, the function
|
||||
// is variadic, it must have at least one parameter, and the last parameter
|
||||
// must be of unnamed slice type.
|
||||
func NewSignature(scope *Scope, recv *Var, params, results *Tuple, isVariadic bool) *Signature {
|
||||
func NewSignature(scope *Scope, recv *Var, params, results *Tuple, variadic bool) *Signature {
|
||||
// TODO(gri) Should we rely on the correct (non-nil) incoming scope
|
||||
// or should this function allocate and populate a scope?
|
||||
if isVariadic {
|
||||
if variadic {
|
||||
n := params.Len()
|
||||
if n == 0 {
|
||||
panic("types.NewSignature: variadic function must have at least one parameter")
|
||||
|
@ -224,7 +224,7 @@ func NewSignature(scope *Scope, recv *Var, params, results *Tuple, isVariadic bo
|
|||
panic("types.NewSignature: variadic parameter must be of unnamed slice type")
|
||||
}
|
||||
}
|
||||
return &Signature{scope, recv, params, results, isVariadic}
|
||||
return &Signature{scope, recv, params, results, variadic}
|
||||
}
|
||||
|
||||
// Recv returns the receiver of signature s (if a method), or nil if a
|
||||
|
@ -241,8 +241,8 @@ func (s *Signature) Params() *Tuple { return s.params }
|
|||
// Results returns the results of signature s, or nil.
|
||||
func (s *Signature) Results() *Tuple { return s.results }
|
||||
|
||||
// IsVariadic reports whether the signature s is variadic.
|
||||
func (s *Signature) IsVariadic() bool { return s.isVariadic }
|
||||
// Variadic reports whether the signature s is variadic.
|
||||
func (s *Signature) Variadic() bool { return s.variadic }
|
||||
|
||||
// An Interface represents an interface type.
|
||||
type Interface struct {
|
||||
|
|
|
@ -190,7 +190,7 @@ func WriteType(buf *bytes.Buffer, this *Package, typ Type) {
|
|||
}
|
||||
}
|
||||
|
||||
func writeTuple(buf *bytes.Buffer, this *Package, tup *Tuple, isVariadic bool) {
|
||||
func writeTuple(buf *bytes.Buffer, this *Package, tup *Tuple, variadic bool) {
|
||||
buf.WriteByte('(')
|
||||
if tup != nil {
|
||||
for i, v := range tup.vars {
|
||||
|
@ -202,7 +202,7 @@ func writeTuple(buf *bytes.Buffer, this *Package, tup *Tuple, isVariadic bool) {
|
|||
buf.WriteByte(' ')
|
||||
}
|
||||
typ := v.typ
|
||||
if isVariadic && i == len(tup.vars)-1 {
|
||||
if variadic && i == len(tup.vars)-1 {
|
||||
buf.WriteString("...")
|
||||
typ = typ.(*Slice).elem
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ func writeTuple(buf *bytes.Buffer, this *Package, tup *Tuple, isVariadic bool) {
|
|||
}
|
||||
|
||||
func writeSignature(buf *bytes.Buffer, this *Package, sig *Signature) {
|
||||
writeTuple(buf, this, sig.params, sig.isVariadic)
|
||||
writeTuple(buf, this, sig.params, sig.variadic)
|
||||
|
||||
n := sig.results.Len()
|
||||
if n == 0 {
|
||||
|
|
|
@ -151,7 +151,7 @@ func (check *checker) funcType(recv *ast.FieldList, ftyp *ast.FuncType, def *Nam
|
|||
check.recordScope(ftyp, scope)
|
||||
|
||||
recv_, _ := check.collectParams(scope, recv, false)
|
||||
params, isVariadic := check.collectParams(scope, ftyp.Params, true)
|
||||
params, variadic := check.collectParams(scope, ftyp.Params, true)
|
||||
results, _ := check.collectParams(scope, ftyp.Results, false)
|
||||
|
||||
if len(recv_) > 0 {
|
||||
|
@ -197,7 +197,7 @@ func (check *checker) funcType(recv *ast.FieldList, ftyp *ast.FuncType, def *Nam
|
|||
sig.scope = scope
|
||||
sig.params = NewTuple(params...)
|
||||
sig.results = NewTuple(results...)
|
||||
sig.isVariadic = isVariadic
|
||||
sig.variadic = variadic
|
||||
|
||||
return sig
|
||||
}
|
||||
|
@ -386,7 +386,7 @@ func (check *checker) arrayLength(e ast.Expr) int64 {
|
|||
return n
|
||||
}
|
||||
|
||||
func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, isVariadic bool) {
|
||||
func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicOk bool) (params []*Var, variadic bool) {
|
||||
if list == nil {
|
||||
return
|
||||
}
|
||||
|
@ -396,7 +396,7 @@ func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
|
|||
if t, _ := ftype.(*ast.Ellipsis); t != nil {
|
||||
ftype = t.Elt
|
||||
if variadicOk && i == len(list.List)-1 {
|
||||
isVariadic = true
|
||||
variadic = true
|
||||
} else {
|
||||
check.invalidAST(field.Pos(), "... not permitted")
|
||||
// ignore ... and continue
|
||||
|
@ -421,7 +421,7 @@ func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
|
|||
}
|
||||
|
||||
// For a variadic function, change the last parameter's type from T to []T.
|
||||
if isVariadic && len(params) > 0 {
|
||||
if variadic && len(params) > 0 {
|
||||
last := params[len(params)-1]
|
||||
last.typ = &Slice{elem: last.typ}
|
||||
}
|
||||
|
|
|
@ -206,7 +206,7 @@ func def(obj Object) {
|
|||
}
|
||||
// exported identifiers go into package unsafe
|
||||
scope := Universe
|
||||
if obj.IsExported() {
|
||||
if obj.Exported() {
|
||||
scope = Unsafe.scope
|
||||
// set Pkg field
|
||||
switch obj := obj.(type) {
|
||||
|
|
|
@ -60,19 +60,19 @@ func implements(o *Oracle, qpos *QueryPos) (queryResult, error) {
|
|||
}
|
||||
|
||||
// T interface, U interface
|
||||
if !types.IsIdentical(T, U) {
|
||||
if types.IsAssignableTo(U, T) {
|
||||
if !types.Identical(T, U) {
|
||||
if types.AssignableTo(U, T) {
|
||||
to = append(to, U)
|
||||
}
|
||||
if types.IsAssignableTo(T, U) {
|
||||
if types.AssignableTo(T, U) {
|
||||
from = append(from, U)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// T interface, U concrete
|
||||
if types.IsAssignableTo(U, T) {
|
||||
if types.AssignableTo(U, T) {
|
||||
to = append(to, U)
|
||||
} else if pU := types.NewPointer(U); types.IsAssignableTo(pU, T) {
|
||||
} else if pU := types.NewPointer(U); types.AssignableTo(pU, T) {
|
||||
to = append(to, pU)
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +82,9 @@ func implements(o *Oracle, qpos *QueryPos) (queryResult, error) {
|
|||
}
|
||||
|
||||
// T concrete, U interface
|
||||
if types.IsAssignableTo(T, U) {
|
||||
if types.AssignableTo(T, U) {
|
||||
from = append(from, U)
|
||||
} else if pT := types.NewPointer(T); types.IsAssignableTo(pT, U) {
|
||||
} else if pT := types.NewPointer(T); types.AssignableTo(pT, U) {
|
||||
fromPtr = append(fromPtr, U)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ func peers(o *Oracle, qpos *QueryPos) (queryResult, error) {
|
|||
o.ptaConfig.AddQuery(queryOp.ch)
|
||||
i := 0
|
||||
for _, op := range ops {
|
||||
if types.IsIdentical(op.ch.Type().Underlying().(*types.Chan).Elem(), queryElemType) {
|
||||
if types.Identical(op.ch.Type().Underlying().(*types.Chan).Elem(), queryElemType) {
|
||||
o.ptaConfig.AddQuery(op.ch)
|
||||
ops[i] = op
|
||||
i++
|
||||
|
|
Loading…
Reference in New Issue