aboutsummaryrefslogblamecommitdiff
path: root/src/dotty/tools/dotc/transform/Pickler.scala
blob: fd50df6ba88938e8617afd7778c7b27f4e23afd5 (plain) (tree)
1
2
3
4
5
6
7
8
9







                        
                      
                          
                






                                                           





                                                   
                                                                                                

                                      
                                                

                                                                           
                                            
                                 

                                                                                                   
 
                                         
                                         
                                                                             


                                                            
                                                        
                                                                                          
      

















                                                                                           
     

   
package dotty.tools.dotc
package transform

import core._
import TreeTransforms._
import Contexts.Context
import Decorators._
import pickling._
import config.Printers
import java.io.PrintStream
import Periods._

/** This miniphase pickles trees */
class Pickler extends MiniPhaseTransform { thisTransform =>
  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
  }
  
  override def transformUnit(tree: Tree)(implicit ctx: Context, info: TransformerInfo): Tree = {
    if (!ctx.compilationUnit.isJava) {
      val pickler = new TastyPickler
      println(i"unpickling in run ${ctx.runId}")
      val previous = if (ctx.settings.YtestPickler.value) tree.show else ""
                  
      val treePkl = new TreePickler(pickler)
      treePkl.pickle(tree :: Nil)
      if (tree.pos.exists)
        new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil, tree.pos)

      val bytes = pickler.assembleParts()
      ctx.compilationUnit.pickled = bytes
      def rawBytes = // not needed right now, but useful to print raw format.
        bytes.iterator.grouped(10).toList.zipWithIndex.map {
          case (row, i) => s"${i}0: ${row.mkString(" ")}"
        }
      // println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
      if (Printers.pickling ne Printers.noPrinter) new TastyPrinter(bytes).printContents()
      
      if (ctx.settings.YtestPickler.value)
        unpickle(bytes, previous)(ctx.fresh.setPeriod(Period(ctx.runId + 1, FirstPhaseId)))
    }
    tree 
  }

  private def unpickle(bytes: Array[Byte], previous: String)(implicit ctx: Context) = {
    println(i"unpickle run = ${ctx.runId}")
    ctx.definitions.init
    val unpickled = i"${new DottyUnpickler(bytes, readPositions = false).result}%\n%"
    println(i"previous :\n $previous")
    println(i"unpickled:\n $unpickled")
    if (previous != unpickled) {
      output("before-pickling.txt", previous)
      output("after-pickling.txt", unpickled)
      println(s"""pickling difference for ${ctx.compilationUnit}, for details:
                 |
                 |  diff before-pickling.txt after-pickling.txt""".stripMargin)
    }
  }
}