aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-10 15:19:13 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-10 15:19:13 +0200
commit87ae863c3efa7ce41fed81b783855c572d541898 (patch)
tree590151812be9d41257e7c4b5d5f804853be78d31
parent1034d4e420c2b0724945486f341c53a07e6a90e0 (diff)
downloaddotty-87ae863c3efa7ce41fed81b783855c572d541898.tar.gz
dotty-87ae863c3efa7ce41fed81b783855c572d541898.tar.bz2
dotty-87ae863c3efa7ce41fed81b783855c572d541898.zip
Re-organized comparisons of types with classes.
New methods: isClassType, derivesFrom, isArray. Refactored calls to typeSymbol and <:< into these. Made sure to use dealias where needed on remaining typeSymbol calls.
-rw-r--r--src/dotty/tools/dotc/config/JavaPlatform.scala6
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala4
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala4
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala12
-rw-r--r--src/dotty/tools/dotc/core/TypeComparers.scala4
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala2
-rw-r--r--src/dotty/tools/dotc/core/TypedTrees.scala12
-rw-r--r--src/dotty/tools/dotc/core/Types.scala23
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala4
-rw-r--r--src/dotty/tools/dotc/core/pickling/UnPickler.scala8
-rw-r--r--src/dotty/tools/dotc/core/transform/Erasure.scala12
11 files changed, 51 insertions, 40 deletions
diff --git a/src/dotty/tools/dotc/config/JavaPlatform.scala b/src/dotty/tools/dotc/config/JavaPlatform.scala
index bf467ec1e..f62c87daf 100644
--- a/src/dotty/tools/dotc/config/JavaPlatform.scala
+++ b/src/dotty/tools/dotc/config/JavaPlatform.scala
@@ -34,9 +34,9 @@ class JavaPlatform extends Platform {
(sym == ObjectClass) ||
(sym == JavaSerializableClass) ||
(sym == ComparableClass) ||
- (sym isNonBottomSubClass BoxedNumberClass) ||
- (sym isNonBottomSubClass BoxedCharClass) ||
- (sym isNonBottomSubClass BoxedBooleanClass)
+ (sym derivesFrom BoxedNumberClass) ||
+ (sym derivesFrom BoxedCharClass) ||
+ (sym derivesFrom BoxedBooleanClass)
}
def newClassLoader(bin: AbstractFile)(implicit ctx: Context): SymbolLoader =
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 371df9e50..98ce4fffd 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -7,7 +7,7 @@ object Annotations {
abstract class Annotation {
def tree: Tree
def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol
- def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.isNonBottomSubClass(cls)
+ def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.derivesFrom(cls)
def appliesToModule: Boolean = true // for now; see remark in SymDenotations
def derivedAnnotation(tree: Tree) =
@@ -51,7 +51,7 @@ object Annotations {
new LazyAnnotation(sym)(treeFn)
def deferred(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation =
- deferred(atp.typeSymbol, New(atp, args))
+ deferred(atp.classSymbol, New(atp, args))
def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
apply(defn.AliasAnnot, List(Ident(TermRef.withSig(sym.owner.thisType, sym.name, sym.signature).withDenot(sym))))
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index fba99439e..f62acb015 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -287,9 +287,9 @@ class Definitions(implicit ctx: Context) {
}
def wrapArrayMethodName(elemtp: Type): TermName = {
- val cls = elemtp.typeSymbol
+ val cls = elemtp.classSymbol
if (cls.isPrimitiveValueClass) nme.wrapXArray(cls.name)
- else if ((elemtp <:< AnyRefType) && !cls.isPhantomClass) nme.wrapRefArray
+ else if (cls.derivesFrom(ObjectClass) && !cls.isPhantomClass) nme.wrapRefArray
else nme.genericWrapArray
}
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index a559e9d79..a14f28ce4 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -319,7 +319,7 @@ object SymDenotations {
/** Is this a subclass of `base`,
* and is the denoting symbol also different from `Null` or `Nothing`?
*/
- def isNonBottomSubClass(base: Symbol)(implicit ctx: Context) = false
+ def derivesFrom(base: Symbol)(implicit ctx: Context) = false
/** Is this symbol a class that does not extend `AnyVal`? */
final def isNonValueClass(implicit ctx: Context): Boolean =
@@ -351,7 +351,7 @@ object SymDenotations {
def isCorrectThisType(pre: Type): Boolean = pre match {
case ThisType(pclazz) =>
(pclazz eq owner) ||
- (this is Protected) && pclazz.isNonBottomSubClass(owner)
+ (this is Protected) && pclazz.derivesFrom(owner)
case _ => false
}
@@ -723,7 +723,7 @@ object SymDenotations {
_baseClasses
}
- final override def isNonBottomSubClass(base: Symbol)(implicit ctx: Context): Boolean =
+ final override def derivesFrom(base: Symbol)(implicit ctx: Context): Boolean =
base.isClass &&
( (symbol eq base)
|| (superClassBits contains base.superId)
@@ -732,7 +732,7 @@ object SymDenotations {
)
final override def isSubClass(base: Symbol)(implicit ctx: Context) =
- isNonBottomSubClass(base) ||
+ derivesFrom(base) ||
base.isClass && (
(symbol eq defn.NothingClass) ||
(symbol eq defn.NullClass) && (base ne defn.NothingClass))
@@ -885,8 +885,8 @@ object SymDenotations {
NoType
}
- ctx.debugTraceIndented(s"$tp.baseType($this) ${tp.typeSymbol.fullName} ${this.fullName}") {
- if (symbol.isStatic && tp.typeSymbol.isNonBottomSubClass(symbol))
+ ctx.debugTraceIndented(s"$tp.baseType($this)") {
+ if (symbol.isStatic && tp.derivesFrom(symbol))
symbol.typeConstructor
else tp match {
case tp: CachedType =>
diff --git a/src/dotty/tools/dotc/core/TypeComparers.scala b/src/dotty/tools/dotc/core/TypeComparers.scala
index 0e0f9c09d..9df88eeb8 100644
--- a/src/dotty/tools/dotc/core/TypeComparers.scala
+++ b/src/dotty/tools/dotc/core/TypeComparers.scala
@@ -169,7 +169,7 @@ object TypeComparers {
def fourthTry(tp1: Type, tp2: Type): Boolean = tp1 match {
case tp1: TypeRef =>
( (tp1 eq defn.NothingType)
- || (tp1 eq defn.NullType) && tp2.typeSymbol.isNonValueClass
+ || (tp1 eq defn.NullType) && tp2.dealias.typeSymbol.isNonValueClass
|| !tp1.symbol.isClass && isSubType(tp1.info.bounds.hi, tp2)
)
case tp1: SingletonType =>
@@ -211,7 +211,7 @@ object TypeComparers {
(hkArgs, tparams).zipped.forall { (hkArg, tparam) =>
val lo2 :: hi2 :: Nil = hkArg.typeArgs
val TypeBounds(lo1, hi1) = base.memberInfo(tparam)
- lo2 <:< lo1 && hi1 <:< hi2 &&
+ isSubType(lo2, lo1) && isSubType(hi1, hi2) &&
defn.hkBoundsClass(tparam.variance) == hkArg.typeSymbol
}
}
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 45bd6a9f9..d3cfaba69 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -11,7 +11,7 @@ trait TypeOps { this: Context =>
def toPrefix(pre: Type, cls: Symbol, thiscls: ClassSymbol): Type = ctx.debugTraceIndented(s"toPrefix($pre, $cls, $thiscls)") {
if ((pre eq NoType) || (pre eq NoPrefix) || (cls is PackageClass))
tp
- else if (thiscls.isNonBottomSubClass(cls) && pre.baseType(thiscls).exists)
+ else if (thiscls.derivesFrom(cls) && pre.baseType(thiscls).exists)
pre match {
case SuperType(thispre, _) => thispre
case _ => pre
diff --git a/src/dotty/tools/dotc/core/TypedTrees.scala b/src/dotty/tools/dotc/core/TypedTrees.scala
index ae4c82c3d..56ecc7c98 100644
--- a/src/dotty/tools/dotc/core/TypedTrees.scala
+++ b/src/dotty/tools/dotc/core/TypedTrees.scala
@@ -494,13 +494,13 @@ object TypedTrees {
check(noLeaksIn(tree.tpe))
case If(cond, thenp, elsep) =>
check(cond.isValue); check(thenp.isValue); check(elsep.isValue)
- check(cond.tpe <:< defn.BooleanType)
+ check(cond.tpe.derivesFrom(defn.BooleanClass))
case Match(selector, cases) =>
check(selector.isValue)
// are any checks that relate selector and patterns desirable?
case CaseDef(pat, guard, body) =>
check(pat.isValueOrPattern); check(guard.isValue); check(body.isValue)
- check(guard.tpe <:< defn.BooleanType)
+ check(guard.tpe.derivesFrom(defn.BooleanClass))
case Return(expr, from) =>
check(expr.isValue); check(from.isTerm)
check(from.tpe.termSymbol.isSourceMethod)
@@ -508,10 +508,10 @@ object TypedTrees {
check(block.isTerm)
check(finalizer.isTerm)
for (ctch <- catches)
- check(ctch.pat.tpe <:< defn.ThrowableType)
+ check(ctch.pat.tpe.derivesFrom(defn.ThrowableClass))
case Throw(expr) =>
check(expr.isValue)
- check(expr.tpe <:< defn.ThrowableType)
+ check(expr.tpe.derivesFrom(defn.ThrowableClass))
case SeqLiteral(elemtpt, elems) =>
check(elemtpt.isValueType);
for (elem <- elems) {
@@ -579,7 +579,7 @@ object TypedTrees {
check(args.head.tpe.typeSymbol == defn.RepeatedParamClass)
case nme.unapply =>
val rtp = funtpe.resultType
- val rsym = rtp.typeSymbol
+ val rsym = rtp.dealias.typeSymbol
if (rsym == defn.BooleanClass)
check(args.isEmpty)
else {
@@ -589,7 +589,7 @@ object TypedTrees {
optionArg.typeArgs match {
case Nil =>
optionArg :: Nil
- case tupleArgs if defn.TupleClasses contains optionArg.typeSymbol =>
+ case tupleArgs if defn.TupleClasses contains optionArg.dealias.typeSymbol =>
tupleArgs
}
case _ =>
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 7656835cf..133018a96 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -90,7 +90,18 @@ object Types {
case _ => false
}
- /** A type T is a legal prefix in a type selection T#A if
+ /** Is this type an instance of the given class `cls`? */
+ final def isClassType(cls: Symbol)(implicit ctx: Context): Boolean =
+ dealias.typeSymbol == cls
+
+ /** Is this type an instance of a non-bottom subclass of the given class `cls`? */
+ final def derivesFrom(cls: Symbol)(implicit ctx: Context): Boolean =
+ classSymbol.derivesFrom(cls)
+
+ /** Is this an array type? */
+ final def isArray(implicit ctx: Context): Boolean = isClassType(defn.ArrayClass)
+
+ /** A type T is a legal prefix in a type selection T#A if
* T is stable or T contains no uninstantiated type variables.
*/
final def isLegalPrefix(implicit ctx: Context): Boolean =
@@ -101,7 +112,7 @@ object Types {
* be refined later.
*/
final def isNotNull(implicit ctx: Context): Boolean =
- widen.typeSymbol is ModuleClass
+ classSymbol is ModuleClass
/** Is this type produced as a repair for an error? */
final def isError(implicit ctx: Context): Boolean =
@@ -448,7 +459,7 @@ object Types {
/** Map references to Object to references to Any; needed for Java interop */
final def objToAny(implicit ctx: Context) =
- if (typeSymbol == defn.ObjectClass && !ctx.phase.erasedTypes) defn.AnyType else this
+ if (isClassType(defn.ObjectClass) && !ctx.phase.erasedTypes) defn.AnyType else this
// ----- Access to parts --------------------------------------------
@@ -684,8 +695,8 @@ object Types {
final def argType(tparam: Symbol)(implicit ctx: Context): Type = this match {
case TypeBounds(lo, hi) =>
val v = tparam.variance
- if (v > 0 && lo.typeSymbol == defn.NothingClass) hi
- else if (v < 0 && hi.typeSymbol == defn.AnyClass) lo
+ if (v > 0 && lo.isClassType(defn.NothingClass)) hi
+ else if (v < 0 && hi.isClassType(defn.AnyClass)) lo
else if (v == 0 && (lo eq hi)) lo
else NoType
case _ =>
@@ -698,7 +709,7 @@ object Types {
*/
final def splitArray(implicit ctx: Context): (Int, Type) = {
def recur(n: Int, tp: Type): (Int, Type) = tp match {
- case RefinedType(tycon, _) if tycon.dealias.typeSymbol == defn.ArrayClass =>
+ case RefinedType(tycon, _) if tycon.isArray =>
tp.typeArgs match {
case arg :: Nil => recur(n + 1, arg)
case _ => (n, tp)
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index 801841915..4ba4842e1 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -284,7 +284,7 @@ class ClassfileParser(
// NOTE that the comparison to Object only works for abstract types bounded by classes that are strict subclasses of Object
// if the bound is exactly Object, it will have been converted to Any, and the comparison will fail
// see also RestrictJavaArraysMap (when compiling java sources directly)
- if (elemtp.typeSymbol.isAbstractType && !(elemtp <:< defn.ObjectType)) {
+ if (elemtp.typeSymbol.isAbstractType && !(elemtp.derivesFrom(defn.ObjectClass))) {
elemtp = AndType(elemtp, defn.ObjectType)
}
@@ -430,7 +430,7 @@ class ClassfileParser(
def parseAttributes(sym: Symbol, symtype: Type): Type = {
def convertTo(c: Constant, pt: Type): Constant = {
- if (pt.typeSymbol == defn.BooleanClass && c.tag == IntTag)
+ if (pt == defn.BooleanType && c.tag == IntTag)
Constant(c.value != 0)
else
c convertTo pt
diff --git a/src/dotty/tools/dotc/core/pickling/UnPickler.scala b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
index 1d748ae55..3168bb37c 100644
--- a/src/dotty/tools/dotc/core/pickling/UnPickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/UnPickler.scala
@@ -82,10 +82,10 @@ object UnPickler {
def arrayToRepeated(tp: Type)(implicit ctx: Context): Type = tp match {
case tp @ MethodType(paramNames, paramTypes) =>
val lastArg = paramTypes.last
- assert(lastArg.typeSymbol == defn.ArrayClass)
+ assert(lastArg.isArray)
val elemtp0 :: Nil = lastArg.typeArgs
val elemtp = elemtp0 match {
- case AndType(t1, t2) if t1.typeSymbol.isAbstractType && t2.typeSymbol == defn.ObjectClass =>
+ case AndType(t1, t2) if t1.typeSymbol.isAbstractType && t2.isClassType(defn.ObjectClass) =>
t1 // drop intersection with Object for abstract types in varargs. UnCurry can handle them.
case _ =>
elemtp0
@@ -550,7 +550,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
*/
def elimExistentials(boundSyms: List[Symbol], tp: Type): Type = {
def removeSingleton(tp: Type): Type =
- if (tp.typeSymbol == defn.SingletonClass) defn.AnyType else tp
+ if (tp.isClassType(defn.SingletonClass)) defn.AnyType else tp
def elim(tp: Type): Type = tp match {
case tp @ RefinedType(parent, name) =>
val parent1 = elim(tp.parent)
@@ -559,7 +559,7 @@ class UnPickler(bytes: Array[Byte], classRoot: ClassDenotation, moduleClassRoot:
RefinedType(parent1, name, info.fixedSym.info)
case info: TypeRefBySym if boundSyms contains info.fixedSym =>
val info1 = info.fixedSym.info
- assert(info1 <:< defn.SingletonClass.typeConstructor)
+ assert(info1.derivesFrom(defn.SingletonClass))
RefinedType(parent1, name, info1.mapAnd(removeSingleton))
case info =>
tp.derivedRefinedType(parent1, name, info)
diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala
index 661a88035..5b8a492e1 100644
--- a/src/dotty/tools/dotc/core/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/core/transform/Erasure.scala
@@ -42,7 +42,7 @@ object Erasure {
else erasure(sym.info)
case tp: RefinedType =>
val parent = tp.parent
- if (parent.dealias.typeSymbol == defn.ArrayClass) eraseArray(tp)
+ if (parent.isArray) eraseArray(tp)
else erasure(parent)
case ConstantType(_) | NoType | NoPrefix =>
tp
@@ -92,7 +92,7 @@ object Erasure {
def lubClass(tp1: Type, tp2: Type)(implicit ctx: Context): ClassSymbol = {
var bcs1 = tp1.baseClasses
val bc2 = tp2.baseClasses.head
- while (bcs1.nonEmpty && !bc2.isNonBottomSubClass(bcs1.head))
+ while (bcs1.nonEmpty && !bc2.derivesFrom(bcs1.head))
bcs1 = bcs1.tail
if (bcs1.isEmpty) defn.ObjectClass else bcs1.head
}
@@ -110,9 +110,9 @@ object Erasure {
else paramSignature(sym.info)
case tp: RefinedType =>
val parent = tp.parent
- if (parent.dealias.typeSymbol == defn.ArrayClass)
+ if (parent.isArray)
eraseArray(tp) match {
- case tp1: RefinedType if tp1.parent.dealias.typeSymbol == defn.ArrayClass =>
+ case tp1: RefinedType if tp1.parent.isArray =>
paramSignature(tp1.refinedInfo) ++ "[]"
case tp1 =>
paramSignature(tp1)
@@ -127,10 +127,10 @@ object Erasure {
}
def resultErasure(tp: Type)(implicit ctx: Context) =
- if (tp.dealias.typeSymbol == defn.UnitClass) tp else erasure(tp)
+ if (tp.isClassType(defn.UnitClass)) tp else erasure(tp)
def removeLaterObjects(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match {
- case tr :: trs1 => tr :: (trs1 filter (_.typeSymbol != defn.ObjectClass))
+ case tr :: trs1 => tr :: trs1.filterNot(_.isClassType(defn.ObjectClass))
case nil => nil
}
}