diff options
Diffstat (limited to 'doc-tool/src/dotty/tools/dottydoc/core/StatisticsPhase.scala')
-rw-r--r-- | doc-tool/src/dotty/tools/dottydoc/core/StatisticsPhase.scala | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/doc-tool/src/dotty/tools/dottydoc/core/StatisticsPhase.scala b/doc-tool/src/dotty/tools/dottydoc/core/StatisticsPhase.scala new file mode 100644 index 000000000..e7f9a9ec7 --- /dev/null +++ b/doc-tool/src/dotty/tools/dottydoc/core/StatisticsPhase.scala @@ -0,0 +1,156 @@ +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) + } +} |