aboutsummaryrefslogblamecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/PrivateToStatic.scala.disabled
blob: 218839d010be5d31df7704d26ad9065d6da330ec (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                       





                                                                                   








                                                                              
                                                            
                                               
                      













                                                                                          











                                                                                                                 
                                                                     






                                                                                          



                                                                      


                                                                                            
                                                                                              















                                                                                                
package dotty.tools.dotc
package transform

import core._
import DenotTransformers.SymTransformer
import Contexts.Context
import Symbols._
import Scopes._
import Flags._
import StdNames._
import SymDenotations._
import Types._
import collection.mutable
import TreeTransforms._
import Decorators._
import ast.Trees._
import TreeTransforms.TransformerInfo

/** Makes private methods static, provided they not deferred, accessors, or static,
 *  by rewriting a method `m` in class `C` as follows:
 *
 *     private def m(ps) = e
 *
 *     --> private static def($this: C, ps) = [this -> $this] e
 */
class PrivateToStatic extends MiniPhase with SymTransformer { thisTransform =>
  import ast.tpd._
  override def phaseName = "privateToStatic"
  override def relaxedTyping = true

  private val Immovable = Deferred | Accessor | JavaStatic

  def shouldBeStatic(sd: SymDenotation)(implicit ctx: Context) =
    sd.current(ctx.withPhase(thisTransform)).asSymDenotation
      .is(PrivateMethod, butNot = Immovable) &&
    sd.owner.is(Trait)

  override def transformSym(sd: SymDenotation)(implicit ctx: Context): SymDenotation =
    if (shouldBeStatic(sd)) {
      val mt @ MethodType(pnames, ptypes) = sd.info
      sd.copySymDenotation(
        initFlags = sd.flags | JavaStatic,
        info = MethodType(nme.SELF :: pnames, sd.owner.thisType :: ptypes, mt.resultType))
    }
    else sd

  val treeTransform = new Transform(NoSymbol)

  class Transform(thisParam: Symbol) extends TreeTransform {
    def phase = thisTransform

    override def prepareForDefDef(tree: DefDef)(implicit ctx: Context) =
      if (shouldBeStatic(tree.symbol)) {
        val selfParam = ctx.newSymbol(tree.symbol, nme.SELF, Param, tree.symbol.owner.thisType, coord = tree.pos)
        new Transform(selfParam)
      }
      else this

    override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo) =
      if (shouldBeStatic(tree.symbol)) {
        val thisParamDef = ValDef(thisParam.asTerm)
        val vparams :: Nil = tree.vparamss
        cpy.DefDef(tree)(vparamss = (thisParamDef :: vparams) :: Nil)
      }
      else tree

    override def transformThis(tree: This)(implicit ctx: Context, info: TransformerInfo) =
      if (shouldBeStatic(ctx.owner.enclosingMethod)) ref(thisParam).withPos(tree.pos)
      else tree

    /** Rwrites a call to a method `m` which is made static as folows:
     *
     *    qual.m(args)  -->  m(qual, args)
     */
    override def transformApply(tree: Apply)(implicit ctx: Context, info: TransformerInfo) =
      tree.fun match {
        case fun @ Select(qual, name) if shouldBeStatic(fun.symbol) =>
          ctx.debuglog(i"mapping $tree to ${cpy.Ident(fun)(name)} (${qual :: tree.args}%, %)")
          cpy.Apply(tree)(ref(fun.symbol).withPos(fun.pos), qual :: tree.args)
        case _ =>
          tree
      }

    override def transformClosure(tree: Closure)(implicit ctx: Context, info: TransformerInfo) =
      tree.meth match {
        case meth @ Select(qual, name) if shouldBeStatic(meth.symbol) =>
          cpy.Closure(tree)(
            env = qual :: tree.env,
            meth = ref(meth.symbol).withPos(meth.pos))
        case _ =>
          tree
    }
  }
}