diff options
author | Paul Phillips <paulp@improving.org> | 2011-07-23 20:50:24 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-07-23 20:50:24 +0000 |
commit | 5c61410fe5b8fd636bde6484f04a2d1160ed7eb4 (patch) | |
tree | 7d6d8068b148e0282bc5156d3e8fde1f9ac4fb7f /src/compiler/scala/tools/nsc/transform/Flatten.scala | |
parent | f9f164d3c71aee897e7885e4c991866bd1c0c339 (diff) | |
download | scala-5c61410fe5b8fd636bde6484f04a2d1160ed7eb4.tar.gz scala-5c61410fe5b8fd636bde6484f04a2d1160ed7eb4.tar.bz2 scala-5c61410fe5b8fd636bde6484f04a2d1160ed7eb4.zip |
Start of an attempt to abstract above some hard...
Start of an attempt to abstract above some hardcoded name mangling
decisions so they can be modified, something we need to do to fix
long-standing problems with inner classes. It's not easy. This commit
doesn't actually change much, it's primarily setup. No review.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/Flatten.scala')
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/Flatten.scala | 63 |
1 files changed, 44 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Flatten.scala b/src/compiler/scala/tools/nsc/transform/Flatten.scala index 28dfabb035..53016dd748 100644 --- a/src/compiler/scala/tools/nsc/transform/Flatten.scala +++ b/src/compiler/scala/tools/nsc/transform/Flatten.scala @@ -18,43 +18,69 @@ abstract class Flatten extends InfoTransform { /** the following two members override abstract members in Transform */ val phaseName: String = "flatten" + /** Updates the owning scope with the given symbol; returns the old symbol. + */ + private def replaceSymbolInCurrentScope(sym: Symbol): Symbol = { + atPhase(phase.next) { + val scope = sym.owner.info.decls + val old = scope lookup sym.name + if (old ne NoSymbol) + scope unlink old + + scope enter sym + old + } + } + private def liftClass(sym: Symbol) { - if (!(sym hasFlag LIFTED)) { + if (!sym.isLifted) { sym setFlag LIFTED - atPhase(phase.next) { - if (settings.debug.value) log("re-enter " + sym + " in " + sym.owner) - assert(sym.owner.isPackageClass, sym) //debug - val scope = sym.owner.info.decls - val old = scope lookup sym.name - if (old != NoSymbol) scope unlink old - scope enter sym - } + debuglog("re-enter " + sym.fullLocationString) + val old = replaceSymbolInCurrentScope(sym) + if (old ne NoSymbol) + debuglog("lifted " + sym.fullLocationString + ", unlinked " + old) + } + } + private def liftSymbol(sym: Symbol) { + liftClass(sym) + if (sym.needsImplClass) + liftClass(erasure implClass sym) + } + // This is a short-term measure partially working around objects being + // lifted out of parameterized classes, leaving them referencing + // invisible type parameters. + private def isFlattenablePrefix(pre: Type) = { + val clazz = pre.typeSymbol + clazz.isClass && !clazz.isPackageClass && { + // Cannot flatten here: class A[T] { object B } + atPhase(currentRun.erasurePhase.prev)(clazz.typeParams.isEmpty) } } private val flattened = new TypeMap { def apply(tp: Type): Type = tp match { - case TypeRef(pre, sym, args) if (pre.typeSymbol.isClass && !pre.typeSymbol.isPackageClass) => - assert(args.isEmpty) - assert(sym.toplevelClass != NoSymbol, sym.ownerChain) - typeRef(sym.toplevelClass.owner.thisType, sym, args) + case TypeRef(pre, sym, args) if isFlattenablePrefix(pre) => + assert(args.isEmpty && sym.toplevelClass != NoSymbol, sym.ownerChain) + typeRef(sym.toplevelClass.owner.thisType, sym, Nil) case ClassInfoType(parents, decls, clazz) => var parents1 = parents val decls1 = new Scope if (clazz.isPackageClass) { atPhase(phase.next)(decls foreach (decls1 enter _)) - } else { + } + else { val oldowner = clazz.owner atPhase(phase.next)(oldowner.info) parents1 = parents mapConserve (this) + for (sym <- decls) { if (sym.isTerm && !sym.isStaticModule) { decls1 enter sym - if (sym.isModule) sym.moduleClass setFlag LIFTED - } else if (sym.isClass) { - liftClass(sym) - if (sym.needsImplClass) liftClass(erasure.implClass(sym)) + if (sym.isModule) + sym.moduleClass setFlag LIFTED } + else if (sym.isClass) + liftSymbol(sym) } } ClassInfoType(parents1, decls1, clazz) @@ -74,7 +100,6 @@ abstract class Flatten extends InfoTransform { protected def newTransformer(unit: CompilationUnit): Transformer = new Flattener class Flattener extends Transformer { - /** Buffers for lifted out classes */ private val liftedDefs = new mutable.HashMap[Symbol, ListBuffer[Tree]] |