diff options
author | Martin Odersky <odersky@gmail.com> | 2013-04-10 15:19:13 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-04-10 15:19:13 +0200 |
commit | 87ae863c3efa7ce41fed81b783855c572d541898 (patch) | |
tree | 590151812be9d41257e7c4b5d5f804853be78d31 | |
parent | 1034d4e420c2b0724945486f341c53a07e6a90e0 (diff) | |
download | dotty-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.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Annotations.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparers.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypeOps.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/TypedTrees.scala | 12 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 23 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/ClassfileParser.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/pickling/UnPickler.scala | 8 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/transform/Erasure.scala | 12 |
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 } } |