Skip to content

Commit

Permalink
Reorganized scaladoc model
Browse files Browse the repository at this point in the history
Since the old model was "interruptible", it was prone to something
similar to race conditions -- where the model was creating a template,
that template creating was interrupted to creat another template, and
so on until a cycle was hit -- then, the loop would be broken by
returning the originally not-yet-finished template.

Now everything happens in a depth-first order, starting from root,
traversing packages and classes all the way to members. The previously
interrupting operations are now grouped in two categories:
 - those that were meant to add entities, like inheriting a class from
a template to the other (e.g. trait T { class C }; trait U extends T)
=> those were moved right after the core model creation
 - those that were meant to do lookups - like finding the companion
object -- those were moved after the model creation and inheritance
and are not allowed to create new documentable templates.

Now, for the documentable templates we have:

DocTemplateImpl - the main documentable template, it represents a
                  Scala template (class, trait, object or package).
                  It may only be created when modelFinished=false by
                  methods in the modelCreation object
NoDocTemplateMemberImpl - a non-documented (source not present)
                          template that was inherited. May be used as
                          a member, but does not get its own page
NoDocTemplateImpl - a non-documented (source not present) template
                    that may not be used as a member and does not
                    get its own page

For model users: you can use anything in the ModelFactory trait at
will, but not from the modelCreation object -- that is reserved for the
core model creation and using those functions may lead to duplicate
templates, invalid links and other ugly problems.
  • Loading branch information
VladUreche committed Jul 2, 2012
1 parent 44ec110 commit c11427c
Show file tree
Hide file tree
Showing 12 changed files with 466 additions and 281 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/doc/DocFactory.scala
Expand Up @@ -83,8 +83,8 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
with model.ModelFactoryImplicitSupport
with model.comment.CommentFactory
with model.TreeFactory {
override def templateShouldDocument(sym: compiler.Symbol) =
extraTemplatesToDocument(sym) || super.templateShouldDocument(sym)
override def templateShouldDocument(sym: compiler.Symbol, inTpl: TemplateImpl) =
extraTemplatesToDocument(sym) || super.templateShouldDocument(sym, inTpl)
}
)

Expand Down
19 changes: 10 additions & 9 deletions src/compiler/scala/tools/nsc/doc/Settings.scala
Expand Up @@ -155,15 +155,16 @@ class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) {
* the function result should be a humanly-understandable description of the type class
*/
val knownTypeClasses: Map[String, String => String] = Map() +
("<root>.scala.package.Numeric" -> ((tparam: String) => tparam + " is a numeric class, such as Int, Long, Float or Double")) +
("<root>.scala.package.Integral" -> ((tparam: String) => tparam + " is an integral numeric class, such as Int or Long")) +
("<root>.scala.package.Fractional" -> ((tparam: String) => tparam + " is a fractional numeric class, such as Float or Double")) +
("<root>.scala.reflect.Manifest" -> ((tparam: String) => tparam + " is accompanied by a Manifest, which is a runtime representation of its type that survives erasure")) +
("<root>.scala.reflect.ClassManifest" -> ((tparam: String) => tparam + " is accompanied by a ClassManifest, which is a runtime representation of its type that survives erasure")) +
("<root>.scala.reflect.OptManifest" -> ((tparam: String) => tparam + " is accompanied by an OptManifest, which can be either a runtime representation of its type or the NoManifest, which means the runtime type is not available")) +
("<root>.scala.reflect.ClassTag" -> ((tparam: String) => tparam + " is accompanied by a ClassTag, which is a runtime representation of its type that survives erasure")) +
("<root>.scala.reflect.AbsTypeTag" -> ((tparam: String) => tparam + " is accompanied by an AbsTypeTag, which is a runtime representation of its type that survives erasure")) +
("<root>.scala.reflect.TypeTag" -> ((tparam: String) => tparam + " is accompanied by a TypeTag, which is a runtime representation of its type that survives erasure"))
// TODO: Bring up to date and test these
("scala.package.Numeric" -> ((tparam: String) => tparam + " is a numeric class, such as Int, Long, Float or Double")) +
("scala.package.Integral" -> ((tparam: String) => tparam + " is an integral numeric class, such as Int or Long")) +
("scala.package.Fractional" -> ((tparam: String) => tparam + " is a fractional numeric class, such as Float or Double")) +
("scala.reflect.Manifest" -> ((tparam: String) => tparam + " is accompanied by a Manifest, which is a runtime representation of its type that survives erasure")) +
("scala.reflect.ClassManifest" -> ((tparam: String) => tparam + " is accompanied by a ClassManifest, which is a runtime representation of its type that survives erasure")) +
("scala.reflect.OptManifest" -> ((tparam: String) => tparam + " is accompanied by an OptManifest, which can be either a runtime representation of its type or the NoManifest, which means the runtime type is not available")) +
("scala.reflect.ClassTag" -> ((tparam: String) => tparam + " is accompanied by a ClassTag, which is a runtime representation of its type that survives erasure")) +
("scala.reflect.AbsTypeTag" -> ((tparam: String) => tparam + " is accompanied by an AbsTypeTag, which is a runtime representation of its type that survives erasure")) +
("scala.reflect.TypeTag" -> ((tparam: String) => tparam + " is accompanied by a TypeTag, which is a runtime representation of its type that survives erasure"))

/**
* Set of classes to exclude from index and diagrams
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/doc/html/Page.scala
Expand Up @@ -58,7 +58,7 @@ abstract class Page {

def templateToPath(tpl: TemplateEntity): List[String] = {
def doName(tpl: TemplateEntity): String =
NameTransformer.encode(tpl.name) + (if (tpl.isObject) "$" else "")
(if (tpl.inPackageObject) "package$$" else "") + NameTransformer.encode(tpl.name) + (if (tpl.isObject) "$" else "")
def downPacks(pack: Package): List[String] =
if (pack.isRootPackage) Nil else (doName(pack) :: downPacks(pack.inTemplate))
def downInner(nme: String, tpl: TemplateEntity): (String, Package) = {
Expand Down
36 changes: 18 additions & 18 deletions src/compiler/scala/tools/nsc/doc/html/page/Template.scala
Expand Up @@ -84,7 +84,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</div>

{ signature(tpl, true) }
{ memberToCommentHtml(tpl, true) }
{ memberToCommentHtml(tpl, tpl.inTemplate, true) }

<div id="mbrsel">
<div id='textfilter'><span class='pre'/><span class='input'><input id='mbrsel-input' type='text' accesskey='/'/></span><span class='post'/></div>
Expand All @@ -96,7 +96,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
{ if (tpl.linearizationTemplates.isEmpty && tpl.conversions.isEmpty) NodeSeq.Empty else
{
if (!tpl.linearization.isEmpty)
if (!tpl.linearizationTemplates.isEmpty)
<div id="ancestors">
<span class="filtertype">Inherited<br/>
</span>
Expand Down Expand Up @@ -138,35 +138,35 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
{ if (constructors.isEmpty) NodeSeq.Empty else
<div id="constructors" class="members">
<h3>Instance Constructors</h3>
<ol>{ constructors map (memberToHtml(_)) }</ol>
<ol>{ constructors map (memberToHtml(_, tpl)) }</ol>
</div>
}

{ if (typeMembers.isEmpty) NodeSeq.Empty else
<div id="types" class="types members">
<h3>Type Members</h3>
<ol>{ typeMembers map (memberToHtml(_)) }</ol>
<ol>{ typeMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}

{ if (absValueMembers.isEmpty) NodeSeq.Empty else
<div id="values" class="values members">
<h3>Abstract Value Members</h3>
<ol>{ absValueMembers map (memberToHtml(_)) }</ol>
<ol>{ absValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}

{ if (concValueMembers.isEmpty) NodeSeq.Empty else
<div id="values" class="values members">
<h3>{ if (absValueMembers.isEmpty) "Value Members" else "Concrete Value Members" }</h3>
<ol>{ concValueMembers map (memberToHtml(_)) }</ol>
<ol>{ concValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}

{ if (deprValueMembers.isEmpty) NodeSeq.Empty else
<div id="values" class="values members">
<h3>Deprecated Value Members</h3>
<ol>{ deprValueMembers map (memberToHtml(_)) }</ol>
<ol>{ deprValueMembers map (memberToHtml(_, tpl)) }</ol>
</div>
}
</div>
Expand Down Expand Up @@ -237,12 +237,12 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
tparamsToString(d.typeParams) + paramLists.mkString
}

def memberToHtml(mbr: MemberEntity): NodeSeq = {
def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = {
val defParamsString = mbr match {
case d:MemberEntity with Def => defParamsToString(d)
case _ => ""
}
val memberComment = memberToCommentHtml(mbr, false)
val memberComment = memberToCommentHtml(mbr, inTpl, false)
<li name={ mbr.definitionName } visbl={ if (mbr.visibility.isProtected) "prt" else "pub" }
data-isabs={ mbr.isAbstract.toString } fullComment={ if(memberComment.isEmpty) "no" else "yes" }>
<a id={ mbr.name +defParamsString +":"+ mbr.resultType.name}/>
Expand All @@ -251,24 +251,24 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</li>
}

def memberToCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq = {
def memberToCommentHtml(mbr: MemberEntity, inTpl: DocTemplateEntity, isSelf: Boolean): NodeSeq = {
mbr match {
case dte: DocTemplateEntity if isSelf =>
// comment of class itself
<xml:group>
<div id="comment" class="fullcommenttop">{ memberToCommentBodyHtml(mbr, isSelf = true) }</div>
<div id="comment" class="fullcommenttop">{ memberToCommentBodyHtml(mbr, inTpl, isSelf = true) }</div>
</xml:group>
case dte: DocTemplateEntity if mbr.comment.isDefined =>
// comment of inner, documented class (only short comment, full comment is on the class' own page)
memberToInlineCommentHtml(mbr, isSelf)
case _ =>
// comment of non-class member or non-documentented inner class
val commentBody = memberToCommentBodyHtml(mbr, isSelf = false)
val commentBody = memberToCommentBodyHtml(mbr, inTpl, isSelf = false)
if (commentBody.isEmpty)
NodeSeq.Empty
else {
val shortComment = memberToShortCommentHtml(mbr, isSelf)
val longComment = memberToUseCaseCommentHtml(mbr, isSelf) ++ memberToCommentBodyHtml(mbr, isSelf)
val longComment = memberToUseCaseCommentHtml(mbr, isSelf) ++ memberToCommentBodyHtml(mbr, inTpl, isSelf)

val includedLongComment = if (shortComment.text.trim == longComment.text.trim)
NodeSeq.Empty
Expand Down Expand Up @@ -298,7 +298,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
def memberToInlineCommentHtml(mbr: MemberEntity, isSelf: Boolean): NodeSeq =
<p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>

def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = {
def memberToCommentBodyHtml(mbr: MemberEntity, inTpl: DocTemplateEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = {

val memberComment =
if (mbr.comment.isEmpty) NodeSeq.Empty
Expand Down Expand Up @@ -383,7 +383,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}

<dd>
This member is added by an implicit conversion from { typeToHtml(mbr.inTemplate.resultType, true) } to
This member is added by an implicit conversion from { typeToHtml(inTpl.resultType, true) } to
{ targetType } performed by method { conversionMethod } in { conversionOwner }.
{ constraintText }
</dd>
Expand All @@ -404,7 +404,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage

val definitionClasses: Seq[scala.xml.Node] = {
val inDefTpls = mbr.inDefinitionTemplates
if ((inDefTpls.tail.isEmpty && (inDefTpls.head == mbr.inTemplate)) || isReduced) NodeSeq.Empty
if ((inDefTpls.tail.isEmpty && (inDefTpls.head == inTpl)) || isReduced) NodeSeq.Empty
else {
<dt>Definition Classes</dt>
<dd>{ templatesToHtml(inDefTpls, xml.Text("")) }</dd>
Expand Down Expand Up @@ -650,7 +650,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
<a href={nameLink}>{nameHtml}</a>
else nameHtml
}{
def tparamsToHtml(mbr: Entity): NodeSeq = mbr match {
def tparamsToHtml(mbr: Any): NodeSeq = mbr match {
case hk: HigherKinded =>
val tpss = hk.typeParams
if (tpss.isEmpty) NodeSeq.Empty else {
Expand All @@ -662,7 +662,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
<span class="tparams">[{ tparams0(tpss) }]</span>
}
case _ => NodeSeq.Empty
case _ => NodeSeq.Empty
}
tparamsToHtml(mbr)
}{
Expand Down
53 changes: 35 additions & 18 deletions src/compiler/scala/tools/nsc/doc/model/Entity.scala
Expand Up @@ -24,6 +24,9 @@ import comment._
* - annotations. */
trait Entity {

/** Similar to symbols, so we can track entities */
def id: Int

/** The name of the entity. Note that the name does not qualify this entity uniquely; use its `qualifiedName`
* instead. */
def name : String
Expand All @@ -48,6 +51,8 @@ trait Entity {
/** The annotations attached to this entity, if any. */
def annotations: List[Annotation]

/** The kind of the entity */
def kind: String
}

object Entity {
Expand Down Expand Up @@ -86,9 +91,11 @@ trait TemplateEntity extends Entity {
/** Whether this template is a case class. */
def isCaseClass: Boolean

/** Whether or not the template was defined in a package object */
def inPackageObject: Boolean

/** The self-type of this template, if it differs from the template type. */
def selfType : Option[TypeEntity]

}


Expand Down Expand Up @@ -177,7 +184,7 @@ object MemberEntity {
}

/** An entity that is parameterized by types */
trait HigherKinded extends Entity {
trait HigherKinded {

/** The type parameters of this entity. */
def typeParams: List[TypeParam]
Expand All @@ -187,8 +194,14 @@ trait HigherKinded extends Entity {

/** A template (class, trait, object or package) which is referenced in the universe, but for which no further
* documentation is available. Only templates for which a source file is given are documented by Scaladoc. */
trait NoDocTemplate extends TemplateEntity
trait NoDocTemplate extends TemplateEntity {
def kind = "<no doc>"
}

/** TODO: Document */
trait NoDocTemplateMemberEntity extends TemplateEntity with MemberEntity {
def kind = "<no doc, mbr>"
}

/** A template (class, trait, object or package) for which documentation is available. Only templates for which
* a source file is given are documented by Scaladoc. */
Expand All @@ -209,9 +222,6 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
/** The direct super-type of this template. */
def parentType: Option[TypeEntity]

@deprecated("Use `linearizationTemplates` and `linearizationTypes` instead", "2.9.0")
def linearization: List[(TemplateEntity, TypeEntity)]

/** All class, trait and object templates which are part of this template's linearization, in lineratization order.
* This template's linearization contains all of its direct and indirect super-classes and super-traits. */
def linearizationTemplates: List[TemplateEntity]
Expand Down Expand Up @@ -254,7 +264,9 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {


/** A trait template. */
trait Trait extends DocTemplateEntity with HigherKinded
trait Trait extends DocTemplateEntity with HigherKinded {
def kind = "trait"
}


/** A class template. */
Expand All @@ -270,11 +282,14 @@ trait Class extends Trait with HigherKinded {
* parameters cannot be curried, the outer list has exactly one element. */
def valueParams: List[List[ValueParam]]

override def kind = "class"
}


/** An object template. */
trait Object extends DocTemplateEntity
trait Object extends DocTemplateEntity {
def kind = "object"
}


/** A package template. A package is in the universe if it is declared as a package object, or if it
Expand All @@ -290,6 +305,8 @@ trait Package extends Object {

/** All packages that are member of this package. */
def packages: List[Package]

override def kind = "package"
}


Expand Down Expand Up @@ -323,6 +340,7 @@ trait Def extends NonTemplateMemberEntity with HigherKinded {
* Each parameter block is a list of value parameters. */
def valueParams : List[List[ValueParam]]

def kind = "method"
}


Expand All @@ -337,11 +355,14 @@ trait Constructor extends NonTemplateMemberEntity {
* element. */
def valueParams : List[List[ValueParam]]

def kind = "constructor"
}


/** A value (`val`), lazy val (`lazy val`) or variable (`var`) of a template. */
trait Val extends NonTemplateMemberEntity
trait Val extends NonTemplateMemberEntity {
def kind = "[lazy] value/variable"
}


/** An abstract type member of a template. */
Expand All @@ -353,6 +374,7 @@ trait AbstractType extends NonTemplateMemberEntity with HigherKinded {
/** The upper bound for this abstract type, if it has been defined. */
def hi: Option[TypeEntity]

def kind = "abstract type"
}


Expand All @@ -362,18 +384,14 @@ trait AliasType extends NonTemplateMemberEntity with HigherKinded {
/** The type aliased by this type alias. */
def alias: TypeEntity

def kind = "type alias"
}


/** A parameter to an entity. */
trait ParameterEntity extends Entity {

/** Whether this parameter is a type parameter. */
def isTypeParam: Boolean

/** Whether this parameter is a value parameter. */
def isValueParam: Boolean
trait ParameterEntity {

def name: String
}


Expand All @@ -388,7 +406,6 @@ trait TypeParam extends ParameterEntity with HigherKinded {

/** The upper bound for this type parameter, if it has been defined. */
def hi: Option[TypeEntity]

}


Expand All @@ -403,7 +420,6 @@ trait ValueParam extends ParameterEntity {

/** Whether this value parameter is implicit. */
def isImplicit: Boolean

}


Expand All @@ -416,6 +432,7 @@ trait Annotation extends Entity {
/** The arguments passed to the constructor of the annotation class. */
def arguments: List[ValueArgument]

def kind = "annotation"
}

/** A trait that signals the member results from an implicit conversion */
Expand Down

0 comments on commit c11427c

Please sign in to comment.