mirror of
https://github.com/golang/go
synced 2024-11-19 18:44:41 -07:00
go/types: add lookup method to context and factor out LookupParent calls
R=go1.11 Also: Moved Checker.pos field into context where it belongs. This is a cleanup/code factoring. For #22992. Change-Id: If9d4f0af537cb181f73735e709ebc8258b2a1378 Reviewed-on: https://go-review.googlesource.com/83017 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
dd448957fd
commit
574fc66b17
@ -314,7 +314,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
|
||||
// can only appear in qualified identifiers which are mapped to
|
||||
// selector expressions.
|
||||
if ident, ok := e.X.(*ast.Ident); ok {
|
||||
_, obj := check.scope.LookupParent(ident.Name, check.pos)
|
||||
obj := check.lookup(ident.Name)
|
||||
if pname, _ := obj.(*PkgName); pname != nil {
|
||||
assert(pname.pkg == check.pkg)
|
||||
check.recordUse(ident, pname)
|
||||
|
@ -51,12 +51,19 @@ type funcInfo struct {
|
||||
type context struct {
|
||||
decl *declInfo // package-level declaration whose init expression/function body is checked
|
||||
scope *Scope // top-most scope for lookups
|
||||
pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
|
||||
iota constant.Value // value of iota in a constant declaration; nil otherwise
|
||||
sig *Signature // function signature if inside a function; nil otherwise
|
||||
hasLabel bool // set if a function makes use of labels (only ~1% of functions); unused outside functions
|
||||
hasCallOrRecv bool // set if an expression contains a function call or channel receive operation
|
||||
}
|
||||
|
||||
// lookup looks up name in the current context and returns the matching object, or nil.
|
||||
func (ctxt *context) lookup(name string) Object {
|
||||
_, obj := ctxt.scope.LookupParent(name, ctxt.pos)
|
||||
return obj
|
||||
}
|
||||
|
||||
// An importKey identifies an imported package by import path and source directory
|
||||
// (directory containing the file containing the import). In practice, the directory
|
||||
// may always be the same, or may not matter. Given an (import path, directory), an
|
||||
@ -95,7 +102,6 @@ type Checker struct {
|
||||
// context within which the current object is type-checked
|
||||
// (valid only for the duration of type-checking a specific object)
|
||||
context
|
||||
pos token.Pos // if valid, identifiers are looked up as if at position pos (used by Eval)
|
||||
|
||||
// debugging
|
||||
indent int // indentation for tracing
|
||||
|
@ -288,7 +288,7 @@ func (check *Checker) infoFromTypeName(name *ast.Ident, path []*TypeName) *iface
|
||||
|
||||
typenameLoop:
|
||||
// name must be a type name denoting a type whose underlying type is an interface
|
||||
_, obj := check.scope.LookupParent(name.Name, check.pos /* use Eval position, if any */)
|
||||
obj := check.lookup(name.Name)
|
||||
if obj == nil {
|
||||
return nil
|
||||
}
|
||||
@ -363,7 +363,7 @@ func (check *Checker) infoFromQualifiedTypeName(qname *ast.SelectorExpr) *ifaceI
|
||||
if name == nil {
|
||||
return nil
|
||||
}
|
||||
_, obj1 := check.scope.LookupParent(name.Name, check.pos /* use Eval position, if any */)
|
||||
obj1 := check.lookup(name.Name)
|
||||
if obj1 == nil {
|
||||
return nil
|
||||
}
|
||||
|
@ -440,7 +440,7 @@ func (check *Checker) stmt(ctxt stmtContext, s ast.Stmt) {
|
||||
// list in a "return" statement if a different entity (constant, type, or variable)
|
||||
// with the same name as a result parameter is in scope at the place of the return."
|
||||
for _, obj := range res.vars {
|
||||
if _, alt := check.scope.LookupParent(obj.name, check.pos); alt != nil && alt != obj {
|
||||
if alt := check.lookup(obj.name); alt != nil && alt != obj {
|
||||
check.errorf(s.Pos(), "result parameter %s not in scope at return", obj.name)
|
||||
check.errorf(alt.Pos(), "\tinner declaration of %s", obj)
|
||||
// ok to continue
|
||||
|
@ -22,6 +22,8 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeNa
|
||||
x.mode = invalid
|
||||
x.expr = e
|
||||
|
||||
// Note that we cannot use check.lookup here because the returned scope
|
||||
// may be different from obj.Parent(). See also Scope.LookupParent doc.
|
||||
scope, obj := check.scope.LookupParent(e.Name, check.pos)
|
||||
if obj == nil {
|
||||
if e.Name == "_" {
|
||||
|
Loading…
Reference in New Issue
Block a user