I took the following comments at their word:

// Cannot be created directly; one should always use `singleType' for creation.
// Cannot be created directly; one should always use `refinedType' for creation.
// Cannot be created directly; one should always use `typeRef' for creation. (@M: Otherwise hashing breaks)

This involved altering about 15 locations.  If there was a
rhyme or a reason as to why those particular places were entitled
to ignore the "always" dictate, I trust it will emerge from some
corner now.  Until then, it's nice to see some code following its
official marching orders.  Review by odersky.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@23906 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2011-01-06 08:44:28 +00:00
parent 5850809376
commit 489b3234d2
7 changed files with 29 additions and 31 deletions

View File

@ -347,7 +347,7 @@ trait DocComments { self: SymbolTable =>
def select(site: Type, name: Name, orElse: => Type): Type = {
val member = site.nonPrivateMember(name)
if (member.isTerm) SingleType(site, member)
if (member.isTerm) singleType(site, member)
else if (member.isType) site.memberType(member)
else orElse
}
@ -395,10 +395,10 @@ trait DocComments { self: SymbolTable =>
else {
val alias1 = alias.cloneSymbol(definitions.RootClass)
alias1.name = repl.toTypeName
TypeRef(NoPrefix, alias1, List())
typeRef(NoPrefix, alias1, Nil)
}
case None =>
TypeRef(NoPrefix, alias, List())
typeRef(NoPrefix, alias, Nil)
}
def subst(sym: Symbol, from: List[Symbol], to: List[Type]): Type =
@ -411,7 +411,7 @@ trait DocComments { self: SymbolTable =>
case tp1 @ TypeRef(pre, sym, args) if (sym.name.length > 1 && sym.name(0) == '$') =>
subst(sym, aliases, aliasExpansions) match {
case TypeRef(pre1, sym1, _) =>
TypeRef(pre1, sym1, args)
typeRef(pre1, sym1, args)
case _ =>
tp1
}

View File

@ -1750,13 +1750,13 @@ A type's typeSymbol should never be inspected directly.
// (!result.isEmpty) IFF isHigherKinded
override def typeParams: List[Symbol] = if (isHigherKinded) typeParamsDirect else List()
override def typeConstructor = TypeRef(pre, sym, List())
override def typeConstructor = typeRef(pre, sym, Nil)
// a reference (in a Scala program) to a type that has type parameters, but where the reference does not include type arguments
// note that it doesn't matter whether the symbol refers to a java or scala symbol,
// it does matter whether it occurs in java or scala code
// typerefs w/o type params that occur in java signatures/code are considered raw types, and are represented as existential types
override def isHigherKinded = (args.isEmpty && !typeParamsDirect.isEmpty)
override def isHigherKinded = args.isEmpty && typeParamsDirect.nonEmpty
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type =
if (isHigherKinded) {
@ -2700,19 +2700,18 @@ A type's typeSymbol should never be inspected directly.
def appliedType(tycon: Type, args: List[Type]): Type =
if (args.isEmpty) tycon //@M! `if (args.isEmpty) tycon' is crucial (otherwise we create new types in phases after typer and then they don't get adapted (??))
else tycon match {
case TypeRef(pre, sym, _) =>
val args1 = if(sym == NothingClass || sym == AnyClass) List() else args //@M drop type args to Any/Nothing
typeRef(pre, sym, args1)
case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args)
case ExistentialType(tparams, restpe) => ExistentialType(tparams, appliedType(restpe, args))
case st: SingletonType => appliedType(st.widen, args) // @M TODO: what to do? see bug1
case RefinedType(parents, decls) => RefinedType(parents map (appliedType(_, args)), decls) // MO to AM: please check
case TypeBounds(lo, hi) => TypeBounds(appliedType(lo, args), appliedType(hi, args))
case tv@TypeVar(_, constr) => tv.applyArgs(args)
case AnnotatedType(annots, underlying, self) => AnnotatedType(annots, appliedType(underlying, args), self)
case ErrorType => tycon
case WildcardType => tycon // needed for neg/t0226
case _ => abort(debugString(tycon))
case TypeRef(pre, sym @ (NothingClass|AnyClass), _) => typeRef(pre, sym, Nil) //@M drop type args to Any/Nothing
case TypeRef(pre, sym, _) => typeRef(pre, sym, args)
case PolyType(tparams, restpe) => restpe.instantiateTypeParams(tparams, args)
case ExistentialType(tparams, restpe) => ExistentialType(tparams, appliedType(restpe, args))
case st: SingletonType => appliedType(st.widen, args) // @M TODO: what to do? see bug1
case RefinedType(parents, decls) => RefinedType(parents map (appliedType(_, args)), decls) // MO to AM: please check
case TypeBounds(lo, hi) => TypeBounds(appliedType(lo, args), appliedType(hi, args))
case tv@TypeVar(_, _) => tv.applyArgs(args)
case AnnotatedType(annots, underlying, self) => AnnotatedType(annots, appliedType(underlying, args), self)
case ErrorType => tycon
case WildcardType => tycon // needed for neg/t0226
case _ => abort(debugString(tycon))
}
/** A creator for type parameterizations
@ -2830,7 +2829,7 @@ A type's typeSymbol should never be inspected directly.
object dropSingletonType extends TypeMap {
def apply(tp: Type): Type = {
tp match {
case TypeRef(_, sym, _) if (sym == SingletonClass) =>
case TypeRef(_, SingletonClass, _) =>
AnyClass.tpe
case tp1 @ RefinedType(parents, decls) =>
var parents1 = parents filter (_.typeSymbol != SingletonClass)
@ -3224,7 +3223,7 @@ A type's typeSymbol should never be inspected directly.
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, List()) if isRawIfWithoutArgs(sym) =>
val eparams = typeParamsToExistentials(sym, sym.typeParams)
existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe)))
existentialAbstraction(eparams, typeRef(pre, sym, eparams map (_.tpe)))
case _ =>
mapOver(tp)
}
@ -5323,9 +5322,9 @@ A type's typeSymbol should never be inspected directly.
None // something is wrong: an array without a type arg.
} else {
val args = argss map (_.head)
if (args.tail forall (_ =:= args.head)) Some(TypeRef(pre, sym, List(args.head)))
if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head)))
else if (args exists (arg => isValueClass(arg.typeSymbol))) Some(ObjectClass.tpe)
else Some(TypeRef(pre, sym, List(lub(args))))
else Some(typeRef(pre, sym, List(lub(args))))
}
} else {
val args = (sym.typeParams, argss.transpose).zipped map {

View File

@ -725,7 +725,7 @@ abstract class ClassfileParser {
case 'L' =>
def processInner(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) if (!sym.isStatic) =>
TypeRef(processInner(pre.widen), sym, args)
typeRef(processInner(pre.widen), sym, args)
case _ =>
tp
}
@ -758,13 +758,13 @@ abstract class ClassfileParser {
}
accept('>')
assert(xs.length > 0)
existentialType(existentials.toList, TypeRef(pre, classSym, xs.toList))
existentialType(existentials.toList, typeRef(pre, classSym, xs.toList))
} else if (classSym.isMonomorphicType) {
tp
} else {
// raw type - existentially quantify all type parameters
val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams)
val t = TypeRef(pre, classSym, eparams.map(_.tpe))
val t = typeRef(pre, classSym, eparams.map(_.tpe))
val res = existentialType(eparams, t)
if (settings.debug.value && settings.verbose.value)
println("raw type " + classSym + " -> " + res)

View File

@ -132,8 +132,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def fromTypesToClassArrayLiteral(paramTypes: List[Type]): Tree =
ArrayValue(TypeTree(ClassClass.tpe), paramTypes map LIT)
def theTypeClassArray =
TypeRef(ArrayClass.tpe.prefix, ArrayClass, List(ClassClass.tpe))
def theTypeClassArray = arrayType(ClassClass.tpe)
/* ... */
def reflectiveMethodCache(method: String, paramTypes: List[Type]): Symbol = dispatchType match {

View File

@ -750,7 +750,7 @@ self: Analyzer =>
companion.moduleClass match {
case mc: ModuleClassSymbol =>
buf += (mc.implicitMembers map (im =>
new ImplicitInfo(im.name, SingleType(pre, companion), im)))
new ImplicitInfo(im.name, singleType(pre, companion), im)))
case _ =>
}
}

View File

@ -27,7 +27,7 @@ trait Namers { self: Analyzer =>
case TypeRef(pre, sym, args)
if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) =>
// println("DESKOLEMIZING "+sym+" in "+sym.owner)
mapOver(TypeRef(NoPrefix, sym.deSkolemize, args))
mapOver(typeRef(NoPrefix, sym.deSkolemize, args))
/*
case PolyType(tparams1, restpe) =>
new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)

View File

@ -3145,7 +3145,7 @@ trait Typers extends Modes {
}
def typedEta(expr1: Tree): Tree = expr1.tpe match {
case TypeRef(_, sym, _) if (sym == ByNameParamClass) =>
case TypeRef(_, ByNameParamClass, _) =>
val expr2 = Function(List(), expr1) setPos expr1.pos
new ChangeOwnerTraverser(context.owner, expr2.symbol).traverse(expr2)
typed1(expr2, mode, pt)