diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-06-08 09:01:57 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-06-08 09:01:57 -0700 |
commit | 59f0214e5d8603572f50514666ec24e274747369 (patch) | |
tree | d6af74733fea5fbe79182f0e534cda2fe6a3bcd9 /src | |
parent | 8d0ba32a3fe2a7331e692868b469b95292b4eabc (diff) | |
parent | 4794374af4d7c84ed6e06ac9c4e4f9f9d09cb102 (diff) | |
download | scala-59f0214e5d8603572f50514666ec24e274747369.tar.gz scala-59f0214e5d8603572f50514666ec24e274747369.tar.bz2 scala-59f0214e5d8603572f50514666ec24e274747369.zip |
Merge pull request #631 from retronym/ticket/5652-3
SI-5652 Mangle names of potentially public lambda lifted methods.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/LambdaLift.scala | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala index 718e58b855..fad41ae98d 100644 --- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala +++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala @@ -10,7 +10,7 @@ import symtab._ import Flags._ import util.TreeSet import scala.collection.{ mutable, immutable } -import scala.collection.mutable.LinkedHashMap +import scala.collection.mutable.{ LinkedHashMap, LinkedHashSet } abstract class LambdaLift extends InfoTransform { import global._ @@ -50,6 +50,9 @@ abstract class LambdaLift extends InfoTransform { /** A hashtable storing calls between functions */ private val called = new LinkedHashMap[Symbol, SymSet] + /** Symbols that are called from an inner class. */ + private val calledFromInner = new LinkedHashSet[Symbol] + /** The set of symbols that need to be renamed. */ private val renamable = newSymSet @@ -64,9 +67,6 @@ abstract class LambdaLift extends InfoTransform { /** Buffers for lifted out classes and methods */ private val liftedDefs = new LinkedHashMap[Symbol, List[Tree]] - /** True if we are transforming under a ReferenceToBoxed node */ - private var isBoxedRef = false - private type SymSet = TreeSet[Symbol] private def newSymSet = new TreeSet[Symbol](_ isLess _) @@ -138,6 +138,7 @@ abstract class LambdaLift extends InfoTransform { private def markCalled(sym: Symbol, owner: Symbol) { debuglog("mark called: " + sym + " of " + sym.owner + " is called by " + owner) symSet(called, owner) addEntry sym + if (sym.enclClass != owner.enclClass) calledFromInner addEntry sym } /** The traverse function */ @@ -214,15 +215,23 @@ abstract class LambdaLift extends InfoTransform { def renameSym(sym: Symbol) { val originalName = sym.name - val base = sym.name + nme.NAME_JOIN_STRING + ( - if (sym.isAnonymousFunction && sym.owner.isMethod) - sym.owner.name + nme.NAME_JOIN_STRING - else "" - ) - sym setName ( - if (sym.name.isTypeName) unit.freshTypeName(base) - else unit.freshTermName(base) + def freshen(prefix: String): Name = + if (originalName.isTypeName) unit.freshTypeName(prefix) + else unit.freshTermName(prefix) + + val newName: Name = ( + if (sym.isAnonymousFunction && sym.owner.isMethod) { + freshen(sym.name + nme.NAME_JOIN_STRING + sym.owner.name + nme.NAME_JOIN_STRING) + } else { + // SI-5652 If the lifted symbol is accessed from an inner class, it will be made public. (where?) + // Generating a a unique name, mangled with the enclosing class name, avoids a VerifyError + // in the case that a sub-class happens to lifts out a method with the *same* name. + val name = freshen(sym.name + nme.NAME_JOIN_STRING) + if (originalName.isTermName && !sym.enclClass.isImplClass && calledFromInner(sym)) nme.expandedName(name, sym.enclClass) + else name + } ) + sym setName newName debuglog("renaming in %s: %s => %s".format(sym.owner.fullLocationString, originalName, sym.name)) } |