summaryrefslogtreecommitdiff
path: root/src/compiler
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
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')
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala149
-rw-r--r--src/compiler/scala/tools/nsc/transform/LazyVals.scala29
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala8
4 files changed, 70 insertions, 121 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 884e54a21d..7e5e133345 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -139,7 +139,10 @@ trait TreeDSL {
val arg = if (msg == null) Nil else List(msg.TOSTRING)
Throw(New(TypeTree(sym.tpe), List(arg)))
}
- def NEW(tpe: Tree, args: Tree*) = New(tpe, List(args.toList))
+ def NEW(tpe: Tree, args: Tree*) = New(tpe, List(args.toList))
+ def NEW(sym: Symbol, args: Tree*) =
+ if (args.isEmpty) New(TypeTree(sym.tpe))
+ else New(TypeTree(sym.tpe), List(args.toList))
def VAL(sym: Symbol) = new ValStart(sym)
def DEF(sym: Symbol) = new DefStart(sym)
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)
}
diff --git a/src/compiler/scala/tools/nsc/transform/LazyVals.scala b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
index 21370c3176..e8db58c2bc 100644
--- a/src/compiler/scala/tools/nsc/transform/LazyVals.scala
+++ b/src/compiler/scala/tools/nsc/transform/LazyVals.scala
@@ -9,6 +9,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
import global._ // the global environment
import definitions._ // standard classes and methods
import typer.{typed, atOwner} // methods to type trees
+ import CODE._
val phaseName: String = "lazyvals"
@@ -20,8 +21,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
/** The phase defined by this transform */
class Phase(prev: scala.tools.nsc.Phase) extends StdPhase(prev) {
- def apply(unit: global.CompilationUnit): Unit =
- newTransformer(unit).transformUnit(unit);
+ def apply(unit: global.CompilationUnit): Unit = newTransformer(unit) transformUnit unit
}
/**
@@ -92,7 +92,7 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
case _ => Block(stats, tree)
}
- val bmps = bitmaps(methSym) map { b => ValDef(b, Literal(Constant(0))) }
+ val bmps = bitmaps(methSym) map (ValDef(_, ZERO))
if (bmps.isEmpty) rhs else rhs match {
case Block(assign, l @ LabelDef(name, params, rhs1))
if (name.toString.equals("_" + methSym.name)
@@ -104,8 +104,6 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
}
}
- import CODE._
-
/** return a 'lazified' version of rhs. Rhs should conform to the
* following schema:
* {
@@ -135,21 +133,20 @@ abstract class LazyVals extends Transform with ast.TreeDSL {
* }
*/
private def mkLazyDef(meth: Symbol, tree: Tree, offset: Int): Tree = {
- val bitmapSym = getBitmapFor(meth, offset)
- val mask = Literal(Constant(1 << (offset % FLAGS_PER_WORD)))
+ val bitmapSym = getBitmapFor(meth, offset)
+ val mask = LIT(1 << (offset % FLAGS_PER_WORD))
+ def mkBlock(stmt: Tree) = BLOCK(stmt, mkSetFlag(bitmapSym, mask), UNIT)
val (block, res) = tree match {
- case Block(List(assignment), res) =>
- (Block(List(assignment, mkSetFlag(bitmapSym, mask)), Literal(Constant(()))), res)
- case rhs =>
- assert(meth.tpe.finalResultType.typeSymbol == definitions.UnitClass)
- (Block(List(rhs, mkSetFlag(bitmapSym, mask)), Literal(Constant(()))), Literal(()))
+ case Block(List(assignment), res) => (mkBlock(assignment), res)
+ case rhs => (mkBlock(rhs), UNIT)
}
+ assert(res != UNIT || meth.tpe.finalResultType.typeSymbol == UnitClass)
- val result = atPos(tree.pos) {
- IF ((Ident(bitmapSym) INT_& mask) INT_== ZERO) THEN block ENDIF
- }
- typed(Block(List(result), res))
+ atPos(tree.pos)(typed {
+ def body = { IF ((Ident(bitmapSym) INT_& mask) INT_== ZERO) THEN block ENDIF }
+ BLOCK(body, res)
+ })
}
private def mkSetFlag(bmp: Symbol, mask: Tree): Tree =
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index 56bcd34cd2..bcab93b461 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -459,14 +459,14 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
/** Create a static reference to given symbol <code>sym</code> of the
* form <code>M.sym</code> where M is the symbol's implementation module.
*/
- private def staticRef(sym: Symbol) = {
+ private def staticRef(sym: Symbol): Tree = {
sym.owner.info //todo: needed?
sym.owner.owner.info //todo: needed?
if (sym.owner.sourceModule == NoSymbol) {
assert(false, "" + sym + " in " + sym.owner + " in " + sym.owner.owner +
" " + sym.owner.owner.info.decls.toList)//debug
}
- Select(gen.mkAttributedRef(sym.owner.sourceModule), sym)
+ REF(sym.owner.sourceModule) DOT sym
}
/** Add all new definitions to a non-trait class
@@ -542,9 +542,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
def completeSuperAccessor(stat: Tree) = stat match {
case DefDef(mods, name, tparams, List(vparams), tpt, EmptyTree)
if (stat.symbol hasFlag SUPERACCESSOR) =>
- val rhs0 =
- Apply(Select(Super(clazz, nme.EMPTY.toTypeName), stat.symbol.alias),
- vparams map (vparam => Ident(vparam.symbol)))
+ val rhs0 = (Super(clazz, nme.EMPTY.toTypeName) DOT stat.symbol.alias)(vparams map (v => Ident(v.symbol)): _*)
val rhs1 = localTyper.typed(atPos(stat.pos)(rhs0), stat.symbol.tpe.resultType)
val rhs2 = atPhase(currentRun.mixinPhase)(transform(rhs1))
if (settings.debug.value)