mirror of https://github.com/golang/go.git
go/types: better names for internal helper functions (cleanup)
Internal helper functions for type-checking type expressions were renamed to make it clearer when they should be used: typExpr (w/o def) -> typ typExpr (w/ def) -> definedType typ -> indirectType typExprInternal -> typInternal The rename emphasizes that in most cases Checker.typ should be used to compute the types.Type from an ast.Type. If the type is defined, definedType should be used. For composite type elements which are not "inlined" in memory, indirectType should be used. In the process, implicitly changed several uses of indirectType (old: typ) to typ (old: typExpr) by not changing the respective function call source. These implicit changes are ok in those places because either call is fine where we are not concerned about composite type elements. But using typ (old: typExpr) is more efficient than using indirectType (old: typ). Change-Id: I4ad14d5357c5f94b6f1c33173de575c4cd05c703 Reviewed-on: https://go-review.googlesource.com/130595 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
43469ddf74
commit
770e37d249
|
|
@ -388,7 +388,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.typExpr(typ, nil)
|
t := check.typ(typ)
|
||||||
if !isConstType(t) {
|
if !isConstType(t) {
|
||||||
// don't report an error if the type is an invalid C (defined) type
|
// don't report an error if the type is an invalid C (defined) type
|
||||||
// (issue #22090)
|
// (issue #22090)
|
||||||
|
|
@ -414,7 +414,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.typExpr(typ, nil)
|
obj.typ = check.typ(typ)
|
||||||
// We cannot spread the type to all lhs variables if there
|
// We cannot spread the type to all lhs variables if there
|
||||||
// are more than one since that would mark them as checked
|
// are more than one since that would mark them as checked
|
||||||
// (see Checker.objDecl) and the assignment of init exprs,
|
// (see Checker.objDecl) and the assignment of init exprs,
|
||||||
|
|
@ -495,7 +495,7 @@ func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bo
|
||||||
if alias {
|
if alias {
|
||||||
|
|
||||||
obj.typ = Typ[Invalid]
|
obj.typ = Typ[Invalid]
|
||||||
obj.typ = check.typExpr(typ, nil)
|
obj.typ = check.typ(typ)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
|
@ -504,7 +504,7 @@ func (check *Checker) typeDecl(obj *TypeName, typ ast.Expr, def *Named, alias bo
|
||||||
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.typExpr(typ, named)
|
check.definedType(typ, named)
|
||||||
|
|
||||||
// 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:
|
||||||
|
|
|
||||||
|
|
@ -1064,7 +1064,7 @@ func (check *Checker) exprInternal(x *operand, e ast.Expr, hint Type) exprKind {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ = check.typExpr(e.Type, nil)
|
typ = check.typ(e.Type)
|
||||||
base = typ
|
base = typ
|
||||||
|
|
||||||
case hint != nil:
|
case hint != nil:
|
||||||
|
|
@ -1439,7 +1439,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.typExpr(e.Type, nil)
|
T := check.typ(e.Type)
|
||||||
if T == Typ[Invalid] {
|
if T == Typ[Invalid] {
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -103,12 +103,17 @@ func (check *Checker) ident(x *operand, e *ast.Ident, def *Named) {
|
||||||
x.typ = typ
|
x.typ = typ
|
||||||
}
|
}
|
||||||
|
|
||||||
// typExpr type-checks the type expression e and returns its type, or Typ[Invalid].
|
// typ 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
|
func (check *Checker) typ(e ast.Expr) Type {
|
||||||
|
return check.definedType(e, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// definedType is like typ but also accepts a type name def.
|
||||||
|
// If def != nil, e is the type specification for the defined 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.
|
// any components of e are type-checked.
|
||||||
//
|
//
|
||||||
func (check *Checker) typExpr(e ast.Expr, def *Named) (T Type) {
|
func (check *Checker) definedType(e ast.Expr, def *Named) (T Type) {
|
||||||
if trace {
|
if trace {
|
||||||
check.trace(e.Pos(), "%s", e)
|
check.trace(e.Pos(), "%s", e)
|
||||||
check.indent++
|
check.indent++
|
||||||
|
|
@ -118,23 +123,21 @@ func (check *Checker) typExpr(e ast.Expr, def *Named) (T Type) {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
T = check.typExprInternal(e, def)
|
T = check.typInternal(e, def)
|
||||||
assert(isTyped(T))
|
assert(isTyped(T))
|
||||||
check.recordTypeAndValue(e, typexpr, T, nil)
|
check.recordTypeAndValue(e, typexpr, T, nil)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// typ is like typExpr (with a nil argument for the def parameter),
|
// indirectType is like typ but it also breaks the (otherwise) infinite size of recursive
|
||||||
// but typ breaks type cycles. It should be called for components of
|
// types by introducing an indirection. It should be called for components of types that
|
||||||
// types that break cycles, such as pointer base types, slice or map
|
// are not layed out in place in memory, such as pointer base types, slice or map element
|
||||||
// element types, etc. See the comment in typExpr for details.
|
// types, function parameter types, etc.
|
||||||
//
|
func (check *Checker) indirectType(e ast.Expr) Type {
|
||||||
func (check *Checker) typ(e ast.Expr) Type {
|
|
||||||
// push indir sentinel on object path to indicate an indirection
|
|
||||||
check.push(indir)
|
check.push(indir)
|
||||||
defer check.pop()
|
defer check.pop()
|
||||||
return check.typExpr(e, nil)
|
return check.definedType(e, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// funcType type-checks a function or method type.
|
// funcType type-checks a function or method type.
|
||||||
|
|
@ -202,10 +205,10 @@ func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast
|
||||||
sig.variadic = variadic
|
sig.variadic = variadic
|
||||||
}
|
}
|
||||||
|
|
||||||
// typExprInternal drives type checking of types.
|
// typInternal drives type checking of types.
|
||||||
// Must only be called by typExpr.
|
// Must only be called by definedType.
|
||||||
//
|
//
|
||||||
func (check *Checker) typExprInternal(e ast.Expr, def *Named) Type {
|
func (check *Checker) typInternal(e ast.Expr, def *Named) Type {
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
case *ast.BadExpr:
|
case *ast.BadExpr:
|
||||||
// ignore - error reported before
|
// ignore - error reported before
|
||||||
|
|
@ -245,20 +248,20 @@ func (check *Checker) typExprInternal(e ast.Expr, def *Named) Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
case *ast.ParenExpr:
|
case *ast.ParenExpr:
|
||||||
return check.typExpr(e.X, def)
|
return check.definedType(e.X, def)
|
||||||
|
|
||||||
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.typExpr(e.Elt, nil)
|
typ.elem = check.typ(e.Elt)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
typ := new(Slice)
|
typ := new(Slice)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
typ.elem = check.typ(e.Elt)
|
typ.elem = check.indirectType(e.Elt)
|
||||||
return typ
|
return typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -271,7 +274,7 @@ func (check *Checker) typExprInternal(e ast.Expr, def *Named) 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)
|
typ.base = check.indirectType(e.X)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
case *ast.FuncType:
|
case *ast.FuncType:
|
||||||
|
|
@ -290,8 +293,8 @@ func (check *Checker) typExprInternal(e ast.Expr, def *Named) Type {
|
||||||
typ := new(Map)
|
typ := new(Map)
|
||||||
def.setUnderlying(typ)
|
def.setUnderlying(typ)
|
||||||
|
|
||||||
typ.key = check.typ(e.Key)
|
typ.key = check.indirectType(e.Key)
|
||||||
typ.elem = check.typ(e.Value)
|
typ.elem = check.indirectType(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
|
||||||
|
|
@ -325,7 +328,7 @@ func (check *Checker) typExprInternal(e ast.Expr, def *Named) Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
typ.dir = dir
|
typ.dir = dir
|
||||||
typ.elem = check.typ(e.Value)
|
typ.elem = check.indirectType(e.Value)
|
||||||
return typ
|
return typ
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -406,7 +409,7 @@ func (check *Checker) collectParams(scope *Scope, list *ast.FieldList, variadicO
|
||||||
// ignore ... and continue
|
// ignore ... and continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typ := check.typ(ftype)
|
typ := check.indirectType(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 {
|
||||||
|
|
@ -486,7 +489,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
|
||||||
|
|
||||||
for _, f := range iface.Methods.List {
|
for _, f := range iface.Methods.List {
|
||||||
if len(f.Names) == 0 {
|
if len(f.Names) == 0 {
|
||||||
typ := check.typ(f.Type)
|
typ := check.indirectType(f.Type)
|
||||||
// typ should be a named type denoting an interface
|
// typ should be a named type denoting an interface
|
||||||
// (the parser will make sure it's a named type but
|
// (the parser will make sure it's a named type but
|
||||||
// constructed ASTs may be wrong).
|
// constructed ASTs may be wrong).
|
||||||
|
|
@ -569,7 +572,7 @@ func (check *Checker) interfaceType(ityp *Interface, iface *ast.InterfaceType, d
|
||||||
// (possibly embedded) methods must be type-checked within their scope and
|
// (possibly embedded) methods must be type-checked within their scope and
|
||||||
// type-checking them must not affect the current context (was issue #23914)
|
// type-checking them must not affect the current context (was issue #23914)
|
||||||
check.context = context{scope: minfo.scope}
|
check.context = context{scope: minfo.scope}
|
||||||
typ := check.typ(minfo.src.Type)
|
typ := check.indirectType(minfo.src.Type)
|
||||||
sig, _ := typ.(*Signature)
|
sig, _ := typ.(*Signature)
|
||||||
if sig == nil {
|
if sig == nil {
|
||||||
if typ != Typ[Invalid] {
|
if typ != Typ[Invalid] {
|
||||||
|
|
@ -672,7 +675,7 @@ func (check *Checker) structType(styp *Struct, e *ast.StructType) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, f := range list.List {
|
for _, f := range list.List {
|
||||||
typ = check.typExpr(f.Type, nil)
|
typ = check.typ(f.Type)
|
||||||
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