aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-26 18:45:03 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-03-29 09:10:10 +0100
commit6a35e3018081a1a8dd90a3e24200223fdbfdce7f (patch)
tree9426d5c581a160ba4def17600a11b71ff45db052 /src/dotty/tools/dotc/core
parent6db08e9457a8bcb093b8c8e79109f7ef419729c2 (diff)
downloaddotty-6a35e3018081a1a8dd90a3e24200223fdbfdce7f.tar.gz
dotty-6a35e3018081a1a8dd90a3e24200223fdbfdce7f.tar.bz2
dotty-6a35e3018081a1a8dd90a3e24200223fdbfdce7f.zip
Reworked erasure denotation transformer
Now works for all combinations of java/scala sue ErasedValueClass/go directly to underlying type constructors/others wildcards ok/not Signatures had to be refined as well, because the signature depends on whether a type comes form Java or Scala (handling of intersections is different). Also, replaced splitArray method in TypeApplication by extractors for single- and multi-dimensional array types in definitions.
Diffstat (limited to 'src/dotty/tools/dotc/core')
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala33
-rw-r--r--src/dotty/tools/dotc/core/Signature.scala8
-rw-r--r--src/dotty/tools/dotc/core/Symbols.scala5
-rw-r--r--src/dotty/tools/dotc/core/TypeApplications.scala17
-rw-r--r--src/dotty/tools/dotc/core/Types.scala10
-rw-r--r--src/dotty/tools/dotc/core/pickling/ClassfileParser.scala3
-rw-r--r--src/dotty/tools/dotc/core/transform/Erasure.scala236
7 files changed, 216 insertions, 96 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 0ec770149..af88a04b9 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -170,6 +170,9 @@ class Definitions {
lazy val UnitClass = valueClassSymbol("scala.Unit", BoxedUnitClass, java.lang.Void.TYPE, UnitEnc)
lazy val BooleanClass = valueClassSymbol("scala.Boolean", BoxedBooleanClass, java.lang.Boolean.TYPE, BooleanEnc)
+
+ lazy val Boolean_and = BooleanClass.requiredMethod(nme.ZAND)
+
lazy val ByteClass = valueClassSymbol("scala.Byte", BoxedByteClass, java.lang.Byte.TYPE, ByteEnc)
lazy val ShortClass = valueClassSymbol("scala.Short", BoxedShortClass, java.lang.Short.TYPE, ShortEnc)
lazy val CharClass = valueClassSymbol("scala.Char", BoxedCharClass, java.lang.Character.TYPE, CharEnc)
@@ -192,7 +195,7 @@ class Definitions {
lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, AnyType)
lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, SeqType)
- lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS, Covariant, ArrayType)
+ lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS, Covariant, ArrayClass.typeRef)
// fundamental classes
lazy val StringClass = ctx.requiredClass("java.lang.String")
@@ -250,8 +253,7 @@ class Definitions {
def NothingType: Type = NothingClass.typeRef
def NullType: Type = NullClass.typeRef
def SeqType: Type = SeqClass.typeRef
- def ArrayType: Type = ArrayClass.typeRef
- def ObjectArrayType = ArrayType.appliedTo(ObjectType)
+ def ObjectArrayType = ArrayType(ObjectType)
def UnitType: Type = UnitClass.typeRef
def BooleanType: Type = BooleanClass.typeRef
@@ -298,6 +300,29 @@ class Definitions {
}
}
+ object ArrayType {
+ def apply(elem: Type) =
+ ArrayClass.typeRef.appliedTo(elem :: Nil)
+ def unapply(tp: Type) = tp.dealias match {
+ case at: RefinedType if (at isRef ArrayClass) && at.argInfos.length == 1 => Some(at.argInfos.head)
+ case _ => None
+ }
+ }
+
+ object MultiArrayType {
+ def apply(elem: Type, ndims: Int): Type =
+ if (ndims == 0) elem else ArrayType(apply(elem, ndims - 1))
+ def unapply(tp: Type): Option[(Type, Int)] = tp match {
+ case ArrayType(elemtp) =>
+ elemtp match {
+ case MultiArrayType(finalElemTp, n) => Some(finalElemTp, n + 1)
+ case _ => Some(elemtp, 1)
+ }
+ case _ =>
+ None
+ }
+ }
+
// ----- Symbol sets ---------------------------------------------------
lazy val FunctionClass = mkArityArray("Function", MaxFunctionArity, 0)
@@ -390,7 +415,7 @@ class Definitions {
hkTraitOfArity.getOrElseUpdate(vcs, createTrait)
}
- // ----- Value class machinery ------------------------------------------
+ // ----- primitive value class machinery ------------------------------------------
lazy val ScalaValueClasses: collection.Set[Symbol] = Set(
UnitClass,
diff --git a/src/dotty/tools/dotc/core/Signature.scala b/src/dotty/tools/dotc/core/Signature.scala
index 18e4e5f6c..02b91b18e 100644
--- a/src/dotty/tools/dotc/core/Signature.scala
+++ b/src/dotty/tools/dotc/core/Signature.scala
@@ -38,8 +38,8 @@ case class Signature private (paramsSig: List[TypeName], resSig: TypeName) {
/** Construct a signature by prepending the signature names of the given `params`
* to the parameter part of this signature.
*/
- def ++:(params: List[Type])(implicit ctx: Context) =
- Signature((params map sigName) ++ paramsSig, resSig)
+ def prepend(params: List[Type], isJava: Boolean)(implicit ctx: Context) =
+ Signature((params.map(sigName(_, isJava))) ++ paramsSig, resSig)
}
@@ -51,6 +51,6 @@ object Signature {
val NotAMethod = Signature(List(), EmptyTypeName)
/** The signature of a method with no parameters and result type `resultType`. */
- def apply(resultType: Type)(implicit ctx: Context): Signature =
- apply(Nil, sigName(resultType))
+ def apply(resultType: Type, isJava: Boolean)(implicit ctx: Context): Signature =
+ apply(Nil, sigName(resultType, isJava))
} \ No newline at end of file
diff --git a/src/dotty/tools/dotc/core/Symbols.scala b/src/dotty/tools/dotc/core/Symbols.scala
index ff70679b8..b4db26ae6 100644
--- a/src/dotty/tools/dotc/core/Symbols.scala
+++ b/src/dotty/tools/dotc/core/Symbols.scala
@@ -379,6 +379,11 @@ object Symbols {
/** If this symbol satisfies predicate `p` this symbol, otherwise `NoSymbol` */
def filter(p: Symbol => Boolean): Symbol = if (p(this)) this else NoSymbol
+ /** Is this symbol a user-defined value class? */
+ final def isDerivedValueClass(implicit ctx: Context): Boolean =
+ false && // value classes are not supported yet
+ isClass && denot.derivesFrom(defn.AnyValClass) && !isPrimitiveValueClass
+
/** Is symbol a primitive value class? */
def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains this
diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala
index b61f39ed7..9cd635cd9 100644
--- a/src/dotty/tools/dotc/core/TypeApplications.scala
+++ b/src/dotty/tools/dotc/core/TypeApplications.scala
@@ -298,23 +298,6 @@ class TypeApplications(val self: Type) extends AnyVal {
def elemType(implicit ctx: Context): Type =
firstBaseArgInfo(defn.SeqClass) orElse firstBaseArgInfo(defn.ArrayClass)
- /** If this type is of the normalized form Array[...[Array[T]...]
- * return the number of Array wrappers and T.
- * Otherwise return 0 and the type itself
- */
- final def splitArray(implicit ctx: Context): (Int, Type) = {
- def recur(n: Int, tp: Type): (Int, Type) = tp.stripTypeVar match {
- case RefinedType(tycon, _) if tycon isRef defn.ArrayClass =>
- tp.argInfos match {
- case arg :: Nil => recur(n + 1, arg)
- case _ => (n, tp)
- }
- case _ =>
- (n, tp)
- }
- recur(0, self)
- }
-
/** Given a type alias
*
* type T[boundSyms] = p.C[targs]
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index ce481759b..a7a33ce8e 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1072,9 +1072,6 @@ object Types {
}
}
- def isType = name.isTypeName
- def isTerm = name.isTermName
-
def symbol(implicit ctx: Context): Symbol = {
val now = ctx.period
if (checkedPeriod == now ||
@@ -1084,6 +1081,9 @@ object Types {
def info(implicit ctx: Context): Type = denot.info
+ def isType = isInstanceOf[TypeRef]
+ def isTerm = isInstanceOf[TermRef]
+
/** Guard against cycles that can arise if given `op`
* follows info. The prblematic cases are a type alias to itself or
* bounded by itself or a val typed as itself:
@@ -1445,7 +1445,7 @@ object Types {
protected def resultSignature(implicit ctx: Context) = resultType match {
case rtp: SignedType => rtp.signature
- case tp => Signature(tp)
+ case tp => Signature(tp, isJava = false)
}
final override def signature(implicit ctx: Context): Signature = {
@@ -1496,7 +1496,7 @@ object Types {
}
protected def computeSignature(implicit ctx: Context): Signature =
- paramTypes ++: resultSignature
+ resultSignature.prepend(paramTypes, isJava)
def derivedMethodType(paramNames: List[TermName], paramTypes: List[Type], restpe: Type)(implicit ctx: Context) =
if ((paramNames eq this.paramNames) && (paramTypes eq this.paramTypes) && (restpe eq this.resultType)) this
diff --git a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
index c33d5c18f..f5942dac2 100644
--- a/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
+++ b/src/dotty/tools/dotc/core/pickling/ClassfileParser.scala
@@ -300,8 +300,7 @@ class ClassfileParser(
if (elemtp.typeSymbol.isAbstractType && !(elemtp.derivesFrom(defn.ObjectClass))) {
elemtp = AndType(elemtp, defn.ObjectType)
}
-
- defn.ArrayType.appliedTo(elemtp)
+ defn.ArrayType(elemtp)
case '(' =>
// we need a method symbol. given in line 486 by calling getType(methodSym, ..)
val paramtypes = new ListBuffer[Type]()
diff --git a/src/dotty/tools/dotc/core/transform/Erasure.scala b/src/dotty/tools/dotc/core/transform/Erasure.scala
index 093b59ae8..89a504ac6 100644
--- a/src/dotty/tools/dotc/core/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/core/transform/Erasure.scala
@@ -2,10 +2,89 @@ package dotty.tools.dotc
package core
package transform
-import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._
+import Symbols._, Types._, Contexts._, Flags._, Names._, StdNames._, Flags.JavaDefined
+import util.DotClass
object Erasure {
+ private def erasureIdx(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcardOK: Boolean) =
+ (if (isJava) 1 else 0) +
+ (if (isSemi) 2 else 0) +
+ (if (isConstructor) 4 else 0) +
+ (if (wildcardOK) 8 else 0)
+
+ private var erasures = new Array[Erasure](16)
+
+ for {
+ isJava <- List(false, true)
+ isSemi <- List(false, true)
+ isConstructor <- List(false, true)
+ wildcardOK <- List(false, true)
+ } erasures(erasureIdx(isJava, isSemi, isConstructor, wildcardOK)) =
+ new Erasure(isJava, isSemi, isConstructor, wildcardOK)
+
+ /** Produces an erasure function.
+ * @param isJava Arguments should be treated the way Java does it
+ * @param isSemi Value classes are mapped in an intermediate step to
+ * ErasedValueClass types, instead of going directly to
+ * the erasure of the underlying type.
+ * @param isConstructor Argument forms part of the type of a constructor
+ * @param wildcardOK Wildcards are acceptable (true when using the erasure
+ * for computing a signature name).
+ */
+ private def erasureFn(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcardOK: Boolean): Erasure =
+ erasures(erasureIdx(isJava, isSemi, isConstructor, wildcardOK))
+
+ private val scalaErasureFn = erasureFn(isJava = false, isSemi = false, isConstructor = false, wildcardOK = false)
+ private val scalaSigFn = erasureFn(isJava = false, isSemi = false, isConstructor = false, wildcardOK = true)
+ private val javaSigFn = erasureFn(isJava = true, isSemi = false, isConstructor = false, wildcardOK = true)
+ private val semiErasureFn = erasureFn(isJava = false, isSemi = true, isConstructor = false, wildcardOK = false)
+
+ def erasure(tp: Type)(implicit ctx: Context): Type = scalaErasureFn(tp)
+ def semiErasure(tp: Type)(implicit ctx: Context): Type = semiErasureFn(tp)
+ def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName =
+ (if (isJava) javaSigFn else scalaSigFn).sigName(tp)
+
+ /** The symbol's erased info. This is the type's erasure, except for the following symbols:
+ *
+ * - For $asInstanceOf : [T]T
+ * - For $isInstanceOf : [T]scala#Boolean
+ * - For Array[T].<init> : [T]{scala#Int)Array[T]
+ * - For type members of Array : The original info
+ * - For all other abstract types: = ?
+ * - For all other symbols : the semi-erasure of their types, with
+ * isJava, isConstructor set according to symbol.
+ */
+ def transformInfo(sym: Symbol, tp: Type)(implicit ctx: Context): Type = {
+ val erase = erasureFn(sym is JavaDefined, isSemi = true, sym.isConstructor, wildcardOK = false)
+ if ((sym eq defn.Object_asInstanceOf) || sym.isType && (sym.owner eq defn.ArrayClass))
+ sym.info
+ else if ((sym eq defn.Object_isInstanceOf) || (sym eq defn.ArrayClass.primaryConstructor)) {
+ val tp @ PolyType(pnames) = sym.info
+ tp.derivedPolyType(pnames, TypeBounds.empty :: Nil, erase(tp.resultType))
+ }
+ else if (sym.isAbstractType)
+ TypeAlias(WildcardType)
+ else
+ erase(tp)
+ }
+
+ def isUnboundedGeneric(tp: Type)(implicit ctx: Context) = !(
+ (tp derivesFrom defn.ObjectClass) ||
+ tp.classSymbol.isPrimitiveValueClass ||
+ (tp.typeSymbol is JavaDefined))
+
+}
+import Erasure._
+
+/**
+ * This is used as the Scala erasure during the erasure phase itself
+ * It differs from normal erasure in that value classes are erased to ErasedValueTypes which
+ * are then later converted to the underlying parameter type in phase posterasure.
+ *
+ */
+class Erasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wildcardOK: Boolean) extends DotClass {
+
/** The erasure |T| of a type T. This is:
*
* - For a refined type scala.Array+[T]:
@@ -15,8 +94,9 @@ object Erasure {
* - otherwise, Object
* - For a constant type, NoType or NoPrefix, the type itself.
* - For all other type proxies: The erasure of the underlying type.
- * - For a typeref scala.Any, scala.AnyVal, scala.Singleon or scala.NotNull, java.lang.Object.
+ * - For a typeref scala.Any, scala.AnyVal, scala.Singleon or scala.NotNull: java.lang.Object.
* - For a typeref scala.Unit, scala.runtime.BoxedUnit.
+ * - For a typeref whose symbol is owned by Array: The typeref itself
* - For a typeref P.C where C refers to a toplevel class, P.C.
* - For a typeref P.C where C refers to a nested class, |P|.C.
* - For a typeref P.C where C refers to an alias type, the erasure of C's alias.
@@ -32,56 +112,73 @@ object Erasure {
* parents |Ps|, but with duplicate references of Object removed.
* - For any other type, exception.
*/
- def erasure(tp: Type)(implicit ctx: Context): Type = tp match {
+ def apply(tp: Type)(implicit ctx: Context): Type = tp match {
case tp: TypeRef =>
val sym = tp.symbol
- if (sym.isClass)
- /*if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tref)
- else */if (sym.owner is Package) normalizeClass(sym.asClass).typeRef
- else tp.derivedSelect(erasure(tp.prefix))
- else erasure(tp.info)
+ if (!sym.isClass)
+ if (sym.owner eq defn.ArrayClass) tp else this(tp.info)
+ else if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tp)
+ else eraseNormalClassRef(tp)
case tp: RefinedType =>
val parent = tp.parent
if (parent isRef defn.ArrayClass) eraseArray(tp)
- else erasure(parent)
- case ConstantType(_) | NoType | NoPrefix =>
+ else this(parent)
+ case tp: ConstantType =>
tp
case tp: TypeProxy =>
- erasure(tp.underlying)
+ this(tp.underlying)
case AndType(tp1, tp2) =>
- erasure(tp1)
+ mergeAnd(this(tp1), this(tp2))
case OrType(tp1, tp2) =>
- erasure(tp.baseTypeRef(lubClass(tp1, tp2)))
+ this(tp.baseTypeRef(lubClass(tp1, tp2)))
case tp: MethodType =>
+ val paramErasure = erasureFn(tp.isJava, isSemi, isConstructor, wildcardOK)(_)
tp.derivedMethodType(
- tp.paramNames, tp.paramTypes.mapConserve(erasure), resultErasure(tp.resultType))
+ tp.paramNames, tp.paramTypes.mapConserve(paramErasure), eraseResult(tp.resultType))
case tp: PolyType =>
- erasure(tp.resultType)
+ this(tp.resultType)
case tp @ ClassInfo(pre, cls, classParents, decls, _) =>
+ def eraseTypeRef = this.asInstanceOf[TypeRef => TypeRef]
val parents: List[TypeRef] =
- if (cls == defn.ObjectClass || cls.isPrimitiveValueClass) Nil
- else if (cls == defn.ArrayClass) defn.ObjectClass.typeRef :: Nil
- else removeLaterObjects(classParents mapConserve (erasure(_).asInstanceOf[TypeRef]))
- tp.derivedClassInfo(erasure(pre), parents, NoType)
- case ErrorType =>
+ if ((cls eq defn.ObjectClass) || cls.isPrimitiveValueClass) Nil
+ else if (cls eq defn.ArrayClass) defn.ObjectClass.typeRef :: Nil
+ else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
+ tp.derivedClassInfo(this(pre), parents, NoType)
+ case NoType | NoPrefix | ErrorType =>
+ tp
+ case tp: WildcardType if wildcardOK =>
tp
}
- def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
- val (n, elemtp) = tp.splitArray
- val elemCls = elemtp.classSymbol
- if (elemCls.isSubClass(defn.NullClass))
- defn.ObjectArrayType
- else if (elemCls.isSubClass(defn.ObjectClass) || elemCls.isPrimitiveValueClass)
- (erasure(elemtp) /: (0 until n))((erased, _) =>
- defn.ArrayType.appliedTo(erased))
- else if (elemtp.typeSymbol is JavaDefined)
- defn.ObjectArrayType
- else
- defn.ObjectType
+ private def eraseArray(tp: RefinedType)(implicit ctx: Context) = {
+ val defn.ArrayType(elemtp) = tp
+ if (elemtp derivesFrom defn.NullClass) defn.ObjectArrayType
+ else if (isUnboundedGeneric(elemtp)) defn.ObjectType
+ else defn.ArrayType(this(elemtp))
+ }
+
+ private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type =
+ unsupported("eraseDerivedValueClass")
+
+ private def eraseNormalClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
+ val sym = tref.symbol
+ if (sym.owner is Package) normalizeClass(sym.asClass).typeRef
+ else tref.derivedSelect(this(tref.prefix))
}
- def normalizeClass(cls: ClassSymbol)(implicit ctx: Context): ClassSymbol = {
+ private def eraseResult(tp: Type)(implicit ctx: Context): Type = tp match {
+ case tp: TypeRef =>
+ val sym = tp.typeSymbol
+ if (sym eq defn.UnitClass) sym.typeRef
+ else if (sym.isDerivedValueClass) eraseNormalClassRef(tp)
+ else this(tp)
+ case RefinedType(parent, _) if !(parent isRef defn.ArrayClass) =>
+ eraseResult(parent)
+ case _ =>
+ this(tp)
+ }
+
+ private def normalizeClass(cls: ClassSymbol)(implicit ctx: Context): ClassSymbol = {
if (cls.owner == defn.ScalaPackageClass) {
if (cls == defn.AnyClass || cls == defn.AnyValClass || cls == defn.SingletonClass || cls == defn.NotNullClass)
return defn.ObjectClass
@@ -91,7 +188,7 @@ object Erasure {
cls
}
- def lubClass(tp1: Type, tp2: Type)(implicit ctx: Context): ClassSymbol = {
+ private def lubClass(tp1: Type, tp2: Type)(implicit ctx: Context): ClassSymbol = {
var bcs1 = tp1.baseClasses
val bc2 = tp2.baseClasses.head
while (bcs1.nonEmpty && !bc2.derivesFrom(bcs1.head))
@@ -99,44 +196,55 @@ object Erasure {
if (bcs1.isEmpty) defn.ObjectClass else bcs1.head
}
+ private def removeLaterObjects(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match {
+ case tr :: trs1 => tr :: trs1.filterNot(_ isRef defn.ObjectClass)
+ case nil => nil
+ }
+
+ private def mergeAnd(tp1: Type, tp2: Type)(implicit ctx: Context): Type = tp1 match {
+ case defn.ArrayType(elem1) =>
+ tp2 match {
+ case defn.ArrayType(elem2) => defn.ArrayType(mergeAnd(elem1, elem2))
+ case _ => defn.ObjectType
+ }
+ case _ =>
+ tp2 match {
+ case defn.ArrayType(_) => defn.ObjectType
+ case _ =>
+ val tsym1 = tp1.typeSymbol
+ val tsym2 = tp2.typeSymbol
+ if (!tsym2.exists) tp1
+ else if (!tsym1.exists) tp2
+ else if (!isJava && tsym1.derivesFrom(tsym2)) tp1
+ else if (!isJava && tsym2.derivesFrom(tsym1)) tp2
+ else if (tp1.typeSymbol.isRealClass) tp1
+ else if (tp2.typeSymbol.isRealClass) tp2
+ else tp1
+ }
+ }
+
/** The name of the type as it is used in `Signature`s.
* Need to ensure correspondence with erasure!
*/
def sigName(tp: Type)(implicit ctx: Context): TypeName = tp match {
case tp: TypeRef =>
val sym = tp.symbol
- if (sym.isClass)
- /*if (sym.isDerivedValueClass) eraseDerivedValueClassRef(tref)
- else */if (sym.owner is Package) normalizeClass(sym.asClass).fullName.asTypeName
- else sym.asClass.fullName.asTypeName
- else sigName(tp.info)
- case tp: RefinedType =>
- val parent = tp.parent
- if (parent isRef defn.ArrayClass)
- eraseArray(tp) match {
- case tp1: RefinedType if tp1.parent isRef defn.ArrayClass =>
- sigName(tp1.refinedInfo) ++ "[]"
- case tp1 =>
- sigName(tp1)
- }
- else sigName(parent)
+ if (!sym.isClass) sigName(tp.info)
+ else if (sym.isDerivedValueClass) sigName(eraseDerivedValueClassRef(tp))
+ else normalizeClass(sym.asClass).fullName.asTypeName
+ case defn.ArrayType(elem) =>
+ sigName(elem) ++ "[]"
+ case tp: TypeBounds =>
+ sigName(tp.hi)
case tp: TypeProxy =>
sigName(tp.underlying)
- case AndType(tp1, tp2) =>
- sigName(tp1)
- case OrType(tp1, tp2) =>
- lubClass(tp1, tp2).name
- case tp: WildcardType =>
+ case ErrorType | WildcardType =>
tpnme.WILDCARD
- case ErrorType =>
- tpnme.WILDCARD
- }
-
- def resultErasure(tp: Type)(implicit ctx: Context) =
- if (tp isRef defn.UnitClass) tp else erasure(tp)
-
- def removeLaterObjects(trs: List[TypeRef])(implicit ctx: Context): List[TypeRef] = trs match {
- case tr :: trs1 => tr :: trs1.filterNot(_ isRef defn.ObjectClass)
- case nil => nil
+ case tp: WildcardType =>
+ sigName(tp.optBounds)
+ case _ =>
+ val erased = this(tp)
+ assert(erased ne tp)
+ sigName(erased)
}
}