Skip to content

Commit add19e6

Browse files
committed
No longer cache all subclass templates.
Instead only cache direct subclasses and compute all known subclasses as a transitive closure.
1 parent 005a08d commit add19e6

File tree

3 files changed

+32
-40
lines changed

3 files changed

+32
-40
lines changed

src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import model._
1515
import model.diagram._
1616
import scala.xml.{ NodeSeq, Text, UnprefixedAttribute }
1717
import scala.language.postfixOps
18+
import scala.collection.mutable. { Set, HashSet }
1819

1920
import model._
2021
import model.diagram._
@@ -636,13 +637,23 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
636637
}
637638

638639
val subclasses = mbr match {
639-
case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.allSubClasses.nonEmpty =>
640-
<div class="toggleContainer block">
641-
<span class="toggle">Known Subclasses</span>
642-
<div class="subClasses hiddenContent">{
643-
templatesToHtml(dtpl.allSubClasses.sortBy(_.name), scala.xml.Text(", "))
644-
}</div>
645-
</div>
640+
case dtpl: DocTemplateEntity if isSelf && !isReduced =>
641+
val subs: Set[DocTemplateEntity] = HashSet.empty
642+
def transitive(dtpl: DocTemplateEntity) {
643+
for (sub <- dtpl.directSubClasses if !(subs contains sub)) {
644+
subs add sub
645+
transitive(sub)
646+
}
647+
}
648+
transitive(dtpl)
649+
if (subs.nonEmpty)
650+
<div class="toggleContainer block">
651+
<span class="toggle">Known Subclasses</span>
652+
<div class="subClasses hiddenContent">{
653+
templatesToHtml(subs.toList.sortBy(_.name), scala.xml.Text(", "))
654+
}</div>
655+
</div>
656+
else NodeSeq.Empty
646657
case _ => NodeSeq.Empty
647658
}
648659

src/scaladoc/scala/tools/nsc/doc/model/Entity.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,10 +258,6 @@ trait DocTemplateEntity extends MemberTemplateEntity {
258258
* This template's linearization contains all of its direct and indirect super-types. */
259259
def linearizationTypes: List[TypeEntity]
260260

261-
/** All class, trait and object templates for which this template is a direct or indirect super-class or super-trait.
262-
* Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */
263-
def allSubClasses: List[DocTemplateEntity]
264-
265261
/** All class, trait and object templates for which this template is a *direct* super-class or super-trait.
266262
* Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */
267263
def directSubClasses: List[DocTemplateEntity]

src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -277,14 +277,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
277277
override def linkTarget: DocTemplateImpl = this
278278
override def toRoot: List[DocTemplateImpl] = this :: inTpl.toRoot
279279

280-
protected def inSourceFromSymbol(symbol: Symbol) =
281-
if (symbol.sourceFile != null && ! symbol.isSynthetic)
282-
Some((symbol.sourceFile, symbol.pos.line))
280+
protected def reprSymbol: Symbol = sym
281+
282+
def inSource =
283+
if (reprSymbol.sourceFile != null && ! reprSymbol.isSynthetic)
284+
Some((reprSymbol.sourceFile, reprSymbol.pos.line))
283285
else
284286
None
285287

286-
def inSource = inSourceFromSymbol(sym)
287-
288288
def sourceUrl = {
289289
def fixPath(s: String) = s.replaceAll("\\" + java.io.File.separator, "/")
290290
val assumedSourceRoot = fixPath(settings.sourcepath.value) stripSuffix "/"
@@ -306,20 +306,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
306306
else None
307307
}
308308

309-
protected def linearizationFromSymbol(symbol: Symbol): List[(TemplateEntity, TypeEntity)] = {
310-
symbol.ancestors map { ancestor =>
311-
val typeEntity = makeType(symbol.info.baseType(ancestor), this)
312-
val tmplEntity = makeTemplate(ancestor) match {
313-
case tmpl: DocTemplateImpl => tmpl registerSubClass this ; tmpl
314-
case tmpl => tmpl
315-
}
316-
(tmplEntity, typeEntity)
317-
}
318-
}
319-
320-
lazy val linearization = linearizationFromSymbol(sym)
321-
def linearizationTemplates = linearization map { _._1 }
322-
def linearizationTypes = linearization map { _._2 }
309+
lazy val (linearizationTemplates, linearizationTypes) =
310+
reprSymbol.ancestors map { ancestor =>
311+
(makeTemplate(ancestor), makeType(reprSymbol.info.baseType(ancestor), this))
312+
} unzip
323313

324314
/* Subclass cache */
325315
private lazy val subClassesCache = (
@@ -330,8 +320,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
330320
if (subClassesCache != null)
331321
subClassesCache += sc
332322
}
333-
def allSubClasses = if (subClassesCache == null) Nil else subClassesCache.toList
334-
def directSubClasses = allSubClasses.filter(_.parentTypes.map(_._1).contains(this))
323+
def directSubClasses = if (subClassesCache == null) Nil else subClassesCache.toList
335324

336325
/* Implcitly convertible class cache */
337326
private var implicitlyConvertibleClassesCache: mutable.ListBuffer[(DocTemplateImpl, ImplicitConversionImpl)] = null
@@ -387,10 +376,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
387376

388377
members :::= memberSymsLazy.map(modelCreation.createLazyTemplateMember(_, this))
389378

390-
// compute linearization to register subclasses
391-
linearization
392379
outgoingImplicitlyConvertedClasses
393380

381+
for (pt <- sym.info.parents; parentTemplate <- findTemplateMaybe(pt.typeSymbol)) parentTemplate registerSubClass this
382+
394383
// the members generated by the symbols in memberSymsEager PLUS the members from the usecases
395384
val allMembers = ownMembers ::: ownMembers.flatMap(_.useCaseOf).distinct
396385
implicitsShadowing = makeShadowingTable(allMembers, conversions, this)
@@ -472,12 +461,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
472461
abstract class PackageImpl(sym: Symbol, inTpl: PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package {
473462
override def inTemplate = inTpl
474463
override def toRoot: List[PackageImpl] = this :: inTpl.toRoot
475-
override lazy val (inSource, linearization) = {
476-
val representive = sym.info.members.find {
477-
s => s.isPackageObject
478-
} getOrElse sym
479-
(inSourceFromSymbol(representive), linearizationFromSymbol(representive))
480-
}
464+
override def reprSymbol = sym.info.members.find (_.isPackageObject) getOrElse sym
465+
481466
def packages = members collect { case p: PackageImpl if !(droppedPackages contains p) => p }
482467
}
483468

0 commit comments

Comments
 (0)