aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/Companions.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-07-03 18:57:22 +0200
committerMartin Odersky <odersky@gmail.com>2014-07-17 11:01:59 +0200
commitefe4f7e43652a303d16a5253f84316e547f45cca (patch)
tree1ea59d27843909b7633e0851e6c8b2cdd32e38c6 /src/dotty/tools/dotc/transform/Companions.scala
parenta47b8b4d3c22133e8cde0053701057e56cc71acb (diff)
downloaddotty-efe4f7e43652a303d16a5253f84316e547f45cca.tar.gz
dotty-efe4f7e43652a303d16a5253f84316e547f45cca.tar.bz2
dotty-efe4f7e43652a303d16a5253f84316e547f45cca.zip
Changed PostTyperTransformer scheme
1) We now always generate companion objects for classes. This is done in mini-phase "companions", which also assures that companion-modules appear after companion-classes. 2) PostTyperTransformers is gone; the part which normalizes trees has been rolled into TreeTransform and the part which reordered companion classes and modules is now in Companions. Note: Some tests were deisabled; should be re-enabled by Dmitry where needed.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Companions.scala')
-rw-r--r--src/dotty/tools/dotc/transform/Companions.scala67
1 files changed, 67 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/transform/Companions.scala b/src/dotty/tools/dotc/transform/Companions.scala
new file mode 100644
index 000000000..0e31b511d
--- /dev/null
+++ b/src/dotty/tools/dotc/transform/Companions.scala
@@ -0,0 +1,67 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import Names._
+import TreeTransforms.{TransformerInfo, TreeTransform, TreeTransformer}
+import ast.Trees.flatten
+import Flags._
+import Contexts.Context
+import Symbols._
+import scala.collection.mutable
+import DenotTransformers._
+import Names.Name
+import NameOps._
+
+
+/** A transformer that provides a convenient way to create companion objects
+ */
+class Companions extends TreeTransform with IdentityDenotTransformer { thisTransformer =>
+ import ast.tpd._
+
+ override def name = "companions"
+
+ /** Reorder statements so that module classes always come after their companion classes, add missing companion classes */
+ private def reorderAndComplete(stats: List[Tree])(implicit ctx: Context): List[Tree] = {
+ val moduleClassDefs, singleClassDefs = mutable.Map[Name, Tree]()
+
+ def reorder(stats: List[Tree]): List[Tree] = stats match {
+ case (stat: TypeDef) :: stats1 if stat.symbol.isClass =>
+ if (stat.symbol is Flags.Module) {
+ moduleClassDefs += (stat.name -> stat)
+ singleClassDefs -= stat.name.stripModuleClassSuffix
+ val stats1r = reorder(stats1)
+ if (moduleClassDefs contains stat.name) stat :: stats1r else stats1r
+ } else {
+ def stats1r = reorder(stats1)
+ val normalized = moduleClassDefs remove stat.name.moduleClassName match {
+ case Some(mcdef) =>
+ mcdef :: stats1r
+ case None =>
+ singleClassDefs += (stat.name -> stat)
+ stats1r
+ }
+ stat :: normalized
+ }
+ case stat :: stats1 => stat :: reorder(stats1)
+ case Nil => Nil
+ }
+
+ def newCompanion(name: TermName): Thicket = {
+ val modul = ctx.newCompleteModuleSymbol(ctx.owner, name, Synthetic, Synthetic,
+ defn.ObjectClass.typeRef :: Nil, Scopes.newScope)
+ if (ctx.owner.isClass) modul.enteredAfter(thisTransformer)
+ ModuleDef(modul, Nil)
+ }
+
+ def addMissingCompanions(stats: List[Tree]): List[Tree] = stats map {
+ case stat: TypeDef if singleClassDefs contains stat.name =>
+ Thicket(stat :: newCompanion(stat.name.toTermName).trees)
+ case stat => stat
+ }
+ addMissingCompanions(reorder(stats))
+ }
+
+ override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] =
+ ast.Trees.flatten(reorderAndComplete(trees)(ctx.withPhase(thisTransformer.next)))
+}