aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/Pickler.scala
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-11-02 11:08:28 +0100
committerGuillaume Martres <smarter@ubuntu.com>2016-11-22 01:35:07 +0100
commit8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch)
treea8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/transform/Pickler.scala
parent6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff)
downloaddotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.gz
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.tar.bz2
dotty-8a61ff432543a29234193cd1f7c14abd3f3d31a0.zip
Move compiler and compiler tests to compiler dir
Diffstat (limited to 'compiler/src/dotty/tools/dotc/transform/Pickler.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Pickler.scala108
1 files changed, 108 insertions, 0 deletions
diff --git a/compiler/src/dotty/tools/dotc/transform/Pickler.scala b/compiler/src/dotty/tools/dotc/transform/Pickler.scala
new file mode 100644
index 000000000..61c3ca5de
--- /dev/null
+++ b/compiler/src/dotty/tools/dotc/transform/Pickler.scala
@@ -0,0 +1,108 @@
+package dotty.tools.dotc
+package transform
+
+import core._
+import Contexts.Context
+import Decorators._
+import tasty._
+import config.Printers.{noPrinter, pickling}
+import java.io.PrintStream
+import Periods._
+import Phases._
+import Symbols._
+import Flags.Module
+import collection.mutable
+
+/** This phase pickles trees */
+class Pickler extends Phase {
+ import ast.tpd._
+
+ override def phaseName: String = "pickler"
+
+ private def output(name: String, msg: String) = {
+ val s = new PrintStream(name)
+ s.print(msg)
+ s.close
+ }
+
+ // Maps that keep a record if -Ytest-pickler is set.
+ private val beforePickling = new mutable.HashMap[ClassSymbol, String]
+ private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler]
+
+ /** Drop any elements of this list that are linked module classes of other elements in the list */
+ private def dropCompanionModuleClasses(clss: List[ClassSymbol])(implicit ctx: Context): List[ClassSymbol] = {
+ val companionModuleClasses =
+ clss.filterNot(_ is Module).map(_.linkedClass).filterNot(_.isAbsent)
+ clss.filterNot(companionModuleClasses.contains)
+ }
+
+ override def run(implicit ctx: Context): Unit = {
+ val unit = ctx.compilationUnit
+ pickling.println(i"unpickling in run ${ctx.runId}")
+
+ for { cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree))
+ tree <- sliceTopLevel(unit.tpdTree, cls) } {
+ val pickler = new TastyPickler()
+ if (ctx.settings.YtestPickler.value) {
+ beforePickling(cls) = tree.show
+ picklers(cls) = pickler
+ }
+ val treePkl = pickler.treePkl
+ treePkl.pickle(tree :: Nil)
+ treePkl.compactify()
+ pickler.addrOfTree = treePkl.buf.addrOfTree
+ pickler.addrOfSym = treePkl.addrOfSym
+ if (tree.pos.exists)
+ new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil)
+
+ // other pickle sections go here.
+ val pickled = pickler.assembleParts()
+ unit.pickled += (cls -> pickled)
+
+ def rawBytes = // not needed right now, but useful to print raw format.
+ pickled.iterator.grouped(10).toList.zipWithIndex.map {
+ case (row, i) => s"${i}0: ${row.mkString(" ")}"
+ }
+ // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
+ if (pickling ne noPrinter) {
+ println(i"**** pickled info of $cls")
+ new TastyPrinter(pickler.assembleParts()).printContents()
+ }
+ }
+ }
+
+ override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
+ val result = super.runOn(units)
+ if (ctx.settings.YtestPickler.value)
+ testUnpickler(
+ ctx.fresh
+ .setPeriod(Period(ctx.runId + 1, FirstPhaseId))
+ .addMode(Mode.ReadPositions))
+ result
+ }
+
+ private def testUnpickler(implicit ctx: Context): Unit = {
+ pickling.println(i"testing unpickler at run ${ctx.runId}")
+ ctx.initialize()
+ val unpicklers =
+ for ((cls, pickler) <- picklers) yield {
+ val unpickler = new DottyUnpickler(pickler.assembleParts())
+ unpickler.enter(roots = Set())
+ cls -> unpickler
+ }
+ pickling.println("************* entered toplevel ***********")
+ for ((cls, unpickler) <- unpicklers) {
+ val unpickled = unpickler.body
+ testSame(i"$unpickled%\n%", beforePickling(cls), cls)
+ }
+ }
+
+ private def testSame(unpickled: String, previous: String, cls: ClassSymbol)(implicit ctx: Context) =
+ if (previous != unpickled) {
+ output("before-pickling.txt", previous)
+ output("after-pickling.txt", unpickled)
+ ctx.error(i"""pickling difference for ${cls.fullName} in ${cls.sourceFile}, for details:
+ |
+ | diff before-pickling.txt after-pickling.txt""")
+ }
+}