diff options
-rw-r--r-- | lib/fjbg.jar.desired.sha1 | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Erasure.scala | 4 | ||||
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/FJBGContext.java | 8 | ||||
-rw-r--r-- | src/fjbg/ch/epfl/lamp/fjbg/JEnclosingMethodAttribute.java | 39 |
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); + } +} |