mirror of
https://github.com/golang/go
synced 2024-11-18 18:44:42 -07:00
go.tools/go/types: call Context.Ident for selectors
Fixes golang/go#5669. R=adonovan CC=golang-dev https://golang.org/cl/9714045
This commit is contained in:
parent
73612ddbfd
commit
63f3103b6f
@ -64,9 +64,9 @@ type Context struct {
|
||||
// filename:line:column: message
|
||||
Error func(err error)
|
||||
|
||||
// If Ident != nil, it is called for each identifier id in the AST
|
||||
// (including package names, dots "." of dot-imports, and blank "_"
|
||||
// identifiers), and obj is the object denoted by ident. The object
|
||||
// If Ident != nil, it is called for each identifier id that is type-
|
||||
// checked (including package names, dots "." of dot-imports, and blank
|
||||
// "_" identifiers), and obj is the object denoted by ident. The object
|
||||
// is nil if the identifier was not declared. Ident may be called
|
||||
// multiple times for the same identifier (e.g., for typed variable
|
||||
// declarations with multiple initialization statements); but Ident
|
||||
|
@ -1328,9 +1328,10 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
|
||||
check.invalidOp(e.Pos(), "%s has no single field or method %s", x, sel)
|
||||
goto Error
|
||||
}
|
||||
check.callIdent(e.Sel, res.obj)
|
||||
if x.mode == typexpr {
|
||||
// method expression
|
||||
sig, ok := res.typ.(*Signature)
|
||||
sig, ok := res.obj.Type().(*Signature)
|
||||
if !ok {
|
||||
check.invalidOp(e.Pos(), "%s has no method %s", x, sel)
|
||||
goto Error
|
||||
@ -1352,7 +1353,7 @@ func (check *checker) rawExpr(x *operand, e ast.Expr, hint Type, iota int, cycle
|
||||
} else {
|
||||
// regular selector
|
||||
x.mode = res.mode
|
||||
x.typ = res.typ
|
||||
x.typ = res.obj.Type()
|
||||
}
|
||||
|
||||
case *ast.IndexExpr:
|
||||
|
@ -209,8 +209,8 @@ func (x *operand) isInteger() bool {
|
||||
// lookupResult represents the result of a struct field/method lookup.
|
||||
type lookupResult struct {
|
||||
mode operandMode
|
||||
typ Type
|
||||
index []int // field index sequence; nil for methods
|
||||
obj Object // *Field or *Func; valid if mode != invalid
|
||||
index []int // field index sequence; nil for methods
|
||||
}
|
||||
|
||||
type embeddedType struct {
|
||||
@ -232,7 +232,7 @@ func lookupFieldBreadthFirst(list []embeddedType, pkg *Package, name string) (re
|
||||
var next []embeddedType
|
||||
|
||||
// potentialMatch is invoked every time a match is found.
|
||||
potentialMatch := func(multiples bool, mode operandMode, typ Type) bool {
|
||||
potentialMatch := func(multiples bool, mode operandMode, obj Object) bool {
|
||||
if multiples || res.mode != invalid {
|
||||
// name appeared already at this level - annihilate
|
||||
res.mode = invalid
|
||||
@ -240,7 +240,7 @@ func lookupFieldBreadthFirst(list []embeddedType, pkg *Package, name string) (re
|
||||
}
|
||||
// first appearance of name
|
||||
res.mode = mode
|
||||
res.typ = typ
|
||||
res.obj = obj
|
||||
res.index = nil
|
||||
return true
|
||||
}
|
||||
@ -267,7 +267,7 @@ func lookupFieldBreadthFirst(list []embeddedType, pkg *Package, name string) (re
|
||||
if obj := typ.methods.Lookup(pkg, name); obj != nil {
|
||||
m := obj.(*Func)
|
||||
assert(m.typ != nil)
|
||||
if !potentialMatch(e.multiples, value, m.typ) {
|
||||
if !potentialMatch(e.multiples, value, m) {
|
||||
return // name collision
|
||||
}
|
||||
}
|
||||
@ -282,7 +282,7 @@ func lookupFieldBreadthFirst(list []embeddedType, pkg *Package, name string) (re
|
||||
f := obj.(*Field)
|
||||
if f.isMatch(pkg, name) {
|
||||
assert(f.typ != nil)
|
||||
if !potentialMatch(e.multiples, variable, f.typ) {
|
||||
if !potentialMatch(e.multiples, variable, f) {
|
||||
return // name collision
|
||||
}
|
||||
var index []int
|
||||
@ -317,7 +317,7 @@ func lookupFieldBreadthFirst(list []embeddedType, pkg *Package, name string) (re
|
||||
if obj := t.methods.Lookup(pkg, name); obj != nil {
|
||||
m := obj.(*Func)
|
||||
assert(m.typ != nil)
|
||||
if !potentialMatch(e.multiples, value, m.typ) {
|
||||
if !potentialMatch(e.multiples, value, m) {
|
||||
return // name collision
|
||||
}
|
||||
}
|
||||
@ -367,7 +367,7 @@ func lookupField(typ Type, pkg *Package, name string) lookupResult {
|
||||
if obj := t.methods.Lookup(pkg, name); obj != nil {
|
||||
m := obj.(*Func)
|
||||
assert(m.typ != nil)
|
||||
return lookupResult{value, m.typ, nil}
|
||||
return lookupResult{value, m, nil}
|
||||
}
|
||||
typ = t.underlying
|
||||
}
|
||||
@ -381,7 +381,7 @@ func lookupField(typ Type, pkg *Package, name string) lookupResult {
|
||||
for i, obj := range t.fields.entries {
|
||||
f := obj.(*Field)
|
||||
if f.isMatch(pkg, name) {
|
||||
return lookupResult{variable, f.typ, []int{i}}
|
||||
return lookupResult{variable, f, []int{i}}
|
||||
}
|
||||
if f.anonymous {
|
||||
// Possible optimization: If the embedded type
|
||||
@ -402,7 +402,7 @@ func lookupField(typ Type, pkg *Package, name string) lookupResult {
|
||||
if obj := t.methods.Lookup(pkg, name); obj != nil {
|
||||
m := obj.(*Func)
|
||||
assert(m.typ != nil)
|
||||
return lookupResult{value, m.typ, nil}
|
||||
return lookupResult{value, m, nil}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@ func missingMethod(typ Type, T *Interface) (method *Func, wrongType bool) {
|
||||
for _, obj := range T.methods.entries {
|
||||
m := obj.(*Func)
|
||||
res := lookupField(ityp, m.pkg, m.name) // TODO(gri) no need to go via lookupField
|
||||
if res.mode != invalid && !IsIdentical(res.typ, m.typ) {
|
||||
if res.mode != invalid && !IsIdentical(res.obj.Type(), m.typ) {
|
||||
return m, true
|
||||
}
|
||||
}
|
||||
@ -303,7 +303,7 @@ func missingMethod(typ Type, T *Interface) (method *Func, wrongType bool) {
|
||||
if res.mode == invalid {
|
||||
return m, false
|
||||
}
|
||||
if !IsIdentical(res.typ, m.typ) {
|
||||
if !IsIdentical(res.obj.Type(), m.typ) {
|
||||
return m, true
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ var sources = []string{
|
||||
type I interface{ m() }
|
||||
var _ = T{a: 1, b: 2, c: 3}
|
||||
func (_ T) m() {}
|
||||
var i I
|
||||
var _ = i.m
|
||||
`,
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user