aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-11-07 12:58:33 +0100
committerMartin Odersky <odersky@gmail.com>2015-11-09 15:45:37 +0100
commit8978ae6dfabae562fb5dcf4c7f66983d4d865892 (patch)
tree999cd971a10b46ec307c550a5af464329495c6c9 /src/dotty/tools/dotc/transform
parentf2b61ce055fccf96e305ef43fca8abef8a912f33 (diff)
downloaddotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.tar.gz
dotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.tar.bz2
dotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.zip
First versions of Definitions based on TypeRefs not Symbols.
Symbols are not stable between runs, so if some symbol referred to from Definitions gets recompiled, there are then two Symbols that are both visible, one referenced from Definitions, the other the one that got compiled. Thos led to a crash when e.g. compiling scala.Short, because the newly compiled symbol was not recognized as a primitive value class. The present commit tries to make systematic changes without regard to simplicity or aesthetics. This will be polished in future commits. // ### comments signal areas that need further attention.
Diffstat (limited to 'src/dotty/tools/dotc/transform')
-rw-r--r--src/dotty/tools/dotc/transform/CapturedVars.scala15
-rw-r--r--src/dotty/tools/dotc/transform/ClassOf.scala29
-rw-r--r--src/dotty/tools/dotc/transform/ClassTags.scala6
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala8
-rw-r--r--src/dotty/tools/dotc/transform/FirstTransform.scala2
-rw-r--r--src/dotty/tools/dotc/transform/GetClass.scala20
-rw-r--r--src/dotty/tools/dotc/transform/NonLocalReturns.scala6
-rw-r--r--src/dotty/tools/dotc/transform/PatternMatcher.scala6
-rw-r--r--src/dotty/tools/dotc/transform/SyntheticMethods.scala25
-rw-r--r--src/dotty/tools/dotc/transform/TypeTestsCasts.scala4
10 files changed, 45 insertions, 76 deletions
diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala
index 0f1a60282..bd0c7f203 100644
--- a/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -54,16 +54,19 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
/** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`,
* depending on whether the reference should be @volatile
*/
- def refCls(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = {
- val refMap = if (isVolatile) defn.volatileRefClass else defn.refClass
- refMap.getOrElse(cls, refMap(defn.ObjectClass))
+ def refTypeRef(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): TypeRef = {
+ val refMap = if (isVolatile) defn.volatileRefTypeRef else defn.refTypeRef
+ if (cls.isClass) {
+ refMap.getOrElse(cls.typeRef, refMap(defn.ObjectClass.typeRef))
+ }
+ else refMap(defn.ObjectClass.typeRef)
}
override def prepareForValDef(vdef: ValDef)(implicit ctx: Context) = {
val sym = vdef.symbol
if (captured contains sym) {
val newd = sym.denot(ctx.withPhase(thisTransform)).copySymDenotation(
- info = refCls(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef,
+ info = refTypeRef(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)),
initFlags = sym.flags &~ Mutable)
newd.removeAnnotation(defn.VolatileAnnot)
newd.installAfter(thisTransform)
@@ -109,11 +112,13 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
* drop the cast.
*/
override def transformAssign(tree: Assign)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ def isBoxedRefType(sym: Symbol) =
+ sym.isClass && defn.boxedRefTypeRefs.exists(_.symbol == sym)
def recur(lhs: Tree): Tree = lhs match {
case TypeApply(Select(qual, nme.asInstanceOf_), _) =>
val Select(_, nme.elem) = qual
recur(qual)
- case Select(_, nme.elem) if defn.boxedRefClasses.contains(lhs.symbol.maybeOwner) =>
+ case Select(_, nme.elem) if isBoxedRefType(lhs.symbol.maybeOwner) =>
val tempDef = transformFollowing(SyntheticValDef(ctx.freshName("ev$").toTermName, tree.rhs))
transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol))))
case _ =>
diff --git a/src/dotty/tools/dotc/transform/ClassOf.scala b/src/dotty/tools/dotc/transform/ClassOf.scala
index 4d6bf2dc9..cc7f8bad3 100644
--- a/src/dotty/tools/dotc/transform/ClassOf.scala
+++ b/src/dotty/tools/dotc/transform/ClassOf.scala
@@ -24,30 +24,15 @@ class ClassOf extends MiniPhaseTransform {
private var classOfMethod: TermSymbol = _
override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context): TreeTransform = {
- val predefModule = ctx.definitions.ScalaPredefModule
- classOfMethod = ctx.requiredMethod(predefModule.moduleClass.asClass, nme.classOf)
+ val predefModule = ctx.definitions.ScalaPredefModuleRef
+ classOfMethod = ctx.requiredMethod(predefModule, nme.classOf)
this
}
- override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree = {
+ override def transformTypeApply(tree: TypeApply)(implicit ctx: Context, info: TransformerInfo): Tree =
if (tree.symbol eq classOfMethod) {
- val tp = tree.args.head.tpe
- val defn = ctx.definitions
- val claz = tp.classSymbol
-
- def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
- claz match {
- case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
- case defn.ByteClass => TYPE(defn.BoxedByteModule)
- case defn.ShortClass => TYPE(defn.BoxedShortModule)
- case defn.CharClass => TYPE(defn.BoxedCharModule)
- case defn.IntClass => TYPE(defn.BoxedIntModule)
- case defn.LongClass => TYPE(defn.BoxedLongModule)
- case defn.FloatClass => TYPE(defn.BoxedFloatModule)
- case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
- case defn.UnitClass => TYPE(defn.BoxedVoidModule)
- case _ => Literal(Constant(TypeErasure.erasure(tp)))
- }
- } else tree
- }
+ val targ = tree.args.head.tpe
+ tree.clsOf(targ, Literal(Constant(TypeErasure.erasure(targ))))
+ }
+ else tree
}
diff --git a/src/dotty/tools/dotc/transform/ClassTags.scala b/src/dotty/tools/dotc/transform/ClassTags.scala
index 9d8abae93..203898ef0 100644
--- a/src/dotty/tools/dotc/transform/ClassTags.scala
+++ b/src/dotty/tools/dotc/transform/ClassTags.scala
@@ -31,9 +31,9 @@ class ClassTags extends MiniPhaseTransform with IdentityDenotTransformer { thisT
override def prepareForUnit(tree: tpd.Tree)(implicit ctx: Context): TreeTransform = {
- val predefClass = defn.DottyPredefModule.moduleClass.asClass
- classTagCache = ctx.requiredMethod(predefClass, nme.classTag)
- typeTagCache = ctx.requiredMethod(predefClass, nme.typeTag)
+ val dottyPredef = defn.DottyPredefModuleRef
+ classTagCache = ctx.requiredMethod(dottyPredef, nme.classTag)
+ typeTagCache = ctx.requiredMethod(dottyPredef, nme.typeTag)
scala2ClassTagModule = ctx.requiredModule("scala.reflect.ClassTag")
this
}
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index a414c6399..a540dafb0 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -218,7 +218,7 @@ object Erasure extends TypeTestsCasts{
case (JavaArrayType(treeElem), JavaArrayType(ptElem))
if treeElem.widen.isPrimitiveValueType && !ptElem.isPrimitiveValueType =>
// See SI-2386 for one example of when this might be necessary.
- cast(ref(defn.runtimeMethod(nme.toObjectArray)).appliedTo(tree), pt)
+ cast(ref(defn.runtimeMethodRef(nme.toObjectArray)).appliedTo(tree), pt)
case (_, ErasedValueType(cls, _)) =>
ref(u2evt(cls)).appliedTo(tree)
case _ =>
@@ -388,10 +388,10 @@ object Erasure extends TypeTestsCasts{
}
private def runtimeCallWithProtoArgs(name: Name, pt: Type, args: Tree*)(implicit ctx: Context): Tree = {
- val meth = defn.runtimeMethod(name)
- val followingParams = meth.info.firstParamTypes.drop(args.length)
+ val meth = defn.runtimeMethodRef(name)
+ val followingParams = meth.symbol.info.firstParamTypes.drop(args.length)
val followingArgs = protoArgs(pt).zipWithConserve(followingParams)(typedExpr).asInstanceOf[List[tpd.Tree]]
- ref(defn.runtimeMethod(name)).appliedToArgs(args.toList ++ followingArgs)
+ ref(meth).appliedToArgs(args.toList ++ followingArgs)
}
private def protoArgs(pt: Type): List[untpd.Tree] = pt match {
diff --git a/src/dotty/tools/dotc/transform/FirstTransform.scala b/src/dotty/tools/dotc/transform/FirstTransform.scala
index aecc1b86f..4b27c9efe 100644
--- a/src/dotty/tools/dotc/transform/FirstTransform.scala
+++ b/src/dotty/tools/dotc/transform/FirstTransform.scala
@@ -100,7 +100,7 @@ class FirstTransform extends MiniPhaseTransform with IdentityDenotTransformer wi
if (ddef.symbol.hasAnnotation(defn.NativeAnnot)) {
ddef.symbol.resetFlag(Deferred)
DefDef(ddef.symbol.asTerm,
- _ => ref(defn.Sys_error).withPos(ddef.pos)
+ _ => ref(defn.Sys_errorR).withPos(ddef.pos)
.appliedTo(Literal(Constant("native method stub"))))
} else ddef
}
diff --git a/src/dotty/tools/dotc/transform/GetClass.scala b/src/dotty/tools/dotc/transform/GetClass.scala
index 4d8c8ae40..9d182382d 100644
--- a/src/dotty/tools/dotc/transform/GetClass.scala
+++ b/src/dotty/tools/dotc/transform/GetClass.scala
@@ -4,7 +4,6 @@ package transform
import ast.tpd
import core.Contexts.Context
import core.StdNames.nme
-import core.Symbols.TermSymbol
import core.Phases.Phase
import TreeTransforms.{MiniPhaseTransform, TransformerInfo}
@@ -24,25 +23,8 @@ class GetClass extends MiniPhaseTransform {
override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo): Tree = {
import ast.Trees._
-
tree match {
- case Apply(Select(qual, nme.getClass_), Nil) =>
- val defn = ctx.definitions
- val claz = qual.tpe.widen.classSymbol
-
- def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
- claz match {
- case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
- case defn.ByteClass => TYPE(defn.BoxedByteModule)
- case defn.ShortClass => TYPE(defn.BoxedShortModule)
- case defn.CharClass => TYPE(defn.BoxedCharModule)
- case defn.IntClass => TYPE(defn.BoxedIntModule)
- case defn.LongClass => TYPE(defn.BoxedLongModule)
- case defn.FloatClass => TYPE(defn.BoxedFloatModule)
- case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
- case defn.UnitClass => TYPE(defn.BoxedVoidModule)
- case _ => tree
- }
+ case Apply(Select(qual, nme.getClass_), Nil) => tree.clsOf(qual.tpe.widen, tree)
case _ => tree
}
}
diff --git a/src/dotty/tools/dotc/transform/NonLocalReturns.scala b/src/dotty/tools/dotc/transform/NonLocalReturns.scala
index 1f18a7318..a58a0fbda 100644
--- a/src/dotty/tools/dotc/transform/NonLocalReturns.scala
+++ b/src/dotty/tools/dotc/transform/NonLocalReturns.scala
@@ -29,7 +29,7 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
/** The type of a non-local return expression with given argument type */
private def nonLocalReturnExceptionType(argtype: Type)(implicit ctx: Context) =
- defn.NonLocalReturnControlClass.typeRef.appliedTo(argtype)
+ defn.NonLocalReturnControlTypeRef.appliedTo(argtype)
/** A hashmap from method symbols to non-local return keys */
private val nonLocalReturnKeys = mutable.Map[Symbol, TermSymbol]()
@@ -50,7 +50,7 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
private def nonLocalReturnThrow(expr: Tree, meth: Symbol)(implicit ctx: Context) =
Throw(
New(
- defn.NonLocalReturnControlClass.typeRef,
+ defn.NonLocalReturnControlTypeRef,
ref(nonLocalReturnKey(meth)) :: expr.ensureConforms(defn.ObjectType) :: Nil))
/** Transform (body, key) to:
@@ -68,7 +68,7 @@ class NonLocalReturns extends MiniPhaseTransform { thisTransformer =>
*/
private def nonLocalReturnTry(body: Tree, key: TermSymbol, meth: Symbol)(implicit ctx: Context) = {
val keyDef = ValDef(key, New(defn.ObjectType, Nil))
- val nonLocalReturnControl = defn.NonLocalReturnControlClass.typeRef
+ val nonLocalReturnControl = defn.NonLocalReturnControlTypeRef
val ex = ctx.newSymbol(meth, nme.ex, EmptyFlags, nonLocalReturnControl, coord = body.pos)
val pat = BindTyped(ex, nonLocalReturnControl)
val rhs = If(
diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala
index 2df7a9825..a47762ebe 100644
--- a/src/dotty/tools/dotc/transform/PatternMatcher.scala
+++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala
@@ -134,7 +134,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans
// for name-based matching, but this was an expedient route for the basics.
def drop(tgt: Tree)(n: Int): Tree = {
def callDirect = tgt.select(nme.drop).appliedTo(Literal(Constant(n)))
- def callRuntime = ref(defn.traversableDropMethod).appliedTo(tgt, Literal(Constant(n)))
+ def callRuntime = ref(defn.ScalaRuntime_drop).appliedTo(tgt, Literal(Constant(n)))
def needsRuntime = !(tgt.tpe derivesFrom defn.SeqClass) /*typeOfMemberNamedDrop(tgt.tpe) == NoType*/
@@ -201,7 +201,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans
// catchAll.isEmpty iff no synthetic default case needed (the (last) user-defined case is a default)
// if the last user-defined case is a default, it will never jump to the next case; it will go immediately to matchEnd
val catchAllDef = matchFailGen.map { _(scrutSym)}
- .getOrElse(Throw(New(defn.MatchErrorType, List(ref(scrutSym)))))
+ .getOrElse(Throw(New(defn.MatchErrorTypeRef, List(ref(scrutSym)))))
val matchFail = newSynthCaseLabel(ctx.freshName("matchFail"), MethodType(Nil, restpe))
val catchAllDefBody = DefDef(matchFail, catchAllDef)
@@ -878,7 +878,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans
// unlike in scalac SubstOnlyTreeMakers are maintained.
val casesRebindingPropagated = casesRaw map (propagateRebindings(_, NoRebindings))
- def matchFailGen = matchFailGenOverride orElse Some((arg: Symbol) => Throw(New(defn.MatchErrorType, List(ref(arg)))))
+ def matchFailGen = matchFailGenOverride orElse Some((arg: Symbol) => Throw(New(defn.MatchErrorTypeRef, List(ref(arg)))))
ctx.debuglog("combining cases: " + (casesRebindingPropagated.map(_.mkString(" >> ")).mkString("{", "\n", "}")))
diff --git a/src/dotty/tools/dotc/transform/SyntheticMethods.scala b/src/dotty/tools/dotc/transform/SyntheticMethods.scala
index fa931a379..a496f80ce 100644
--- a/src/dotty/tools/dotc/transform/SyntheticMethods.scala
+++ b/src/dotty/tools/dotc/transform/SyntheticMethods.scala
@@ -77,7 +77,7 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
coord = clazz.coord).enteredAfter(thisTransformer).asTerm
def forwardToRuntime(vrefss: List[List[Tree]]): Tree =
- ref(defn.runtimeMethod("_" + sym.name.toString)).appliedToArgs(This(clazz) :: vrefss.head)
+ ref(defn.runtimeMethodRef("_" + sym.name.toString)).appliedToArgs(This(clazz) :: vrefss.head)
def syntheticRHS(implicit ctx: Context): List[List[Tree]] => Tree = synthetic.name match {
case nme.hashCode_ if isDerivedValueClass(clazz) => vrefss => valueHashCodeBody
@@ -161,20 +161,17 @@ class SyntheticMethods(thisTransformer: DenotTransformer) {
}
/** The hashCode implementation for given symbol `sym`. */
- def hashImpl(sym: Symbol)(implicit ctx: Context): Tree = {
- val d = defn
- import d._
- sym.info.finalResultType.typeSymbol match {
- case UnitClass | NullClass => Literal(Constant(0))
- case BooleanClass => If(ref(sym), Literal(Constant(1231)), Literal(Constant(1237)))
- case IntClass => ref(sym)
- case ShortClass | ByteClass | CharClass => ref(sym).select(nme.toInt)
- case LongClass => ref(staticsMethod("longHash")).appliedTo(ref(sym))
- case DoubleClass => ref(staticsMethod("doubleHash")).appliedTo(ref(sym))
- case FloatClass => ref(staticsMethod("floatHash")).appliedTo(ref(sym))
- case _ => ref(staticsMethod("anyHash")).appliedTo(ref(sym))
+ def hashImpl(sym: Symbol)(implicit ctx: Context): Tree =
+ defn.scalaClassName(sym.info.finalResultType) match {
+ case tpnme.Unit | tpnme.Null => Literal(Constant(0))
+ case tpnme.Boolean => If(ref(sym), Literal(Constant(1231)), Literal(Constant(1237)))
+ case tpnme.Int => ref(sym)
+ case tpnme.Short | tpnme.Byte | tpnme.Char => ref(sym).select(nme.toInt)
+ case tpnme.Long => ref(defn.staticsMethod("longHash")).appliedTo(ref(sym))
+ case tpnme.Double => ref(defn.staticsMethod("doubleHash")).appliedTo(ref(sym))
+ case tpnme.Float => ref(defn.staticsMethod("floatHash")).appliedTo(ref(sym))
+ case _ => ref(defn.staticsMethod("anyHash")).appliedTo(ref(sym))
}
- }
/** The class
*
diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
index b2d45b661..80c3b654e 100644
--- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
+++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala
@@ -50,7 +50,7 @@ trait TypeTestsCasts {
Literal(Constant(true)) withPos tree.pos
else if (argCls.isPrimitiveValueClass)
if (qualCls.isPrimitiveValueClass) Literal(Constant(qualCls == argCls)) withPos tree.pos
- else transformIsInstanceOf(expr, defn.boxedClass(argCls).typeRef)
+ else transformIsInstanceOf(expr, defn.boxedTypeRef(argCls.typeRef)) // ### unstable
else argType.dealias match {
case _: SingletonType =>
val cmpOp = if (argType derivesFrom defn.AnyValClass) defn.Any_equals else defn.Object_eq
@@ -70,7 +70,7 @@ trait TypeTestsCasts {
}
case defn.MultiArrayType(elem, ndims) if isUnboundedGeneric(elem) =>
def isArrayTest(arg: Tree) =
- ref(defn.runtimeMethod(nme.isArray)).appliedTo(arg, Literal(Constant(ndims)))
+ ref(defn.runtimeMethodRef(nme.isArray)).appliedTo(arg, Literal(Constant(ndims)))
if (ndims == 1) isArrayTest(qual)
else evalOnce(qual) { qual1 =>
derivedTree(qual1, defn.Any_isInstanceOf, qual1.tpe) and isArrayTest(qual1)