aboutsummaryrefslogblamecommitdiff
path: root/compiler/src/dotty/tools/dotc/transform/SelectStatic.scala
blob: 5d60bb984102347aa7693751383be1977571ff07 (plain) (tree)
1
2
3
4


                        
                                   










                                                                               





                                                                                              


                                                                                                            








                                                                                         
               
 
                    



                                                                   
                                           

                                         

                                             




                                                                                                          
   



                                                                                                                  
 
package dotty.tools.dotc
package transform

import dotty.tools.dotc.ast.Trees._
import dotty.tools.dotc.ast.tpd
import dotty.tools.dotc.core.Contexts.Context
import dotty.tools.dotc.core.DenotTransformers.IdentityDenotTransformer
import dotty.tools.dotc.core.Flags._
import dotty.tools.dotc.core.Symbols._
import dotty.tools.dotc.core._
import dotty.tools.dotc.transform.TreeTransforms._

/** Removes selects that would be compiled into GetStatic
 * otherwise backend needs to be aware that some qualifiers need to be dropped.
 * Similar transformation seems to be performed by flatten in nsc
 * @author Dmytro Petrashko
 */
class SelectStatic extends MiniPhaseTransform with IdentityDenotTransformer { thisTransform =>
  import ast.tpd._

  override def phaseName: String = "selectStatic"

  override def transformSelect(tree: tpd.Select)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
    val sym = tree.symbol
    def isStaticMember =
      (sym is Flags.Module) && sym.initial.maybeOwner.initial.isStaticOwner ||
      (sym is Flags.JavaStatic) ||
      (sym.maybeOwner is Flags.ImplClass) ||
      sym.hasAnnotation(ctx.definitions.ScalaStaticAnnot)
    val isStaticRef = !sym.is(Package) && !sym.maybeOwner.is(Package) && isStaticMember
    val tree1 =
      if (isStaticRef && !tree.qualifier.symbol.is(JavaModule) && !tree.qualifier.isType)
        Block(List(tree.qualifier), ref(sym))
      else tree

    normalize(tree1)
  }

  private def normalize(t: Tree)(implicit ctx: Context) = t match {
    case Select(Block(stats, qual), nm) =>
      Block(stats, cpy.Select(t)(qual, nm))
    case Apply(Block(stats, qual), nm) =>
      Block(stats, Apply(qual, nm))
    case TypeApply(Block(stats, qual), nm) =>
      Block(stats, TypeApply(qual, nm))
    case _ => t
  }

  override def transformApply(tree: tpd.Apply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
    normalize(tree)
  }

  override def transformTypeApply(tree: tpd.TypeApply)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
    normalize(tree)
  }
}