summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-11-01 16:28:16 +0000
committerMartin Odersky <odersky@gmail.com>2006-11-01 16:28:16 +0000
commit40990494c7e8007850ef0e010b0889acfcb77162 (patch)
tree2816fe32fc061f27512edbc0640c2070862319ad /src/compiler
parent257a1845d3db3477a0b5939e94d77b0495d89561 (diff)
downloadscala-40990494c7e8007850ef0e010b0889acfcb77162.tar.gz
scala-40990494c7e8007850ef0e010b0889acfcb77162.tar.bz2
scala-40990494c7e8007850ef0e010b0889acfcb77162.zip
enabled isinstanceof of intersection types (fix...
enabled isinstanceof of intersection types (fixed bug789)
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala51
1 files changed, 35 insertions, 16 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index b174e5747a..2cb7cb2c05 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -141,6 +141,16 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
}
}
+ private def evalOnce(expr: Tree, owner: Symbol, unit: CompilationUnit)
+ (within: (() => Tree) => Tree): Tree =
+ if (treeInfo.isPureExpr(expr)) {
+ within(() => expr);
+ } else {
+ val temp = owner.newValue(expr.pos, unit.fresh.newName())
+ .setFlag(SYNTHETIC).setInfo(expr.tpe);
+ Block(List(ValDef(temp, expr)), within(() => Ident(temp) setType expr.tpe))
+ }
+
// -------- boxing/unboxing --------------------------------------------------------
override def newTyper(context: Context) = new Eraser(context)
@@ -148,15 +158,6 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
/** The modifier typer which retypes with erased types. */
class Eraser(context: Context) extends Typer(context) {
- private def evalOnce(expr: Tree, within: (() => Tree) => Tree): Tree =
- if (treeInfo.isPureExpr(expr)) {
- within(() => expr);
- } else {
- val temp = context.owner.newValue(expr.pos, context.unit.fresh.newName())
- .setFlag(SYNTHETIC).setInfo(expr.tpe);
- Block(List(ValDef(temp, expr)), within(() => Ident(temp) setType expr.tpe))
- }
-
/** Box `tree' of unboxed type */
private def box(tree: Tree): Tree =
typed {
@@ -237,7 +238,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
if (pt.symbol == ArrayClass)
typed {
atPos(tree.pos) {
- evalOnce(tree, x =>
+ evalOnce(tree, context.owner, context.unit) { x =>
gen.mkAttributedCast(
If(
Apply(
@@ -247,13 +248,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
List()),
unbox(gen.mkAttributedCast(x(), BoxedArrayClass.tpe), pt),
x()),
- pt))
+ pt)
+ }
}
}
else if (pt.symbol isNonBottomSubClass BoxedArrayClass)
typed {
atPos(tree.pos) {
- evalOnce(tree, x =>
+ evalOnce(tree, context.owner, context.unit) { x =>
gen.mkAttributedCast(
If(
Apply(
@@ -263,13 +265,14 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
List()),
x(),
boxArray(x())),
- pt))
+ pt)
+ }
}
}
else if ((SeqClass isNonBottomSubClass pt.symbol) && pt.symbol != ObjectClass)
typed {
atPos(tree.pos) {
- evalOnce(tree, x =>
+ evalOnce(tree, context.owner, context.unit) { x =>
gen.mkAttributedCast(
If(
Apply(
@@ -279,7 +282,8 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
List()),
x(),
boxArray(x())),
- pt))
+ pt)
+ }
}
}
else gen.mkAttributedCast(tree, pt)
@@ -637,13 +641,28 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
// todo: also handle the case where the singleton type is buried in a compound
else if (fn.symbol == Any_isInstanceOf || fn.symbol == Any_isInstanceOfErased)
fn match {
- case TypeApply(Select(qual, _), List(targ)) =>
+ case TypeApply(sel @ Select(qual, name), List(targ)) =>
targ.tpe match {
case SingleType(pre, sym) =>
val cmpOp = if (targ.tpe <:< AnyValClass.tpe) Any_equals else Object_eq
atPos(tree.pos) {
Apply(Select(qual, cmpOp), List(gen.mkAttributedQualifier(targ.tpe)))
}
+ case RefinedType(parents, decls) if (parents.length >= 2) =>
+ evalOnce(qual, currentOwner, unit) {
+ q =>
+ def mkIsInstanceOf(tp: Type) =
+ copy.Apply(tree,
+ copy.TypeApply(fn,
+ copy.Select(sel, q(), name),
+ List(TypeTree(tp))),
+ List())
+ def mkAnd(tree1: Tree, tree2: Tree) =
+ atPos(tree1.pos) {
+ Apply(Select(tree1, Boolean_and), List(tree2))
+ }
+ parents map mkIsInstanceOf reduceRight mkAnd
+ }
case _ =>
tree
}