diff options
author | Felix Mulder <felix.mulder@gmail.com> | 2016-11-02 11:08:28 +0100 |
---|---|---|
committer | Guillaume Martres <smarter@ubuntu.com> | 2016-11-22 01:35:07 +0100 |
commit | 8a61ff432543a29234193cd1f7c14abd3f3d31a0 (patch) | |
tree | a8147561d307af862c295cfc8100d271063bb0dd /compiler/src/dotty/tools/dotc/transform/Pickler.scala | |
parent | 6a455fe6da5ff9c741d91279a2dc6fe2fb1b472f (diff) | |
download | dotty-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.scala | 108 |
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""") + } +} |