All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dotty.tools.dotc.transform.CountOuterAccesses.scala Maven / Gradle / Ivy

There is a newer version: 3.6.4-RC1-bin-20241220-0bfa1af-NIGHTLY
Show newest version
package dotty.tools.dotc
package transform

import core.*
import MegaPhase.MiniPhase
import dotty.tools.dotc.core.Contexts.*
import ast.*
import Flags.*
import Symbols.*
import ExplicitOuter.isOuterParamAccessor

import collection.mutable

object CountOuterAccesses:
  val name: String = "countOuterAccesses"
  val description: String = "identify outer accessors that can be dropped"

  /** Characterizes outer accessors and outer fields that can be dropped
   *  if there are no references to them from within the toplevel class
   *  where they are defined.
   */
  def mightBeDropped(sym: Symbol)(using Context) =
    def isLocal(cls: Symbol) =
      cls.isAnonymousClass
      || cls.owner.isTerm
      || cls.accessBoundary(defn.RootClass).isContainedIn(cls.topLevelClass)
    (sym.is(OuterAccessor) || sym.isOuterParamAccessor) && isLocal(sym.owner)

/** Counts number of accesses to outer accessors and outer fields of
 *  classes that are visible only within one source file. The info
 *  is collected in `outerAccessCount` and used in the subsequent
 *  DropOuterAccessors phase
 */
class CountOuterAccesses extends MiniPhase:
  thisPhase =>
  import tpd.*

  override def phaseName: String = CountOuterAccesses.name

  override def description: String = CountOuterAccesses.description

  override def runsAfter: Set[String] = Set(LambdaLift.name)
    // LambdaLift can create outer paths. These need to be known in this phase.

  /** The number of times an outer accessor that might be dropped is accessed */
  val outerAccessCount = new mutable.HashMap[Symbol, Int].withDefaultValue(0)

  private def markAccessed(tree: RefTree)(using Context): Tree =
    val sym = tree.symbol
    if CountOuterAccesses.mightBeDropped(sym) then outerAccessCount(sym) += 1
    tree

  override def transformIdent(tree: Ident)(using Context): Tree =
    markAccessed(tree)

  override def transformSelect(tree: Select)(using Context): Tree =
    markAccessed(tree)




© 2015 - 2025 Weber Informatics LLC | Privacy Policy