diff options
author | Paul Phillips <paulp@improving.org> | 2010-03-20 04:24:39 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2010-03-20 04:24:39 +0000 |
commit | a4f00eaf4da004ee2fd8a1ac1135b465533415d4 (patch) | |
tree | 6bd5d70be6c2e7bcf2c2ef07514c67f4d45b4757 /src | |
parent | 44fddf75406a83017791677b53126fe9a6d6a17b (diff) | |
download | scala-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.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/CleanUp.scala | 38 |
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 |