summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2011-11-23 13:00:35 +0000
committerMartin Odersky <odersky@gmail.com>2011-11-23 13:00:35 +0000
commit579e999fbf59f540e2d6287fafa7f149ea2b0989 (patch)
treed36c9209601adfdade8171f0a0cb1fc45c6eac0a
parentf191dca582e47c8f01a030191c960e25411de0a4 (diff)
downloadscala-579e999fbf59f540e2d6287fafa7f149ea2b0989.tar.gz
scala-579e999fbf59f540e2d6287fafa7f149ea2b0989.tar.bz2
scala-579e999fbf59f540e2d6287fafa7f149ea2b0989.zip
Preparations for new version of AbstractPartial...
Preparations for new version of AbstractPartialFunctions that also does isDefinedAt correctly. Should be a new starr. Review by extempore.
-rw-r--r--src/compiler/scala/reflect/internal/StdNames.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala23
-rw-r--r--src/library/scala/PartialFunction.scala4
-rw-r--r--src/library/scala/runtime/AbstractPartialFunction.scala8
4 files changed, 28 insertions, 9 deletions
diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala
index 59d42b933f..cd31183d73 100644
--- a/src/compiler/scala/reflect/internal/StdNames.scala
+++ b/src/compiler/scala/reflect/internal/StdNames.scala
@@ -241,6 +241,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val applyDynamic: NameType = "applyDynamic"
val isArray: NameType = "isArray"
val isDefinedAt: NameType = "isDefinedAt"
+ val isDefinedAtCurrent: NameType = "isDefinedAtCurrent"
val isEmpty: NameType = "isEmpty"
val isInstanceOf_ : NameType = "isInstanceOf"
val java: NameType = "java"
@@ -248,6 +249,7 @@ trait StdNames extends /*reflect.generic.StdNames with*/ NameManglers { self: Sy
val length: NameType = "length"
val lengthCompare: NameType = "lengthCompare"
val lift_ : NameType = "lift"
+ val macro_ : NameType = "macro"
val main: NameType = "main"
val map: NameType = "map"
val missingCase: NameType = "missingCase"
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index c4bdb73744..f8cca67da7 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -216,7 +216,7 @@ abstract class UnCurry extends InfoTransform
/* Transform a function node (x_1,...,x_n) => body of type FunctionN[T_1, .., T_N, R] to
*
- * class $anon() extends Object() with FunctionN[T_1, .., T_N, R] with ScalaObject {
+ * class $anon() extends AbstractFunctionN[T_1, .., T_N, R] with Serializable {
* def apply(x_1: T_1, ..., x_N: T_n): R = body
* }
* new $anon()
@@ -225,10 +225,14 @@ abstract class UnCurry extends InfoTransform
* body = expr match { case P_i if G_i => E_i }_i=1..n
* to:
*
- * class $anon() extends Object() with PartialFunction[T, R] with ScalaObject {
+ * class $anon() extends AbstractPartialFunction[T, R] with Serializable {
* def apply(x: T): R = (expr: @unchecked) match {
- * { case P_i if G_i => E_i }_i=1..n
- * def isDefinedAt(x: T): boolean = (x: @unchecked) match {
+ * case P_1 if G_1 => E_1
+ * ...
+ * case P_n if G_n => true
+ * case _ => this.missingCase(x)
+ * }
+ * def isDefinedAtCurrent(x: T): boolean = (x: @unchecked) match {
* case P_1 if G_1 => true
* ...
* case P_n if G_n => true
@@ -237,9 +241,10 @@ abstract class UnCurry extends InfoTransform
* }
* new $anon()
*
- * However, if one of the patterns P_i if G_i is a default pattern, generate instead
+ * However, if one of the patterns P_i if G_i is a default pattern,
+ * drop the last default clause in tghe definition of `apply` and generate for `isDefinedAtCurrent` instead
*
- * def isDefinedAt(x: T): boolean = true
+ * def isDefinedAtCurrent(x: T): boolean = true
*/
def transformFunction(fun: Function): Tree = {
val fun1 = deEta(fun)
@@ -274,7 +279,11 @@ abstract class UnCurry extends InfoTransform
DefDef(Modifiers(FINAL), nme.apply, Nil, List(fun.vparams), TypeTree(restpe), body) setSymbol applyMethod
}
def isDefinedAtMethodDef() = {
- val m = anonClass.newMethod(fun.pos, nme.isDefinedAt) setFlag FINAL
+ val isDefinedAtName = {
+ if (anonClass.info.member(nme.isDefinedAtCurrent) != NoSymbol) nme.isDefinedAtCurrent
+ else nme.isDefinedAt
+ }
+ val m = anonClass.newMethod(fun.pos, isDefinedAtName) setFlag FINAL
m setInfo MethodType(m newSyntheticValueParams formals, BooleanClass.tpe)
anonClass.info.decls enter m
val vparam = fun.vparams.head.symbol
diff --git a/src/library/scala/PartialFunction.scala b/src/library/scala/PartialFunction.scala
index ac721b88bc..254a610648 100644
--- a/src/library/scala/PartialFunction.scala
+++ b/src/library/scala/PartialFunction.scala
@@ -48,6 +48,9 @@ trait PartialFunction[-A, +B] extends (A => B) {
else that.apply(x)
}
+ def orElseFast[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] =
+ orElse(that)
+
/** Composes this partial function with a transformation function that
* gets applied to results of this partial function.
* @param k the transformation function
@@ -90,6 +93,7 @@ object PartialFunction {
def isDefinedAt(x: Any) = false
def apply(x: Any): Nothing = throw new MatchError(x)
override def orElse[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
+ override def orElseFast[A1, B1](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = that
override def lift = (x: Any) => None
}
def empty[A, B] : PartialFunction[A, B] = empty_pf
diff --git a/src/library/scala/runtime/AbstractPartialFunction.scala b/src/library/scala/runtime/AbstractPartialFunction.scala
index 2a45ec3671..b188cbb37d 100644
--- a/src/library/scala/runtime/AbstractPartialFunction.scala
+++ b/src/library/scala/runtime/AbstractPartialFunction.scala
@@ -32,11 +32,15 @@ abstract class AbstractPartialFunction[-T1, +R]
// Question: Need to ensure that fallBack is overwritten before any access
// Is the `synchronized` here the right thing to achieve this?
// Is there a cheaper way?
- def orElseFast[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
+ override def orElseFast[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]) : PartialFunction[A1, B1] = {
val result = this.clone.asInstanceOf[AbstractPartialFunction[A1, B1]]
result.synchronized {
- result.fallBack = this.fallBack orElse that
+ result.fallBack = this.fallBack orElseFast that
result
}
}
+/*
+ def isDefinedAt(x: T1): scala.Boolean = isDefinedAtCurrent(x) || fallBack.isDefinedAt(x)
+ def isDefinedAtCurrent(x: T1): scala.Boolean = false
+*/
}