dotty.tools.dottydoc.core.StatisticsPhase.scala Maven / Gradle / Ivy
The newest version!
package dotty.tools
package dottydoc
package core
import dotc.core.Phases.Phase
import dotc.core.Contexts.Context
import dotc.core.Symbols.Symbol
import dotc.core.Decorators._
import dotc.core.Flags._
import dotc.CompilationUnit
import dottydoc.util.syntax._
import dottydoc.util.traversing._
import model._
object Statistics {
implicit class MapTotals(val map: Map[String, Statistics]) extends AnyVal {
def totalEntities =
map.values.foldLeft(0)(_ + _.totalEntities)
}
}
case class Statistics(pkgName: String, api: Counters, internalApi: Counters) {
def totalEntities =
api.totalEntities + internalApi.totalEntities
def totalDocstrings =
api.totalDocstrings + internalApi.totalDocstrings
}
case class Counters(
publicEntities: Int,
privateEntities: Int,
protectedEntities: Int,
publicDocstrings: Int,
privateDocstrings: Int,
protectedDocstrings: Int
) {
def totalEntities =
publicEntities + privateEntities + protectedEntities
def totalDocstrings =
publicDocstrings + privateDocstrings + protectedDocstrings
def merge(o: Counters): Counters = Counters(
publicEntities + o.publicEntities,
privateEntities + o.privateEntities,
protectedEntities + o.protectedEntities,
publicDocstrings + o.publicDocstrings,
privateDocstrings + o.privateDocstrings,
protectedDocstrings + o.protectedDocstrings
)
}
class StatisticsPhase extends Phase {
def phaseName = "StatisticsPhase"
override def run(implicit ctx: Context): Unit = ()
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
for {
(pkgName, pack) <- ctx.docbase.packages
externalApi = collectPublicStats(pack)
internalApi = collectInternalStats(pack)
stats = Statistics(pkgName, externalApi, internalApi)
} ctx.docbase.registerStatistics(pkgName, stats)
units
}
def collectPublicStats(pack: Package)(implicit ctx: Context): Counters = {
var publicEntities: Int = 0
var protectedEntities: Int = 0
var publicDocstrings: Int = 0
var protectedDocstrings: Int = 0
if (pack.comment.isDefined) {
publicEntities += 1
publicDocstrings += 1
}
def doCount(sym: Symbol, comment: Int): Unit =
if (!sym.is(Protected)) {
publicEntities += 1
publicDocstrings += comment
}
else {
protectedEntities += 1
protectedDocstrings += comment
}
def recur(e: Entity, reachable: Boolean): Unit = {
val isVisible = !e.symbol.is(Private) && !e.symbol.privateWithin.exists
val shouldCount = isVisible && reachable
e match {
case e: Package => ()
case e: Entity with Members => if (shouldCount) {
doCount(e.symbol, if (e.comment.isDefined) 1 else 0)
e.members.foreach { c =>
if (!(e.symbol.is(Final) && c.symbol.is(Protected))) recur(c, true)
}
}
case e =>
if (shouldCount) doCount(e.symbol, if (e.comment.isDefined) 1 else 0)
}
}
pack.members.foreach(recur(_, true))
Counters(publicEntities, 0, protectedEntities, publicDocstrings, 0, protectedDocstrings)
}
def collectInternalStats(pack: Package)(implicit ctx: Context): Counters = {
var publicEntities: Int = 0
var privateEntities: Int = 0
var protectedEntities: Int = 0
var publicDocstrings: Int = 0
var privateDocstrings: Int = 0
var protectedDocstrings: Int = 0
def doCount(sym: Symbol, comment: Int): Unit =
if (sym.is(Private)) {
privateEntities += 1
privateDocstrings += comment
}
else if (!sym.is(Protected)) {
publicEntities += 1
publicDocstrings += comment
}
else {
protectedEntities += 1
protectedDocstrings += comment
}
def recur(e: Entity, reachable: Boolean): Unit = {
val internal = !reachable || e.symbol.is(Private) || e.symbol.privateWithin.exists
e match {
case _: Package => ()
case e: Entity with Members =>
e.members.foreach { c =>
val childIsInternal = !internal || (e.symbol.is(Final) && c.symbol.is(Protected))
recur(c, childIsInternal)
}
if (internal) doCount(e.symbol, if (e.comment.isDefined) 1 else 0)
case _ =>
if (internal) doCount(e.symbol, if (e.comment.isDefined) 1 else 0)
}
}
pack.members.foreach(recur(_, true))
Counters(publicEntities, privateEntities, protectedEntities, publicDocstrings, privateDocstrings, protectedDocstrings)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy