summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormichelou <michelou@epfl.ch>2010-12-30 23:53:00 +0000
committermichelou <michelou@epfl.ch>2010-12-30 23:53:00 +0000
commitbf375f7d6375a2e437342a6d3b935048fa3ec545 (patch)
tree34a6d17021ee734f365c6044c4ceea1ad3cde8ea /src
parent096bc81a90b746ea3fa8a5bd8eb9009c08a71082 (diff)
downloadscala-bf375f7d6375a2e437342a6d3b935048fa3ec545.tar.gz
scala-bf375f7d6375a2e437342a6d3b935048fa3ec545.tar.bz2
scala-bf375f7d6375a2e437342a6d3b935048fa3ec545.zip
fixed issue with EnclosingMethod attribute.
The above issue was made explicit using the dx tool for the Android SDK to convert Java bytecode to Dalvik bytecode.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala38
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala83
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala59
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala5
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala39
-rw-r--r--src/library/scala/collection/TraversableLike.scala91
8 files changed, 184 insertions, 164 deletions
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index c8085e58a1..a3a04e34b9 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -236,11 +236,11 @@ object ScriptRunner {
*/
private def runCompiled(
settings: GenericRunnerSettings,
- compiledLocation: String,
- scriptArgs: List[String]): Boolean =
- {
- val pr = new PathResolver(settings)
- val classpath = File(compiledLocation).toURL +: pr.asURLs
+ compiledLocation: String,
+ scriptArgs: List[String]): Boolean =
+ {
+ val pr = new PathResolver(settings)
+ val classpath = File(compiledLocation).toURL +: pr.asURLs
ObjectRunner.runAndCatch(classpath, scriptMain(settings), scriptArgs) match {
case Left(ex) => ex.printStackTrace() ; false
@@ -255,13 +255,13 @@ object ScriptRunner {
*/
def runScript(
settings: GenericRunnerSettings,
- scriptFile: String,
- scriptArgs: List[String]): Boolean =
- {
- if (File(scriptFile).isFile)
- withCompiledScript(settings, scriptFile) { runCompiled(settings, _, scriptArgs) }
- else
- throw new IOException("no such file: " + scriptFile)
+ scriptFile: String,
+ scriptArgs: List[String]): Boolean =
+ {
+ if (File(scriptFile).isFile)
+ withCompiledScript(settings, scriptFile) { runCompiled(settings, _, scriptArgs) }
+ else
+ throw new IOException("no such file: " + scriptFile)
}
/** Calls runScript and catches the enumerated exceptions, routing
@@ -269,11 +269,11 @@ object ScriptRunner {
*/
def runScriptAndCatch(
settings: GenericRunnerSettings,
- scriptFile: String,
- scriptArgs: List[String]): Either[Throwable, Boolean] =
- {
- try Right(runScript(settings, scriptFile, scriptArgs))
- catch { case e => Left(unwrap(e)) }
+ scriptFile: String,
+ scriptArgs: List[String]): Either[Throwable, Boolean] =
+ {
+ try Right(runScript(settings, scriptFile, scriptArgs))
+ catch { case e => Left(unwrap(e)) }
}
/** Run a command
@@ -283,8 +283,8 @@ object ScriptRunner {
def runCommand(
settings: GenericRunnerSettings,
command: String,
- scriptArgs: List[String]) : Boolean =
- {
+ scriptArgs: List[String]): Boolean =
+ {
val scriptFile = File.makeTemp("scalacmd", ".scala")
// save the command to the file
scriptFile writeAll command
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
index e0a06fa076..301dbd18d6 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenAndroid.scala
@@ -1,7 +1,9 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Stephane Micheloud
*/
+
package scala.tools.nsc
package backend.jvm
@@ -15,20 +17,27 @@ trait GenAndroid {
import icodes._
import opcodes._
+ /** From the reference documentation of the Android SDK:
+ * The `Parcelable` interface identifies classes whose instances can be
+ * written to and restored from a `Parcel`. Classes implementing the
+ * `Parcelable` interface must also have a static field called `CREATOR`,
+ * which is an object implementing the `Parcelable.Creator` interface.
+ */
private val fieldName = "CREATOR"
+
private lazy val AndroidParcelableInterface =
try definitions.getClass("android.os.Parcelable")
catch { case _: FatalError => NoSymbol }
+
private lazy val AndroidCreatorClass =
if (AndroidParcelableInterface == NoSymbol) NoSymbol
else definitions.getClass("android.os.Parcelable$Creator")
- def isAndroidParcelableClass(sym: Symbol) = (
+ def isAndroidParcelableClass(sym: Symbol) =
(AndroidParcelableInterface != NoSymbol) &&
(sym.info.parents contains AndroidParcelableInterface.tpe)
- )
- def addCreatorCode(codegen: BytecodeGenerator, block: BasicBlock) = {
+ def addCreatorCode(codegen: BytecodeGenerator, block: BasicBlock) {
import codegen._
val fieldSymbol = clasz.symbol.newValue(NoPosition, newTermName(fieldName))
.setFlag(Flags.STATIC | Flags.FINAL)
@@ -39,7 +48,7 @@ trait GenAndroid {
block emit STORE_FIELD(fieldSymbol, true)
}
- def legacyAddCreatorCode(codegen: BytecodeGenerator, clinit: JExtendedCode) = {
+ def legacyAddCreatorCode(codegen: BytecodeGenerator, clinit: JExtendedCode) {
import codegen._
val creatorType = javaType(AndroidCreatorClass)
jclass.addNewField(PublicStaticFinal,
@@ -53,4 +62,5 @@ trait GenAndroid {
new JMethodType(creatorType, Array()))
clinit.emitPUTSTATIC(jclass.getName(), fieldName, creatorType)
}
+
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 18f82d51be..df0220ffe3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -1,5 +1,5 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
* @author Iulian Dragos
*/
@@ -7,9 +7,11 @@
package scala.tools.nsc
package backend.jvm
+import java.io.DataOutputStream
import java.nio.ByteBuffer
import scala.collection.{ mutable, immutable }
import mutable.{ ListBuffer, LinkedHashSet }
+import scala.reflect.generic.{ PickleFormat, PickleBuffer }
import scala.tools.nsc.io.AbstractFile
import scala.tools.nsc.symtab._
import scala.tools.nsc.symtab.classfile.ClassfileConstants._
@@ -17,8 +19,6 @@ import scala.tools.nsc.symtab.classfile.ClassfileConstants._
import ch.epfl.lamp.fjbg._
import JAccessFlags._
import JObjectType.{ JAVA_LANG_STRING, JAVA_LANG_OBJECT }
-import java.io.{ DataOutputStream }
-import reflect.generic.{ PickleFormat, PickleBuffer }
/** This class ...
*
@@ -91,7 +91,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
def label = if (ok) "[ OK ] " else "[BAD!] "
if (settings.verbose.value || !ok)
- Console.println(label + sym + " in " + sym.owner.skipPackageObject.fullName + "\n " + sig)
+ println(label + sym + " in " + sym.owner.skipPackageObject.fullName + "\n " + sig)
}
val MIN_SWITCH_DENSITY = 0.7
@@ -194,7 +194,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
val sigBytes = ScalaSigBytes(pickle.bytes.take(pickle.writeIndex))
AnnotationInfo(sigBytes.sigAnnot, Nil, List((nme.bytes, sigBytes)))
}
- pickledBytes = pickledBytes + pickle.writeIndex
+ pickledBytes += pickle.writeIndex
currentRun.symData -= sym
currentRun.symData -= sym.companionSymbol
Some(scalaAnnot)
@@ -212,9 +212,6 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
private val innerClassBuffer = new ListBuffer[Symbol]
def genClass(c: IClass) {
- val needsEnclosingMethod: Boolean =
- c.symbol.isClass && (c.symbol.originalEnclosingMethod != NoSymbol)
-
clasz = c
innerClassBuffer.clear()
@@ -294,23 +291,34 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
val ssa = scalaSignatureAddingMarker(jclass, c.symbol)
addGenericSignature(jclass, c.symbol, c.symbol.owner)
addAnnotations(jclass, c.symbol.annotations ++ ssa)
- if (needsEnclosingMethod) addEnclosingMethodAttribute(jclass, c.symbol)
+ addEnclosingMethodAttribute(jclass, c.symbol)
emitClass(jclass, c.symbol)
if (c.symbol hasAnnotation BeanInfoAttr)
genBeanInfoClass(c)
}
- def addEnclosingMethodAttribute(jclass: JClass, clazz: Symbol) {
+ private def addEnclosingMethodAttribute(jclass: JClass, clazz: Symbol) {
val sym = clazz.originalEnclosingMethod
if (sym.isMethod) {
- log("enclosing method for %s is %s".format(clazz, sym))
+ log("enclosing method for %s is %s (%s)".format(clazz, sym, sym.enclClass))
jclass addAttribute fjbgContext.JEnclosingMethodAttribute(
jclass,
javaName(sym.enclClass),
javaName(sym),
javaType(sym)
)
+ } else if (clazz.isAnonymousClass) {
+ val enclClass = clazz.rawowner
+ assert(enclClass.isClass)
+ val sym = enclClass.primaryConstructor
+ log("enclosing method for %s is %s (%s)".format(clazz, sym, enclClass))
+ jclass addAttribute fjbgContext.JEnclosingMethodAttribute(
+ jclass,
+ javaName(enclClass),
+ javaName(sym),
+ JMethodType.ARGLESS_VOID_FUNCTION
+ )
}
}
@@ -601,7 +609,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
* That means non-member classes (anonymous). See Section 4.7.5 in the JVMS.
*/
def outerName(innerSym: Symbol): String = {
- if (innerSym.isAnonymousClass || innerSym.isAnonymousFunction || innerSym.originalEnclosingMethod != NoSymbol)
+ if (innerSym.originalEnclosingMethod != NoSymbol)
null
else {
val outerName = javaName(innerSym.rawowner)
@@ -629,19 +637,16 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
// to satisfy the Eclipse Java compiler
//for (innerSym <- innerClasses.toList sortBy (_.name.length)) {
for (innerSym <- allInners.distinct sortBy (_.name.length)) {
- val outer = outerName(innerSym)
- if (outer != null) {
- var flags = javaFlags(innerSym)
- if (innerSym.rawowner.hasModuleFlag)
- flags |= ACC_STATIC
-
- innerClassesAttr.addEntry(
- javaName(innerSym),
- outer,
- innerName(innerSym),
- (flags & INNER_CLASSES_FLAGS)
- )
- }
+ var flags = javaFlags(innerSym)
+ if (innerSym.rawowner.hasModuleFlag)
+ flags |= ACC_STATIC
+
+ innerClassesAttr.addEntry(
+ javaName(innerSym),
+ outerName(innerSym),
+ innerName(innerSym),
+ flags & INNER_CLASSES_FLAGS
+ )
}
}
}
@@ -729,7 +734,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
genCode(m)
if (emitVars)
- genLocalVariableTable(m, jcode);
+ genLocalVariableTable(m, jcode)
}
addGenericSignature(jmethod, m.symbol, clasz.symbol)
@@ -1142,7 +1147,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
else
jcode.emitGETSTATIC(javaName(module) /* + "$" */ ,
nme.MODULE_INSTANCE_FIELD.toString,
- javaType(module));
+ javaType(module))
case STORE_ARRAY_ITEM(kind) =>
jcode emitASTORE javaType(kind)
@@ -1283,7 +1288,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
case JUMP(whereto) =>
if (nextBlock != whereto)
- jcode.emitGOTO_maybe_W(labels(whereto), false); // default to short jumps
+ jcode.emitGOTO_maybe_W(labels(whereto), false) // default to short jumps
case CJUMP(success, failure, cond, kind) =>
kind match {
@@ -1594,12 +1599,12 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
case Conversion(src, dst) =>
if (settings.debug.value)
- log("Converting from: " + src + " to: " + dst);
+ log("Converting from: " + src + " to: " + dst)
if (dst == BOOL) {
- Console.println("Illegal conversion at: " + clasz +
- " at: " + pos.source + ":" + pos.line);
+ println("Illegal conversion at: " + clasz +
+ " at: " + pos.source + ":" + pos.line)
} else
- jcode.emitT2T(javaType(src), javaType(dst));
+ jcode.emitT2T(javaType(src), javaType(dst))
case ArrayLength(_) =>
jcode.emitARRAYLENGTH()
@@ -1657,11 +1662,11 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
val lvTab = ByteBuffer.allocate(2 + 10 * entries)
def emitEntry(name: String, signature: String, idx: Short, start: Short, end: Short) {
- lvTab.putShort(start)
- lvTab.putShort(end)
- lvTab.putShort(pool.addUtf8(name).toShort)
- lvTab.putShort(pool.addUtf8(signature).toShort)
- lvTab.putShort(idx)
+ lvTab putShort start
+ lvTab putShort end
+ lvTab putShort pool.addUtf8(name).toShort
+ lvTab putShort pool.addUtf8(signature).toShort
+ lvTab putShort idx
}
lvTab.putShort(entries.toShort)
@@ -1684,7 +1689,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
}
val attr =
fjbgContext.JOtherAttribute(jclass,
- jmethod,
+ jcode,
tpnme.LocalVariableTableATTR.toString,
lvTab.array())
jcode addAttribute attr
@@ -1704,7 +1709,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid {
}
def indexOf(m: IMethod, sym: Symbol): Int = {
- val Some(local) = m.lookupLocal(sym)
+ val Some(local) = m lookupLocal sym
indexOf(local)
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
index 13c802b2e4..5700236062 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVMUtil.scala
@@ -1,5 +1,5 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
* @author Iulian Dragos
*/
@@ -7,18 +7,9 @@
package scala.tools.nsc
package backend.jvm
-import java.nio.ByteBuffer
-
import scala.collection.{ mutable, immutable }
-import scala.tools.nsc.io.AbstractFile
-import scala.tools.nsc.symtab._
-import scala.tools.nsc.symtab.classfile.ClassfileConstants._
import ch.epfl.lamp.fjbg._
-import JAccessFlags._
-import JObjectType.{ JAVA_LANG_STRING, JAVA_LANG_OBJECT }
-import java.io.{ DataOutputStream }
-import reflect.generic.{ PickleFormat, PickleBuffer }
trait GenJVMUtil {
self: GenJVM =>
@@ -158,4 +149,4 @@ trait GenJVMUtil {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index d5bb6e0f88..cd38a2a4a7 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -1,15 +1,15 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
* @author Iulian Dragos
*/
package scala.tools.nsc
-package backend.opt;
+package backend.opt
-import scala.collection.mutable.{Map, HashMap};
-import scala.tools.nsc.backend.icode.analysis.LubException;
-import scala.tools.nsc.symtab._;
+import scala.collection.mutable.{Map, HashMap}
+import scala.tools.nsc.backend.icode.analysis.LubException
+import scala.tools.nsc.symtab._
/**
* @author Iulian Dragos
@@ -29,10 +29,7 @@ abstract class ClosureElimination extends SubComponent {
def peep(bb: BasicBlock, i1: Instruction, i2: Instruction) = (i1, i2) match {
case (CONSTANT(c), DROP(_)) =>
- if (c.tag == UnitTag)
- Some(List(i2))
- else
- Some(Nil);
+ if (c.tag == UnitTag) Some(List(i2)) else Some(Nil)
case (LOAD_LOCAL(x), STORE_LOCAL(y)) =>
if (x eq y) Some(Nil) else None
@@ -64,7 +61,7 @@ abstract class ClosureElimination extends SubComponent {
if (isStatic)
Some(Nil)
else
- Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil);
+ Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil)
case _ => None
}
@@ -78,7 +75,7 @@ abstract class ClosureElimination extends SubComponent {
val closser = new ClosureElim
override def apply(c: IClass): Unit =
- closser.analyzeClass(c)
+ closser analyzeClass c
}
/**
@@ -89,12 +86,11 @@ abstract class ClosureElimination extends SubComponent {
*/
class ClosureElim {
def analyzeClass(cls: IClass): Unit = if (settings.Xcloselim.value) {
- cls.methods.foreach { m =>
+ cls.methods foreach { m =>
analyzeMethod(m)
- peephole(m);
+ peephole(m)
}}
-
val cpp = new copyPropagation.CopyAnalysis
import copyPropagation._
@@ -111,7 +107,7 @@ abstract class ClosureElimination extends SubComponent {
for (i <- bb) {
i match {
- case LOAD_LOCAL(l) if (info.bindings.isDefinedAt(LocalVar(l))) =>
+ case LOAD_LOCAL(l) if info.bindings isDefinedAt LocalVar(l) =>
val t = info.getBinding(l)
t match {
case Deref(LocalVar(_)) | Deref(This) | Const(_) =>
@@ -119,7 +115,7 @@ abstract class ClosureElimination extends SubComponent {
log("replaced " + i + " with " + t)
case _ =>
- bb.replaceInstruction(i, LOAD_LOCAL(info.getAlias(l)));
+ bb.replaceInstruction(i, LOAD_LOCAL(info.getAlias(l)))
log("replaced " + i + " with " + info.getAlias(l))
}
@@ -132,23 +128,23 @@ abstract class ClosureElimination extends SubComponent {
bb.replaceInstruction(i,
DROP(REFERENCE(cls)) :: valueToInstruction(v) :: Nil);
log("Replaced " + i + " with " + info.getFieldNonRecordValue(r, f));
- case None => ();
+ case None =>
}
}
info.stack(0) match {
- case r @ Record(_, bindings) if bindings.isDefinedAt(f) =>
+ case r @ Record(_, bindings) if bindings isDefinedAt f =>
replaceFieldAccess(r)
case Deref(LocalVar(l)) =>
info.getBinding(l) match {
- case r @ Record(_, bindings) if bindings.isDefinedAt(f) =>
+ case r @ Record(_, bindings) if bindings isDefinedAt f =>
replaceFieldAccess(r)
case _ =>
}
case Deref(Field(r1, f1)) =>
info.getFieldValue(r1, f1) match {
- case Some(r @ Record(_, bindings)) if bindings.isDefinedAt(f) =>
+ case Some(r @ Record(_, bindings)) if bindings isDefinedAt f =>
replaceFieldAccess(r)
case _ =>
}
@@ -158,7 +154,7 @@ abstract class ClosureElimination extends SubComponent {
case UNBOX(_) =>
info.stack match {
- case Deref(LocalVar(loc1)) :: _ if (info.bindings.isDefinedAt(LocalVar(loc1))) =>
+ case Deref(LocalVar(loc1)) :: _ if info.bindings isDefinedAt LocalVar(loc1) =>
val value = info.getBinding(loc1)
value match {
case Boxed(LocalVar(loc2)) =>
@@ -172,10 +168,9 @@ abstract class ClosureElimination extends SubComponent {
bb.replaceInstruction(i, DROP(icodes.ObjectReference) :: valueToInstruction(Deref(LocalVar(loc2))) :: Nil)
log("replaced " + i + " with " + LocalVar(loc2))
case _ =>
- ()
}
- case _ => ();
+ case _ =>
}
info = cpp.interpret(info, i)
}
@@ -225,31 +220,31 @@ abstract class ClosureElimination extends SubComponent {
}
def transformBlock(b: BasicBlock): Unit = if (b.size >= 2) {
- var newInstructions: List[Instruction] = Nil;
+ var newInstructions: List[Instruction] = Nil
newInstructions = b.toList
var redo = false
do {
- var h = newInstructions.head;
- var t = newInstructions.tail;
- var seen: List[Instruction] = Nil;
- redo = false;
+ var h = newInstructions.head
+ var t = newInstructions.tail
+ var seen: List[Instruction] = Nil
+ redo = false
while (t != Nil) {
peep(b, h, t.head) match {
case Some(newInstrs) =>
newInstructions = seen.reverse ::: newInstrs ::: t.tail;
- redo = true;
+ redo = true
case None =>
()
}
- seen = h :: seen;
- h = t.head;
+ seen = h :: seen
+ h = t.head
t = t.tail
}
} while (redo);
- b.fromList(newInstructions)
+ b fromList newInstructions
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index 0db14d5e59..66dc3c78b2 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -1,5 +1,5 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
* @author Iulian Dragos
*/
@@ -113,7 +113,7 @@ abstract class Inliners extends SubComponent {
override def default(k: Symbol) = 0
}
- def analyzeMethod(m: IMethod): Unit = {
+ def analyzeMethod(m: IMethod) {
var sizeBeforeInlining = if (m.code ne null) m.code.blocks.length else 0
var instrBeforeInlining = if (m.code ne null) m.code.blocks.foldLeft(0)(_ + _.length) else 0
var retry = false
@@ -240,6 +240,7 @@ abstract class Inliners extends SubComponent {
case nme.foreach | nme.filter | nme.withFilter | nme.map | nme.flatMap => true
case _ => false
}
+
private def isHigherOrderMethod(sym: Symbol) =
sym.isMethod && atPhase(currentRun.erasurePhase.prev)(sym.info.paramTypes exists isFunctionType)
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index c170469016..934622bea0 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1,5 +1,5 @@
/* NSC -- new Scala compiler
- * Copyright 2005-2010 LAMP/EPFL
+ * Copyright 2005-2011 LAMP/EPFL
* @author Martin Odersky
*/
@@ -1196,13 +1196,17 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
else packSym
}
- /** Return the original enclosing method of this symbol. It
- * should return the same thing as enclMethod when called before
- * lambda lift, but it preserves the original nesting when called afterwards.
+ /** Return the original enclosing method of this symbol. It should return
+ * the same thing as enclMethod when called before lambda lift,
+ * but it preserves the original nesting when called afterwards.
*/
def originalEnclosingMethod: Symbol = {
if (isMethod) this
- else originalOwner.getOrElse(this, rawowner).originalEnclosingMethod
+ else {
+ val owner = originalOwner.getOrElse(this, rawowner)
+ if (isLocalDummy) owner.enclClass.primaryConstructor
+ else owner.originalEnclosingMethod
+ }
}
/** The top-level class containing this symbol */
@@ -1260,16 +1264,19 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
else NoSymbol
}
- /** A helper method that factors the common code used the discover a companion module of a class.
- * If a companion module exists, its symbol is returned, otherwise, `NoSymbol` is returned.
- * The method assumes that `this` symbol has already been checked to be a class (using `isClass`).
+ /** A helper method that factors the common code used the discover a
+ * companion module of a class. If a companion module exists, its symbol is
+ * returned, otherwise, `NoSymbol` is returned. The method assumes that
+ * `this` symbol has already been checked to be a class (using `isClass`).
*
- * After refchecks nested objects get transformed to lazy vals so we filter on LAZY flag as well.
- * @note The resident compiler may run many times over, and symbols may be reused. Therefore, a
- * module symbol that has been translated to a lazy val by refchecks is not guaranteed to
- * have MODULE set on the next run (even before refcheck). Flags are not part of symbol
- * history. Instead we rely on the fact that a synthetic lazy value must have been a
- * module.
+ * After refchecks nested objects get transformed to lazy vals so we
+ * filter on LAZY flag as well.
+ * @note The resident compiler may run many times over, and symbols may be
+ * reused. Therefore, a module symbol that has been translated to a
+ * lazy val by refchecks is not guaranteed to have MODULE set on the
+ * next run (even before refcheck). Flags are not part of symbol
+ * history. Instead we rely on the fact that a synthetic lazy value
+ * must have been a module.
*/
private final def companionModule0: Symbol = {
def isSyntheticLazy(sym: Symbol) =
@@ -1310,8 +1317,8 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
if (isModuleClass) companionClass else companionModule.moduleClass
/**
- * Returns the rawInfo of the owner. If the current phase has flat classes, it first
- * applies all pending type maps to this symbol.
+ * Returns the rawInfo of the owner. If the current phase has flat classes,
+ * it first applies all pending type maps to this symbol.
*
* assume this is the ModuleSymbol for B in the following definition:
* package p { class A { object B { val x = 1 } } }
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 9c6b4531d4..bc155d4e88 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -19,8 +19,8 @@ import annotation.unchecked.{ uncheckedVariance => uV }
* $traversableInfo
* @define mutability
* @define traversableInfo
- * This is a base trait of all kinds of $mutability Scala collections. It implements
- * the behavior common to all collections, in terms of a method
+ * This is a base trait of all kinds of $mutability Scala collections. It
+ * implements the behavior common to all collections, in terms of a method
* `foreach` with signature:
* {{{
* def foreach[U](f: Elem => U): Unit
@@ -69,8 +69,8 @@ import annotation.unchecked.{ uncheckedVariance => uV }
* depends on the element type `B` being admissible for that class,
* which means that an implicit instance of type `CanBuildFrom[Repr, B, That]`
* is found.
- * @define bfinfo an implicit value of class `CanBuildFrom` which determines the
- * result class `That` from the current representation type `Repr` and
+ * @define bfinfo an implicit value of class `CanBuildFrom` which determines
+ * the result class `That` from the current representation type `Repr` and
* and the new element type `B`.
* @define orderDependent
*
@@ -97,7 +97,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
protected type Self = Repr
/** The collection of type $coll underlying this `TraversableLike` object.
- * By default this is implemented as the `TraversableLike` object itself, but this can be overridden.
+ * By default this is implemented as the `TraversableLike` object itself,
+ * but this can be overridden.
*/
def repr: Repr = this.asInstanceOf[Repr]
@@ -170,10 +171,10 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
- * @return a new collection of type `That` which contains all elements of this $coll
- * followed by all elements of `that`.
+ * @return a new collection of type `That` which contains all elements
+ * of this $coll followed by all elements of `that`.
*
- * @usecase def ++(that: TraversableOnce[A]): $Coll[A]
+ * @usecase def ++[B](that: TraversableOnce[B]): $Coll[B]
*
* @return a new $coll which contains all elements of this $coll
* followed by all elements of `that`.
@@ -186,18 +187,18 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
b.result
}
- /** Concatenates this $coll with the elements of a traversable collection. It
- * differs from ++ in that the right operand determines the type of the resulting
- * collection rather than the left one.
+ /** Concatenates this $coll with the elements of a traversable collection.
+ * It differs from ++ in that the right operand determines the type of the
+ * resulting collection rather than the left one.
*
* @param that the traversable to append.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
- * @return a new collection of type `That` which contains all elements of this $coll
- * followed by all elements of `that`.
+ * @return a new collection of type `That` which contains all elements
+ * of this $coll followed by all elements of `that`.
*
- * @usecase def ++(that: TraversableOnce[A]): $Coll[A]
+ * @usecase def ++:[B](that: TraversableOnce[B]): $Coll[B]
*
* @return a new $coll which contains all elements of this $coll
* followed by all elements of `that`.
@@ -304,8 +305,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
b.result
}
- /** Builds a new collection by applying an option-valued function to all elements of this $coll
- * on which the function is defined.
+ /** Builds a new collection by applying an option-valued function to all
+ * elements of this $coll on which the function is defined.
*
* @param f the option-valued function which filters and maps the $coll.
* @tparam B the element type of the returned collection.
@@ -398,8 +399,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
* $mayNotTerminateInf
*
* @param p the predicate used to test elements.
- * @return `true` if the given predicate `p` holds for some of the elements
- * of this $coll, otherwise `false`.
+ * @return `true` if the given predicate `p` holds for some of the
+ * elements of this $coll, otherwise `false`.
*/
def exists(p: A => Boolean): Boolean = {
var result = false
@@ -429,7 +430,9 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
}
/**
- * Produces a collection containing cummulative results of applying the operator going left to right.
+ * Produces a collection containing cummulative results of applying the
+ * operator going left to right.
+ *
* $willNotTerminateInf
* $orderDependent
*
@@ -506,7 +509,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
/** Selects the last element.
* $orderDependent
* @return The last element of this $coll.
- * @throws NoSuchElementException If the $coll is empty. */
+ * @throws NoSuchElementException If the $coll is empty.
+ */
def last: A = {
var lst = head
for (x <- this)
@@ -543,8 +547,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
/** Selects first ''n'' elements.
* $orderDependent
* @param n Tt number of elements to take from this $coll.
- * @return a $coll consisting only of the first `n` elements of this $coll, or else the
- * whole $coll, if it has less than `n` elements.
+ * @return a $coll consisting only of the first `n` elements of this $coll,
+ * or else the whole $coll, if it has less than `n` elements.
*/
def take(n: Int): Repr = {
val b = newBuilder
@@ -638,8 +642,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
/** Splits this $coll into a prefix/suffix pair according to a predicate.
*
* Note: `c span p` is equivalent to (but possibly more efficient than)
- * `(c takeWhile p, c dropWhile p)`, provided the evaluation of the predicate `p`
- * does not cause any side-effects.
+ * `(c takeWhile p, c dropWhile p)`, provided the evaluation of the
+ * predicate `p` does not cause any side-effects.
* $orderDependent
*
* @param p the test predicate
@@ -728,6 +732,7 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
def toStream: Stream[A] = toBuffer.toStream
/** Converts this $coll to a string.
+ *
* @return a string representation of this collection. By default this
* string consists of the `stringPrefix` of this $coll,
* followed by all elements separated by commas and enclosed in parentheses.
@@ -735,8 +740,10 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
override def toString = mkString(stringPrefix + "(", ", ", ")")
/** Defines the prefix of this object's `toString` representation.
- * @return a string representation which starts the result of `toString` applied to this $coll.
- * By default the string prefix is the simple name of the collection class $coll.
+ *
+ * @return a string representation which starts the result of `toString`
+ * applied to this $coll. By default the string prefix is the
+ * simple name of the collection class $coll.
*/
def stringPrefix : String = {
var string = repr.asInstanceOf[AnyRef].getClass.getName
@@ -774,8 +781,9 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
/** Creates a non-strict filter of this $coll.
*
* Note: the difference between `c filter p` and `c withFilter p` is that
- * the former creates a new collection, whereas the latter only restricts
- * the domain of subsequent `map`, `flatMap`, `foreach`, and `withFilter` operations.
+ * the former creates a new collection, whereas the latter only
+ * restricts the domain of subsequent `map`, `flatMap`, `foreach`,
+ * and `withFilter` operations.
* $orderDependent
*
* @param p the predicate used to test elements.
@@ -786,8 +794,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
*/
def withFilter(p: A => Boolean): FilterMonadic[A, Repr] = new WithFilter(p)
- /** A class supporting filtered operations. Instances of this class are returned by
- * method `withFilter`.
+ /** A class supporting filtered operations. Instances of this class are
+ * returned by method `withFilter`.
*/
class WithFilter(p: A => Boolean) extends FilterMonadic[A, Repr] {
@@ -798,15 +806,15 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
- * @return a new collection of type `That` resulting from applying the given function
- * `f` to each element of the outer $coll that satisfies predicate `p`
- * and collecting the results.
+ * @return a new collection of type `That` resulting from applying
+ * the given function `f` to each element of the outer $coll
+ * that satisfies predicate `p` and collecting the results.
*
* @usecase def map[B](f: A => B): $Coll[B]
*
* @return a new $coll resulting from applying the given function
- * `f` to each element of the outer $coll that satisfies predicate `p`
- * and collecting the results.
+ * `f` to each element of the outer $coll that satisfies
+ * predicate `p` and collecting the results.
*/
def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
@@ -816,14 +824,17 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
}
/** Builds a new collection by applying a function to all elements of the
- * outer $coll containing this `WithFilter` instance that satisfy predicate `p` and concatenating the results.
+ * outer $coll containing this `WithFilter` instance that satisfy
+ * predicate `p` and concatenating the results.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
* @tparam That $thatinfo
* @param bf $bfinfo
- * @return a new collection of type `That` resulting from applying the given collection-valued function
- * `f` to each element of the outer $coll that satisfies predicate `p` and concatenating the results.
+ * @return a new collection of type `That` resulting from applying
+ * the given collection-valued function `f` to each element
+ * of the outer $coll that satisfies predicate `p` and
+ * concatenating the results.
*
* @usecase def flatMap[B](f: A => TraversableOnce[B]): $Coll[B]
*
@@ -837,8 +848,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
b.result
}
- /** Applies a function `f` to all elements of the outer $coll containing this `WithFilter` instance
- * that satisfy predicate `p`.
+ /** Applies a function `f` to all elements of the outer $coll containing
+ * this `WithFilter` instance that satisfy predicate `p`.
*
* @param f the function that is applied for its side-effect to every element.
* The result of function `f` is discarded.