summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/fjbg.jar.desired.sha12
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala11
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java8
-rw-r--r--src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java39
7 files changed, 64 insertions, 5 deletions
diff --git a/lib/fjbg.jar.desired.sha1 b/lib/fjbg.jar.desired.sha1
index 862868d030..6d794d19d7 100644
--- a/lib/fjbg.jar.desired.sha1
+++ b/lib/fjbg.jar.desired.sha1
@@ -1 +1 @@
-3997a32211461f0f7de1e4eb37e964cd134ea003 ?fjbg.jar
+d91d1cbb43b02243dcef2bbedf4d0a372879e972 ?fjbg.jar
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 45d1916ca9..c7cdad7c20 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -331,7 +331,6 @@ trait BasicBlocks {
* and RETURNs easier.
*/
def enterIgnoreMode = {
- log("Entering ignore mode in " + fullString)
ignore = true
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
index 7d216dc3aa..0c7455c6c8 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -199,6 +199,9 @@ abstract class GenJVM extends SubComponent {
var isParcelableClass = false
def genClass(c: IClass) {
+ val needsEnclosingMethod: Boolean =
+ c.symbol.isClass && c.symbol.asInstanceOf[ClassSymbol].originalOwner.isMethod
+
clasz = c
innerClasses = immutable.ListSet.empty
@@ -282,12 +285,20 @@ abstract class GenJVM extends SubComponent {
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)
emitClass(jclass, c.symbol)
if (c.symbol hasAnnotation BeanInfoAttr)
genBeanInfoClass(c)
}
+ def addEnclosingMethodAttribute(jclass: JClass, clazz: Symbol) {
+ val sym = clazz.asInstanceOf[ClassSymbol].originalOwner
+ if (sym.isMethod) {
+ jclass.addAttribute(fjbgContext.JEnclosingMethodAttribute(jclass, javaName(sym.enclClass), javaName(sym), javaType(sym)))
+ } else
+ log("Local class %s has non-method owner: %s".format(clazz, sym))
+ }
/**
* Generate a bean info class that describes the given class.
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index f8320595e9..d94b617904 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -1897,6 +1897,10 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable =>
/** The classfile from which this class was loaded. Maybe null. */
var classFile: AbstractFile = null;
+ /** The original owner of this class. Used by the backend to generate
+ * EnclosingMethod attributes. */
+ var originalOwner: Symbol = initOwner
+
private var source: AbstractFile = null
override def sourceFile =
if (owner.isPackageClass) source else super.sourceFile
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 906297a4b8..b9d195a01e 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -249,9 +249,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast.
else ARRAY_TAG.toString+(args map jsig).mkString
else if (sym.isTypeParameterOrSkolem &&
// only refer to type params that will actually make it into the sig, this excludes:
- !sym.owner.isTypeParameterOrSkolem && // higher-order type parameters (!sym.owner.isTypeParameterOrSkolem), and parameters of methods
- (!sym0.isClass || sym.owner.isClass) // if we're generating the sig for a class, type params must be owned by a class (not a method -- #3249)
- )
+ !sym.owner.isTypeParameterOrSkolem) // higher-order type parameters (!sym.owner.isTypeParameterOrSkolem), and parameters of methods
TVAR_TAG.toString+sym.name+";"
else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass)
jsig(ObjectClass.tpe)
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java b/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java
index 569a9ac272..07030fbb9c 100644
--- a/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java
+++ b/src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java
@@ -145,6 +145,14 @@ public class FJBGContext {
return new JOtherAttribute(this, clazz, owner, name, contents, length);
}
+ public JEnclosingMethodAttribute JEnclosingMethodAttribute(JClass clazz,
+ String className,
+ String methodName,
+ JType methodType) {
+ return new JEnclosingMethodAttribute(this, clazz, className, methodName, methodType);
+ }
+
+
public JOtherAttribute JOtherAttribute(JClass clazz,
Object owner,
String name,
diff --git a/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java b/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java
new file mode 100644
index 0000000000..4351e2fc7b
--- /dev/null
+++ b/src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java
@@ -0,0 +1,39 @@
+
+package ch.epfl.lamp.fjbg;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+/**
+ * Sourcefile attribute, which can be attached to class files to
+ * associate them with their enclosing method. A class may have
+ * at most one EclosingMethod attribute.
+ *
+ * @version 1.0
+ * @author Michel Schinz
+ */
+
+public class JEnclosingMethodAttribute extends JAttribute {
+ protected final int classIdx;
+ protected final int nameAndTypeIdx;
+
+ public JEnclosingMethodAttribute(FJBGContext context,
+ JClass clazz,
+ String className, String methodName, JType methodType) {
+ super(context, clazz);
+ this.classIdx = clazz.getConstantPool().addClass(className);
+ this.nameAndTypeIdx = clazz.getConstantPool().addNameAndType(methodName, methodType.getSignature());
+ }
+
+ public String getName() { return "EnclosingMethod"; }
+
+ protected int getSize() {
+ return 4;
+ }
+
+ protected void writeContentsTo(DataOutputStream stream) throws IOException {
+ stream.writeShort(classIdx);
+ stream.writeShort(nameAndTypeIdx);
+ }
+}