go.tools/go/types: internal cleanup (resolve a TODO)
LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/59560046
This commit is contained in:
parent
5351a1ccd2
commit
c37c5f6f46
|
@ -357,7 +357,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
||||||
// make(T, n, m)
|
// make(T, n, m)
|
||||||
// (no argument evaluated yet)
|
// (no argument evaluated yet)
|
||||||
arg0 := call.Args[0]
|
arg0 := call.Args[0]
|
||||||
T := check.typ(arg0, nil, nil)
|
T := check.typ(arg0)
|
||||||
if T == Typ[Invalid] {
|
if T == Typ[Invalid] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -395,7 +395,7 @@ func (check *checker) builtin(x *operand, call *ast.CallExpr, id builtinId) (_ b
|
||||||
case _New:
|
case _New:
|
||||||
// new(T)
|
// new(T)
|
||||||
// (no argument evaluated yet)
|
// (no argument evaluated yet)
|
||||||
T := check.typ(call.Args[0], nil, nil)
|
T := check.typ(call.Args[0])
|
||||||
if T == Typ[Invalid] {
|
if T == Typ[Invalid] {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,7 +107,7 @@ func (check *checker) constDecl(obj *Const, typ, init ast.Expr) {
|
||||||
|
|
||||||
// determine type, if any
|
// determine type, if any
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
t := check.typ(typ, nil, nil)
|
t := check.typ(typ)
|
||||||
if !isConstType(t) {
|
if !isConstType(t) {
|
||||||
check.errorf(typ.Pos(), "invalid constant type %s", t)
|
check.errorf(typ.Pos(), "invalid constant type %s", t)
|
||||||
obj.typ = Typ[Invalid]
|
obj.typ = Typ[Invalid]
|
||||||
|
@ -138,7 +138,7 @@ func (check *checker) varDecl(obj *Var, lhs []*Var, typ, init ast.Expr) {
|
||||||
|
|
||||||
// determine type, if any
|
// determine type, if any
|
||||||
if typ != nil {
|
if typ != nil {
|
||||||
obj.typ = check.typ(typ, nil, nil)
|
obj.typ = check.typ(typ)
|
||||||
}
|
}
|
||||||
|
|
||||||
// check initialization
|
// check initialization
|
||||||
|
@ -205,7 +205,7 @@ func (check *checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, path []*
|
||||||
obj.typ = named // make sure recursive type declarations terminate
|
obj.typ = named // make sure recursive type declarations terminate
|
||||||
|
|
||||||
// determine underlying type of named
|
// determine underlying type of named
|
||||||
check.typ(typ, named, append(path, obj))
|
check.typExpr(typ, named, append(path, obj))
|
||||||
|
|
||||||
// The underlying type of named may be itself a named type that is
|
// The underlying type of named may be itself a named type that is
|
||||||
// incomplete:
|
// incomplete:
|
||||||
|
|
|
@ -959,7 +959,7 @@ func (check *checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *ast.FuncLit:
|
case *ast.FuncLit:
|
||||||
if sig, ok := check.typ(e.Type, nil, nil).(*Signature); ok {
|
if sig, ok := check.typ(e.Type).(*Signature); ok {
|
||||||
// Anonymous functions are considered part of the
|
// Anonymous functions are considered part of the
|
||||||
// init expression/func declaration which contains
|
// init expression/func declaration which contains
|
||||||
// them: use existing package-level declaration info.
|
// them: use existing package-level declaration info.
|
||||||
|
@ -983,12 +983,12 @@ func (check *checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||||
// We have an "open" [...]T array type.
|
// We have an "open" [...]T array type.
|
||||||
// Create a new ArrayType with unknown length (-1)
|
// Create a new ArrayType with unknown length (-1)
|
||||||
// and finish setting it up after analyzing the literal.
|
// and finish setting it up after analyzing the literal.
|
||||||
typ = &Array{len: -1, elem: check.typ(atyp.Elt, nil, nil)}
|
typ = &Array{len: -1, elem: check.typ(atyp.Elt)}
|
||||||
openArray = true
|
openArray = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
typ = check.typ(e.Type, nil, nil)
|
typ = check.typ(e.Type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if typ == nil {
|
if typ == nil {
|
||||||
|
@ -1309,7 +1309,7 @@ func (check *checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||||
check.invalidAST(e.Pos(), "use of .(type) outside type switch")
|
check.invalidAST(e.Pos(), "use of .(type) outside type switch")
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
T := check.typ(e.Type, nil, nil)
|
T := check.typ(e.Type)
|
||||||
if T == Typ[Invalid] {
|
if T == Typ[Invalid] {
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
@ -1365,7 +1365,7 @@ func (check *checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||||
case *ast.ArrayType, *ast.StructType, *ast.FuncType,
|
case *ast.ArrayType, *ast.StructType, *ast.FuncType,
|
||||||
*ast.InterfaceType, *ast.MapType, *ast.ChanType:
|
*ast.InterfaceType, *ast.MapType, *ast.ChanType:
|
||||||
x.mode = typexpr
|
x.mode = typexpr
|
||||||
x.typ = check.typ(e, nil, nil)
|
x.typ = check.typ(e)
|
||||||
// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
|
// Note: rawExpr (caller of exprInternal) will call check.recordTypeAndValue
|
||||||
// even though check.typ has already called it. This is fine as both
|
// even though check.typ has already called it. This is fine as both
|
||||||
// times the same expression and type are recorded. It is also not a
|
// times the same expression and type are recorded. It is also not a
|
||||||
|
|
|
@ -112,13 +112,13 @@ func (check *checker) ident(x *operand, e *ast.Ident, def *Named, path []*TypeNa
|
||||||
x.typ = typ
|
x.typ = typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// typ type-checks the type expression e and returns its type, or Typ[Invalid].
|
// typExpr type-checks the type expression e and returns its type, or Typ[Invalid].
|
||||||
// If def != nil, e is the type specification for the named type def, declared
|
// If def != nil, e is the type specification for the named type def, declared
|
||||||
// in a type declaration, and def.underlying will be set to the type of e before
|
// in a type declaration, and def.underlying will be set to the type of e before
|
||||||
// any components of e are type-checked. Path contains the path of named types
|
// any components of e are type-checked. Path contains the path of named types
|
||||||
// referring to this type.
|
// referring to this type.
|
||||||
//
|
//
|
||||||
func (check *checker) typ(e ast.Expr, def *Named, path []*TypeName) (T Type) {
|
func (check *checker) typExpr(e ast.Expr, def *Named, path []*TypeName) (T Type) {
|
||||||
if trace {
|
if trace {
|
||||||
check.trace(e.Pos(), "%s", e)
|
check.trace(e.Pos(), "%s", e)
|
||||||
check.indent++
|
check.indent++
|
||||||
|
@ -128,15 +128,16 @@ func (check *checker) typ(e ast.Expr, def *Named, path []*TypeName) (T Type) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
T = check.typInternal(e, def, path)
|
T = check.typExprInternal(e, def, path)
|
||||||
assert(isTyped(T))
|
assert(isTyped(T))
|
||||||
check.recordTypeAndValue(e, T, nil)
|
check.recordTypeAndValue(e, T, nil)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(gri) provide a convenience function (say, check.typExpr) that works
|
func (check *checker) typ(e ast.Expr) Type {
|
||||||
// as check.typ but only takes an ast.Expr and assumes nil for def and cycle.
|
return check.typExpr(e, nil, nil)
|
||||||
|
}
|
||||||
|
|
||||||
// funcType type-checks a function or method type and returns its signature.
|
// 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, recv *ast.FieldList, ftyp *ast.FuncType) *Signature {
|
||||||
|
@ -195,10 +196,10 @@ func (check *checker) funcType(sig *Signature, recv *ast.FieldList, ftyp *ast.Fu
|
||||||
return sig
|
return sig
|
||||||
}
|
}
|
||||||
|
|
||||||
// typInternal drives type checking of types.
|
// typExprInternal drives type checking of types.
|
||||||
// Must only be called by typ.
|
// Must only be called by typExpr.
|
||||||
//
|
//
|
||||||
func (check *checker) typInternal(e ast.Expr, def *Named, path []*TypeName) Type {
|
func (check *checker) typExprInternal(e ast.Expr, def *Named, path []*TypeName) Type {
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
case *ast.BadExpr:
|
case *ast.BadExpr:
|
||||||
// ignore - error reported before
|
// ignore - error reported before
|
||||||
|
@ -238,20 +239,20 @@ func (check *checker) typInternal(e ast.Expr, def *Named, path []*TypeName) Type
|
||||||
}
|
}
|
||||||
|
|
||||||
case *ast.ParenExpr:
|
case *ast.ParenExpr:
|
||||||
return check.typ(e.X, def, path)
|
return check.typExpr(e.X, def, path)
|
||||||
|
|
||||||
case *ast.ArrayType:
|
case *ast.ArrayType:
|
||||||
if e.Len != nil {
|
if e.Len != nil {
|
||||||
typ := new(Array)
|
typ := new(Array)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
typ.len = check.arrayLength(e.Len)
|
typ.len = check.arrayLength(e.Len)
|
||||||
typ.elem = check.typ(e.Elt, nil, path)
|
typ.elem = check.typExpr(e.Elt, nil, path)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
typ := new(Slice)
|
typ := new(Slice)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
typ.elem = check.typ(e.Elt, nil, nil)
|
typ.elem = check.typ(e.Elt)
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -264,7 +265,7 @@ func (check *checker) typInternal(e ast.Expr, def *Named, path []*TypeName) Type
|
||||||
case *ast.StarExpr:
|
case *ast.StarExpr:
|
||||||
typ := new(Pointer)
|
typ := new(Pointer)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
typ.base = check.typ(e.X, nil, nil)
|
typ.base = check.typ(e.X)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
|
@ -283,8 +284,8 @@ func (check *checker) typInternal(e ast.Expr, def *Named, path []*TypeName) Type
|
||||||
typ := new(Map)
|
typ := new(Map)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
|
|
||||||
typ.key = check.typ(e.Key, nil, nil)
|
typ.key = check.typ(e.Key)
|
||||||
typ.elem = check.typ(e.Value, nil, nil)
|
typ.elem = check.typ(e.Value)
|
||||||
|
|
||||||
// spec: "The comparison operators == and != must be fully defined
|
// spec: "The comparison operators == and != must be fully defined
|
||||||
// for operands of the key type; thus the key type must not be a
|
// for operands of the key type; thus the key type must not be a
|
||||||
|
@ -318,7 +319,7 @@ func (check *checker) typInternal(e ast.Expr, def *Named, path []*TypeName) Type
|
||||||
}
|
}
|
||||||
|
|
||||||
typ.dir = dir
|
typ.dir = dir
|
||||||
typ.elem = check.typ(e.Value, nil, nil)
|
typ.elem = check.typ(e.Value)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -392,7 +393,7 @@ func (check *checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
|
||||||
// ignore ... and continue
|
// ignore ... and continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ := check.typ(ftype, nil, nil)
|
typ := check.typ(ftype)
|
||||||
// The parser ensures that f.Tag is nil and we don't
|
// The parser ensures that f.Tag is nil and we don't
|
||||||
// care if a constructed AST contains a non-nil tag.
|
// care if a constructed AST contains a non-nil tag.
|
||||||
if len(field.Names) > 0 {
|
if len(field.Names) > 0 {
|
||||||
|
@ -499,7 +500,7 @@ func (check *checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, d
|
||||||
|
|
||||||
for _, e := range embedded {
|
for _, e := range embedded {
|
||||||
pos := e.Pos()
|
pos := e.Pos()
|
||||||
typ := check.typ(e, nil, path)
|
typ := check.typExpr(e, nil, path)
|
||||||
named, _ := typ.(*Named)
|
named, _ := typ.(*Named)
|
||||||
if named == nil {
|
if named == nil {
|
||||||
if typ != Typ[Invalid] {
|
if typ != Typ[Invalid] {
|
||||||
|
@ -534,7 +535,7 @@ func (check *checker) interfaceType(iface *Interface, ityp *ast.InterfaceType, d
|
||||||
|
|
||||||
for i, m := range iface.methods {
|
for i, m := range iface.methods {
|
||||||
expr := signatures[i]
|
expr := signatures[i]
|
||||||
typ := check.typ(expr, nil, nil)
|
typ := check.typ(expr)
|
||||||
sig, _ := typ.(*Signature)
|
sig, _ := typ.(*Signature)
|
||||||
if sig == nil {
|
if sig == nil {
|
||||||
if typ != Typ[Invalid] {
|
if typ != Typ[Invalid] {
|
||||||
|
@ -622,7 +623,7 @@ func (check *checker) structType(styp *Struct, e *ast.StructType, path []*TypeNa
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range list.List {
|
for _, f := range list.List {
|
||||||
typ = check.typ(f.Type, nil, path)
|
typ = check.typExpr(f.Type, nil, path)
|
||||||
tag = check.tag(f.Tag)
|
tag = check.tag(f.Tag)
|
||||||
if len(f.Names) > 0 {
|
if len(f.Names) > 0 {
|
||||||
// named fields
|
// named fields
|
||||||
|
|
Loading…
Reference in New Issue