summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2010-03-20 04:24:39 +0000
committerPaul Phillips <paulp@improving.org>2010-03-20 04:24:39 +0000
commita4f00eaf4da004ee2fd8a1ac1135b465533415d4 (patch)
tree6bd5d70be6c2e7bcf2c2ef07514c67f4d45b4757 /src
parent44fddf75406a83017791677b53126fe9a6d6a17b (diff)
downloadscala-a4f00eaf4da004ee2fd8a1ac1135b465533415d4.tar.gz
scala-a4f00eaf4da004ee2fd8a1ac1135b465533415d4.tar.bz2
scala-a4f00eaf4da004ee2fd8a1ac1135b465533415d4.zip
Some work on the Array methods as they manifest...
Some work on the Array methods as they manifest in refinement types: tightening when Array code is generated and also what code is generated. Review by dubochet.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala (renamed from src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala)0
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala38
3 files changed, 24 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala b/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala
index 9d102eef28..9d102eef28 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/CheckerException.scala
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 98f87ca362..5ce0025de5 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -295,6 +295,7 @@ trait StdNames extends reflect.generic.StdNames { self: SymbolTable =>
val hasNext = newTermName("hasNext")
val head = newTermName("head")
val invoke_ = newTermName("invoke")
+ val isArray = newTermName("isArray")
val isInstanceOf_ = newTermName("isInstanceOf")
val isDefinedAt = newTermName("isDefinedAt")
val isEmpty = newTermName("isEmpty")
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 114f49ad50..107a73aa66 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -338,6 +338,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val methSym = ad.symbol
def args = qual :: params
+ def isArrayMethodSignature = {
+ def typesMatchApply = paramTypes match {
+ case List(tp) => tp <:< IntClass.tpe
+ case _ => false
+ }
+ def typesMatchUpdate = paramTypes match {
+ case List(tp1, tp2) => (tp1 <:< IntClass.tpe) && (UnitClass.tpe <:< structResType)
+ case _ => false
+ }
+
+ (methSym.name == nme.length && params.isEmpty) ||
+ (methSym.name == nme.clone_ && params.isEmpty) ||
+ (methSym.name == nme.apply && typesMatchApply) ||
+ (methSym.name == nme.update && typesMatchUpdate)
+ }
+
/** Normal non-Array call */
def defaultCall = {
// reflective method call machinery
@@ -361,33 +377,25 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
(getPrimitiveReplacementForStructuralCall isDefinedAt methSym.name) &&
((resType :: paramTypes) forall (x => isJavaValueClass(x.typeSymbol))) // issue #1110
- def isArrayMethodSignature =
- (methSym.name == nme.length && params.isEmpty) ||
- (methSym.name == nme.update && (structResType.typeSymbol eq UnitClass) && params.size == 2) ||
- (methSym.name == nme.apply && params.size == 1) ||
- (methSym.name == nme.clone_ && params.isEmpty)
-
- def isDefinitelyArray = isArrayMethodSignature && (qualSym == ArrayClass)
- def isMaybeArray = isArrayMethodSignature && (qualSym == ObjectClass) // precondition: !isDefinitelyArray
-
def genArrayCall = methSym.name match {
case nme.length => REF(boxMethod(IntClass)) APPLY (REF(arrayLengthMethod) APPLY args)
case nme.update => REF(arrayUpdateMethod) APPLY List(args(0), (REF(unboxMethod(IntClass)) APPLY args(1)), args(2))
case nme.apply => REF(arrayApplyMethod) APPLY List(args(0), (REF(unboxMethod(IntClass)) APPLY args(1)))
case nme.clone_ => REF(arrayCloneMethod) APPLY List(args(0))
}
- def genArrayTest = {
- def oneTest(s: Symbol) = qual IS_OBJ arrayType(s.tpe)
- OR((ObjectClass :: ScalaValueClasses filterNot (_ eq UnitClass)) map oneTest: _*)
- }
+ def genConditionalArrayCall =
+ IF ((qual GETCLASS()) DOT nme.isArray) THEN genArrayCall ELSE defaultCall
val callCode =
if (useValueOperator) {
val (operator, test) = getPrimitiveReplacementForStructuralCall(methSym.name)
IF (test) THEN fixResult(REF(operator) APPLY args) ELSE defaultCall
}
- else if (isDefinitelyArray) genArrayCall
- else if (isMaybeArray) IF (genArrayTest) THEN genArrayCall ELSE defaultCall
+ else if (isArrayMethodSignature) {
+ if (qualSym == ArrayClass) genArrayCall
+ else if (qualSym == ObjectClass) genConditionalArrayCall
+ else defaultCall
+ }
else defaultCall
localTyper typed callCode