summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-09-16 15:32:34 +1000
committerJason Zaugg <jzaugg@gmail.com>2014-09-16 15:32:34 +1000
commit3307e44a9d980eef5a442a688ef22765556f609f (patch)
tree4ed3921c46e13138a0e16735461128ebbe479ce4 /src/compiler
parent0e2be38f05a6d3fadd0a6c800604503c72401117 (diff)
parent63207e115a46634d47446a87a7f4bc3c2651b0e7 (diff)
downloadscala-3307e44a9d980eef5a442a688ef22765556f609f.tar.gz
scala-3307e44a9d980eef5a442a688ef22765556f609f.tar.bz2
scala-3307e44a9d980eef5a442a688ef22765556f609f.zip
Merge pull request #3972 from lrytz/BCodeDelambdafyFix
isAnonymousClass/Function for delambdafy classes is not true
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala28
2 files changed, 21 insertions, 20 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
index e5b4c4a6c2..0c0d726630 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeAsmCommon.scala
@@ -22,14 +22,11 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
* null.
*/
def isAnonymousOrLocalClass(classSym: Symbol): Boolean = {
- def isDelambdafyLambdaClass(classSym: Symbol): Boolean = {
- classSym.isAnonymousFunction && (settings.Ydelambdafy.value == "method")
- }
-
assert(classSym.isClass, s"not a class: $classSym")
-
- !isDelambdafyLambdaClass(classSym) &&
- (classSym.isAnonymousClass || !classSym.originalOwner.isClass)
+ val res = (classSym.isAnonymousClass || !classSym.originalOwner.isClass)
+ // lambda classes are always top-level classes.
+ if (res) assert(!classSym.isDelambdafyFunction)
+ res
}
/**
@@ -81,7 +78,7 @@ final class BCodeAsmCommon[G <: Global](val global: G) {
final case class EnclosingMethodEntry(owner: String, name: String, methodDescriptor: String)
/**
- * If data for emitting an EnclosingMethod attribute. None if `classSym` is a member class (not
+ * Data for emitting an EnclosingMethod attribute. None if `classSym` is a member class (not
* an anonymous or local class). See doc in BTypes.
*
* The class is parametrized by two functions to obtain a bytecode class descriptor for a class
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 9cc8d779a0..12e7b23f48 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -245,18 +245,22 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// - make `anonClass.isAnonymousClass` true.
// - use `newAnonymousClassSymbol` or push the required variations into a similar factory method
// - reinstate the assertion in `Erasure.resolveAnonymousBridgeClash`
- val suffix = "$lambda$" + (
+ val suffix = nme.DELAMBDAFY_LAMBDA_CLASS_NAME + "$" + (
if (funOwner.isPrimaryConstructor) ""
else "$" + funOwner.name + "$"
)
- val name = unit.freshTypeName(s"${oldClass.name.decode}$suffix")
+ val oldClassPart = oldClass.name.decode
+ // make sure the class name doesn't contain $anon, otherwsie isAnonymousClass/Function may be true
+ val name = unit.freshTypeName(s"$oldClassPart$suffix".replace("$anon", "$nestedInAnon"))
- val anonClass = pkg newClassSymbol(name, originalFunction.pos, FINAL | SYNTHETIC) addAnnotation SerialVersionUIDAnnotation
- anonClass setInfo ClassInfoType(parents, newScope, anonClass)
+ val lambdaClass = pkg newClassSymbol(name, originalFunction.pos, FINAL | SYNTHETIC) addAnnotation SerialVersionUIDAnnotation
+ lambdaClass setInfo ClassInfoType(parents, newScope, lambdaClass)
+ assert(!lambdaClass.isAnonymousClass && !lambdaClass.isAnonymousFunction, "anonymous class name: "+ lambdaClass.name)
+ assert(lambdaClass.isDelambdafyFunction, "not lambda class name: " + lambdaClass.name)
val captureProxies2 = new LinkedHashMap[Symbol, TermSymbol]
captures foreach {capture =>
- val sym = anonClass.newVariable(capture.name.toTermName, capture.pos, SYNTHETIC)
+ val sym = lambdaClass.newVariable(capture.name.toTermName, capture.pos, SYNTHETIC)
sym setInfo capture.info
captureProxies2 += ((capture, sym))
}
@@ -266,30 +270,30 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val thisProxy = {
val target = targetMethod(originalFunction)
if (thisReferringMethods contains target) {
- val sym = anonClass.newVariable(nme.FAKE_LOCAL_THIS, originalFunction.pos, SYNTHETIC)
+ val sym = lambdaClass.newVariable(nme.FAKE_LOCAL_THIS, originalFunction.pos, SYNTHETIC)
sym.info = oldClass.tpe
sym
} else NoSymbol
}
- val decapturify = new DeCapturifyTransformer(captureProxies2, unit, oldClass, anonClass, originalFunction.symbol.pos, thisProxy)
+ val decapturify = new DeCapturifyTransformer(captureProxies2, unit, oldClass, lambdaClass, originalFunction.symbol.pos, thisProxy)
val accessorMethod = createAccessorMethod(thisProxy, originalFunction)
val decapturedFunction = decapturify.transform(originalFunction).asInstanceOf[Function]
val members = (optionSymbol(thisProxy).toList ++ (captureProxies2 map (_._2))) map {member =>
- anonClass.info.decls enter member
+ lambdaClass.info.decls enter member
ValDef(member, gen.mkZero(member.tpe)) setPos decapturedFunction.pos
}
// constructor
- val constr = createConstructor(anonClass, members)
+ val constr = createConstructor(lambdaClass, members)
// apply method with same arguments and return type as original lambda.
- val applyMethodDef = createApplyMethod(anonClass, decapturedFunction, accessorMethod, thisProxy)
+ val applyMethodDef = createApplyMethod(lambdaClass, decapturedFunction, accessorMethod, thisProxy)
- val bridgeMethod = createBridgeMethod(anonClass, originalFunction, applyMethodDef)
+ val bridgeMethod = createBridgeMethod(lambdaClass, originalFunction, applyMethodDef)
def fulldef(sym: Symbol) =
if (sym == NoSymbol) sym.toString
@@ -305,7 +309,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val body = members ++ List(constr, applyMethodDef) ++ bridgeMethod
// TODO if member fields are private this complains that they're not accessible
- (localTyper.typedPos(decapturedFunction.pos)(ClassDef(anonClass, body)).asInstanceOf[ClassDef], thisProxy, accessorMethod)
+ (localTyper.typedPos(decapturedFunction.pos)(ClassDef(lambdaClass, body)).asInstanceOf[ClassDef], thisProxy, accessorMethod)
}
val (anonymousClassDef, thisProxy, accessorMethod) = makeAnonymousClass