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:
Robert Griesemer 2014-02-04 11:06:00 -08:00
parent 5351a1ccd2
commit c37c5f6f46
4 changed files with 30 additions and 29 deletions

View File

@ -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
} }

View File

@ -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:

View File

@ -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

View File

@ -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