1
0
mirror of https://github.com/golang/go synced 2024-11-18 14:14:46 -07:00

go.tools/go/types: handle all receiver errors in go/types

Pending parser change in CL 123010044.

LGTM=adonovan
R=adonovan
CC=golang-codereviews
https://golang.org/cl/125830043
This commit is contained in:
Robert Griesemer 2014-08-07 12:45:28 -07:00
parent 3bbc63016b
commit 8ce35843de
2 changed files with 33 additions and 12 deletions

View File

@ -80,12 +80,24 @@ type T5 interface {
func (T5 /* ERROR "invalid receiver" */ ) m1() {}
func (T5 /* ERROR "invalid receiver" */ ) m2() {}
// Methods associated with a named pointer type.
type ptr *int
func (ptr /* ERROR "invalid receiver" */ ) _() {}
func (* /* ERROR "invalid receiver" */ ptr) _() {}
// Methods with zero or multiple receivers.
func ( /* ERROR "missing receiver" */ ) _() {}
func (T3, * /* ERROR "exactly one receiver" */ T3) _() {}
func (T3, T3, T3 /* ERROR "exactly one receiver" */ ) _() {}
func (a, b /* ERROR "exactly one receiver" */ T3) _() {}
func (a, b, c /* ERROR "exactly one receiver" */ T3) _() {}
// Methods associated with non-local or unnamed types.
func (int /* ERROR "invalid receiver" */ ) m() {}
func ([ /* ERROR "identifier" */ ]int) m() {}
func (time /* ERROR "identifier" */ .Time) m() {}
func (*time /* ERROR "identifier" */ .Time) m() {}
func (x interface /* ERROR "identifier" */ {}) m() {}
func ([ /* ERROR "invalid receiver" */ ]int) m() {}
func (time /* ERROR "invalid receiver" */ .Time) m() {}
func (* /* ERROR "invalid receiver" */ time.Time) m() {}
func (x /* ERROR "invalid receiver" */ interface{}) m() {}
// Unsafe.Pointer is treated like a pointer when used as receiver type.
type UP unsafe.Pointer

View File

@ -139,21 +139,30 @@ func (check *Checker) typ(e ast.Expr) Type {
}
// funcType type-checks a function or method type and returns its signature.
func (check *Checker) funcType(sig *Signature, recv *ast.FieldList, ftyp *ast.FuncType) *Signature {
func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) *Signature {
scope := NewScope(check.scope, "function")
check.recordScope(ftyp, scope)
recv_, _ := check.collectParams(scope, recv, false)
recvList, _ := check.collectParams(scope, recvPar, false)
params, variadic := check.collectParams(scope, ftyp.Params, true)
results, _ := check.collectParams(scope, ftyp.Results, false)
if len(recv_) > 0 {
// There must be exactly one receiver.
if len(recv_) > 1 {
check.invalidAST(recv_[1].Pos(), "method must have exactly one receiver")
// ok to continue
if recvPar != nil {
// recv parameter list present (may be empty)
// spec: "The receiver is specified via an extra parameter section preceeding the
// method name. That parameter section must declare a single parameter, the receiver."
var recv *Var
switch len(recvList) {
case 0:
check.error(recvPar.Pos(), "method is missing receiver")
recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
default:
// more than one receiver
check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
fallthrough // continue with first receiver
case 1:
recv = recvList[0]
}
recv := recv_[0]
// spec: "The receiver type must be of the form T or *T where T is a type name."
// (ignore invalid types - error was reported before)
if t, _ := deref(recv.typ); t != Typ[Invalid] {