blob: 8b9d2be0d02121cf3dbc25913d62471cd67c4a6a (
plain) (
tree)
|
|
package dotty.tools.dotc
package transform
import core._
import DenotTransformers.IdentityDenotTransformer
import Contexts.Context
import Symbols._
import Scopes._
import collection.mutable
import TreeTransforms.MiniPhaseTransform
import SymDenotations._
import ast.Trees._
import NameOps._
import TreeTransforms.TransformerInfo
import StdNames._
/** The preceding lambda lift and flatten phases move symbols to different scopes
* and rename them. This miniphase cleans up afterwards and makes sure that all
* class scopes contain the symbols defined in them.
*/
class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
import ast.tpd._
override def phaseName = "restoreScopes"
/* Note: We need to wait until we see a package definition because
* DropEmptyConstructors changes template members when analyzing the
* enclosing package definitions. So by the time RestoreScopes gets to
* see a typedef or template, it still might be changed by DropEmptyConstructors.
*/
override def transformPackageDef(pdef: PackageDef)(implicit ctx: Context, info: TransformerInfo) = {
pdef.stats.foreach(restoreScope)
pdef
}
private def restoreScope(tree: Tree)(implicit ctx: Context, info: TransformerInfo) = tree match {
case TypeDef(_, impl: Template) =>
val restoredDecls = newScope
for (stat <- impl.constr :: impl.body)
if (stat.isInstanceOf[MemberDef] && stat.symbol.exists)
restoredDecls.enter(stat.symbol)
// Enter class in enclosing package scope, in case it was an inner class before flatten.
// For top-level classes this does nothing.
val cls = tree.symbol.asClass
val pkg = cls.owner.asClass
// Bring back companion links
val companionClass = cls.info.decls.lookup(nme.COMPANION_CLASS_METHOD)
val companionModule = cls.info.decls.lookup(nme.COMPANION_MODULE_METHOD)
if (companionClass.exists) {
restoredDecls.enter(companionClass)
}
if (companionModule.exists) {
restoredDecls.enter(companionModule)
}
pkg.enter(cls)
val cinfo = cls.classInfo
tree.symbol.copySymDenotation(
info = cinfo.derivedClassInfo( // Dotty deviation: Cannot expand cinfo inline without a type error
decls = restoredDecls: Scope)).installAfter(thisTransform)
tree
case tree => tree
}
}
|