summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-11-12 16:26:17 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-11-12 16:26:17 +0000
commita061def4dd3d16b226f17a5246470255623177c2 (patch)
tree2e69c017110eb3a196af9b2c9b865f08f72743f6 /src/compiler
parent505a858ea1328227f18d116926a57296fd63dddd (diff)
downloadscala-a061def4dd3d16b226f17a5246470255623177c2.tar.gz
scala-a061def4dd3d16b226f17a5246470255623177c2.tar.bz2
scala-a061def4dd3d16b226f17a5246470255623177c2.zip
Generate EnclosingMethod classfile attributes.
This should fix java signatures when they refer to method type parameters. I unrolled Adriaans previous fix for #3249, as this one is more general. Closes #3249, review by moors.
Diffstat (limited to 'src/compiler')
-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
4 files changed, 16 insertions, 4 deletions
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)