diff options
author | Paul Phillips <paulp@improving.org> | 2009-06-28 19:36:31 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-06-28 19:36:31 +0000 |
commit | e3bb9bfa5cdaa4ef293713a7bebb189f73732e6d (patch) | |
tree | 331bc2f1d133bdc09b0792d0591f0a6cd8c8fb8b /src/compiler/scala/tools/nsc/transform/Erasure.scala | |
parent | e32113307c381e8bc8558208a6076f60666784a2 (diff) | |
download | scala-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.scala | 149 |
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) } |