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


                        
                                                                      

                               
                  
 
                     
 
                                              
 
                                                                              
                                              

                               
 
                                              

                                              
 








                                                                               

                          
                                                                
                                                 

                                                                            
                      

                                                                              
                                                            

                                                                        

                                                   

                                      
                                                                                   

     
                                        
                                              

                                                                                                                                        
                                                                                     



                                
                                                                    
 
                                                          






                                                                    
 
package dotty.tools.dotc
package core

import Periods._, SymDenotations._, Contexts._, Types._, Denotations._
import java.lang.AssertionError

trait Transformers

object Transformers {

  trait TransformerBase { self: ContextBase =>

    def transformersFor(ref: SingleDenotation): TransformerGroup = ref match {
      case _: SymDenotation => symTransformers
      case _ => refTransformers
    }

    val symTransformers = new TransformerGroup
    val refTransformers = new TransformerGroup
  }

  /** A transformer group contains a sequence of transformers,
   *  ordered by the phase where they apply. Transformers are added
   *  to a group via `install`.
   *
   *  There are two transformerGroups in a context base:
   *  symTransformers and refTransformers. symTransformers translate
   *  full symbol denotations, refTransformers translate only symbol references
   *  of type Unique/JointRefDenotation.
   */
  class TransformerGroup {

    /** A transformer transforms denotations at a given phase */
    abstract class Transformer extends DotClass {

      /** The phase at the start of which the denotations are transformed */
      val phaseId: Int

      /** The last phase during which the transformed denotations are valid */
      def lastPhaseId = nextTransformer(phaseId).phaseId - 1

      /** The validity period of the transformer in the given context */
      def validFor(implicit ctx: Context): Period =
        Period(ctx.runId, phaseId, lastPhaseId)

      /** The transformation method */
      def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation
    }

    /** A sentinel transformer object */
    object NoTransformer extends Transformer {
      val phaseId = MaxPossiblePhaseId + 1
      override def lastPhaseId = phaseId - 1 // TODO JZ Probably off-by-N error here. MO: Don't think so: we want empty validity period.
      def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation =
        unsupported("transform")
    }

    private val nxTransformer =
      Array.fill[Transformer](MaxPossiblePhaseId + 1)(NoTransformer)

    def nextTransformer(pid: PhaseId) = nxTransformer(pid)

    def install(pid: PhaseId, trans: Transformer): Unit =
      if ((pid > NoPhaseId) && (nxTransformer(pid).phaseId > pid)) {
        nxTransformer(pid) = trans
        install(pid - 1, trans)
      }
  }
}