summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/Erasure.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-06-28 19:36:31 +0000
committerPaul Phillips <paulp@improving.org>2009-06-28 19:36:31 +0000
commite3bb9bfa5cdaa4ef293713a7bebb189f73732e6d (patch)
tree331bc2f1d133bdc09b0792d0591f0a6cd8c8fb8b /src/compiler/scala/tools/nsc/transform/Erasure.scala
parente32113307c381e8bc8558208a6076f60666784a2 (diff)
downloadscala-e3bb9bfa5cdaa4ef293713a7bebb189f73732e6d.tar.gz
scala-e3bb9bfa5cdaa4ef293713a7bebb189f73732e6d.tar.bz2
scala-e3bb9bfa5cdaa4ef293713a7bebb189f73732e6d.zip
DSL refinement continues apace.
good-sized whacks on Erasure.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Erasure.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala149
1 files changed, 50 insertions, 99 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 188bab5810..8ed3aaef88 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -13,7 +13,8 @@ import scala.tools.nsc.util.Position
import symtab._
import Flags._
-abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
+abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.TreeDSL
+{
import global._ // the global environment
import definitions._ // standard classes and methods
// @S: XXX: why is this here? earsure is a typer, if you comment this
@@ -21,6 +22,9 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
lazy val typerXXX = this.typer
import typerXXX.{typed} // methods to type trees
+ import CODE._
+ def typedPos(pos: Position)(tree: Tree) = typed { atPos(pos)(tree) }
+
val phaseName: String = "erasure"
def newTransformer(unit: CompilationUnit): Transformer =
@@ -371,20 +375,15 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val rhs1 = box(rhs)
treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe
case _ =>
- typed {
- atPos(tree.pos) {
- val sym = tree.tpe.typeSymbol;
- if (sym == UnitClass) {
- if (treeInfo.isPureExpr(tree)) gen.mkAttributedRef(BoxedUnit_UNIT)
- else Block(List(tree), gen.mkAttributedRef(BoxedUnit_UNIT))
- } else if (sym == ArrayClass) {
- boxArray(tree)
- } else {
- Apply(gen.mkAttributedRef(boxMethod(tree.tpe.typeSymbol)), List(tree)).
- setPos(tree.pos) setType ObjectClass.tpe
- }
- }
- }
+ typedPos(tree.pos)(tree.tpe.typeSymbol match {
+ case UnitClass =>
+ if (treeInfo isPureExpr tree) REF(BoxedUnit_UNIT)
+ else BLOCK(tree, REF(BoxedUnit_UNIT))
+ case ArrayClass =>
+ boxArray(tree)
+ case x =>
+ (REF(boxMethod(x)) APPLY tree) setPos (tree.pos) setType (ObjectClass.tpe)
+ })
}
/** generate ScalaRuntime.boxArray(tree) */
@@ -393,11 +392,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val rhs1 = boxArray(rhs)
treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe
case _ =>
- typed {
- atPos(tree.pos) {
- gen.mkRuntimeCall(nme.boxArray, List(tree))
- }
- }
+ typedPos(tree.pos) { gen.mkRuntimeCall(nme.boxArray, List(tree)) }
}
/** Unbox <code>tree</code> of boxed type to expected type <code>pt</code>.
@@ -411,23 +406,16 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
val rhs1 = unbox(rhs, pt)
treeCopy.LabelDef(tree, name, params, rhs1) setType rhs1.tpe
case _ =>
- typed {
- atPos(tree.pos) {
- if (pt.typeSymbol == UnitClass) {
- if (treeInfo.isPureExpr(tree)) Literal(())
- else Block(List(tree), Literal(()))
- }
- else if (pt.typeSymbol == ArrayClass) {
- val tree1 = adaptToType(tree, BoxedArrayClass.tpe)
- gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head)))
- }
- else {
- atPos(tree.pos) {
- Apply(gen.mkAttributedRef(unboxMethod(pt.typeSymbol)), List(tree)) setType pt
- }
- }
- }
- }
+ typedPos(tree.pos)(pt.typeSymbol match {
+ case UnitClass =>
+ if (treeInfo isPureExpr tree) UNIT
+ else BLOCK(tree, UNIT)
+ case ArrayClass =>
+ val tree1 = adaptToType(tree, BoxedArrayClass.tpe)
+ gen.mkRuntimeCall(nme.arrayValue, List(tree1, Literal(pt.typeArgs.head)))
+ case _ =>
+ (REF(unboxMethod(pt.typeSymbol)) APPLY tree) setType pt
+ })
}
/** <p>
@@ -451,61 +439,25 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
*/
private def cast(tree: Tree, pt: Type): Tree = {
assert(pt eq pt.normalize)
+ def asPt(t: Tree) = t AS_ATTR pt
+ def once(within: (() => Tree) => Tree) =
+ typedPos(tree.pos)(gen.evalOnce(tree, context.owner, context.unit)(within andThen asPt))
if (tree.tpe.typeSymbol == ObjectClass) {
- if (pt.typeSymbol == ArrayClass)
- typed {
- atPos(tree.pos) {
- gen.evalOnce(tree, context.owner, context.unit) { x =>
- gen.mkAttributedCast(
- If(
- Apply(
- TypeApply(
- Select(x(), Object_isInstanceOf),
- List(TypeTree(BoxedArrayClass.tpe))),
- List()),
- unbox(gen.mkAttributedCast(x(), BoxedArrayClass.tpe), pt),
- x()),
- pt)
- }
- }
- }
- else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass)
- typed {
- atPos(tree.pos) {
- gen.evalOnce(tree, context.owner, context.unit) { x =>
- gen.mkAttributedCast(
- If(
- Apply(
- TypeApply(
- Select(x(), Object_isInstanceOf),
- List(TypeTree(BoxedArrayClass.tpe))),
- List()),
- x(),
- boxArray(x())),
- pt)
- }
- }
- }
- else if (isSeqClass(pt.typeSymbol))
- typed {
- atPos(tree.pos) {
- gen.evalOnce(tree, context.owner, context.unit) { x =>
- gen.mkAttributedCast(
- If(
- Apply(
- TypeApply(
- Select(x(), Object_isInstanceOf),
- List(TypeTree(pt))),
- List()),
- x(),
- boxArray(x())),
- pt)
- }
- }
- }
- else gen.mkAttributedCast(tree, pt)
- } else gen.mkAttributedCast(tree, pt)
+ if (pt.typeSymbol == ArrayClass) once (x =>
+ (IF (x() IS_OBJ BoxedArrayClass.tpe)
+ THEN (unbox(x() AS_ATTR BoxedArrayClass.tpe, pt))
+ ELSE (x())
+ )
+ )
+ else if (pt.typeSymbol isNonBottomSubClass BoxedArrayClass) once (x =>
+ (IF (x() IS_OBJ BoxedArrayClass.tpe) THEN (x()) ELSE boxArray(x()))
+ )
+ else if (isSeqClass(pt.typeSymbol)) once (x =>
+ (IF (x() IS_OBJ pt) THEN (x()) ELSE (boxArray(x())))
+ )
+ else asPt(tree)
+ } else asPt(tree)
}
/** Is symbol a member of unboxed arrays (which will be expanded directly
@@ -514,9 +466,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
* @param sym ..
* @return <code>true</code> if ..
*/
- private def isUnboxedArrayMember(sym: Symbol) =
- sym.name == nme.apply || sym.name == nme.length || sym.name == nme.update ||
- sym.owner == ObjectClass
+ private def isUnboxedArrayMember(sym: Symbol) = sym.name match {
+ case nme.apply | nme.length | nme.update => true
+ case _ => sym.owner == ObjectClass
+ }
private def isUnboxedValueMember(sym: Symbol) =
sym != NoSymbol && isValueClass(sym.owner)
@@ -606,12 +559,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
tree match {
case Apply(Select(New(tpt), name), args) if (tpt.tpe.typeSymbol == BoxedArrayClass) =>
assert(name == nme.CONSTRUCTOR);
- val translated =
- if (args.length >= 2) {
- Select(gen.mkAttributedRef(ArrayModule), nme.withDims)
- } else {
- Select(New(TypeTree(BoxedAnyArrayClass.tpe)), name)
- }
+ val translated: Tree =
+ if (args.length >= 2) REF(ArrayModule) DOT nme.withDims
+ else NEW(BoxedAnyArrayClass) DOT name
+
atPos(tree.pos) {
Typed(Apply(translated, args), tpt)
}