Skip to content

Commit

Permalink
[scaladoc] Types are links.
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilles Dubochet committed Dec 2, 2009
1 parent 5697e11 commit 6995333
Show file tree
Hide file tree
Showing 17 changed files with 328 additions and 240 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/ant/Scaladoc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ class Scaladoc extends MatchingTask {
val Pair(docSettings, sourceFiles) = initialize
val reporter = new ConsoleReporter(docSettings)
try {
val docProcessor = new scala.tools.nsc.doc.Processor(reporter, docSettings)
val docProcessor = new scala.tools.nsc.doc.DocFactory(reporter, docSettings)
docProcessor.document(sourceFiles.map (_.toString))
if (reporter.ERROR.count > 0)
error(
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/ScalaDoc.scala
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ object ScalaDoc {
docSettings.assemrefs.value = docSettings.assemrefs.value + File.pathSeparator + libpath
}

val docProcessor = new scala.tools.nsc.doc.Processor(reporter, docSettings)
val docProcessor = new scala.tools.nsc.doc.DocFactory(reporter, docSettings)
docProcessor.document(command.files)

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import reporters.Reporter
* @param settings The settings to be used by the documenter and compiler for generating documentation.
*
* @author Gilles Dubochet */
class Processor(val reporter: Reporter, val settings: doc.Settings) { processor =>
class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor =>

/** The unique compiler instance used by this processor and constructed from its `settings`. */
object compiler extends Global(settings, reporter) {
Expand All @@ -49,8 +49,13 @@ class Processor(val reporter: Reporter, val settings: doc.Settings) { processor
def document(files: List[String]): Unit = {
(new compiler.Run()) compile files
compiler.addSourceless
if (!reporter.hasErrors)
(new html.SiteFactory(reporter, settings)) generate (new model.EntityFactory(compiler, settings)).makeModel
if (!reporter.hasErrors) {
val modelFactory = (new model.ModelFactory(compiler, settings))
val htmlFactory = (new html.HtmlFactory(reporter, settings))
val docModel = modelFactory.makeModel
println("model contains " + modelFactory.templatesCount + " documentable templates")
htmlFactory generate docModel
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import scala.collection._
/** A class that can generate Scaladoc sites to some fixed root folder.
* @author David Bernard
* @author Gilles Dubochet */
class SiteFactory(val reporter: Reporter, val settings: Settings) {
class HtmlFactory(val reporter: Reporter, val settings: Settings) {

/** The character encoding to be used for generated Scaladoc sites. This value is currently always UTF-8. */
def encoding: String = "UTF-8"
Expand Down
36 changes: 29 additions & 7 deletions src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ abstract class HtmlPage { thisPage =>
/** Writes this page as a file. The file's location is relative to the generator's site root, and the encoding is
* also defined by the generator.
* @param generator The generator that is writing this page. */
def writeFor(site: SiteFactory): Unit = {
def writeFor(site: HtmlFactory): Unit = {
val pageFile = new File(site.siteRoot, absoluteLinkTo(thisPage.path))
val pageFolder = pageFile.getParentFile
if (!pageFolder.exists) pageFolder.mkdirs()
Expand Down Expand Up @@ -145,12 +145,34 @@ abstract class HtmlPage { thisPage =>
case Text(text) => Unparsed(text)
}

def typeToHtml(tpe: model.TypeEntity): NodeSeq = {

// TODO: Generate links using tpe's refEntity map

xml.Text(tpe.name)

def typeToHtml(tpe: model.TypeEntity, hasLinks: Boolean): NodeSeq = {
val string = tpe.name
def toLinksOut(inPos: Int, starts: List[Int]): NodeSeq = {
if (starts.isEmpty && (inPos == string.length))
NodeSeq.Empty
else if (starts.isEmpty)
xml.Text(string.slice(inPos, string.length))
else if (inPos == starts.head)
toLinksIn(inPos, starts)
else {
xml.Text(string.slice(inPos, starts.head)) ++ toLinksIn(starts.head, starts)
}
}
def toLinksIn(inPos: Int, starts: List[Int]): NodeSeq = {
val (tpl, width) = tpe.refEntity(inPos)
(tpl match {
case dtpl:DocTemplateEntity if hasLinks =>
<a href={ relativeLinkTo(tpl) } class="extype" name={ dtpl.qualifiedName }>{
string.slice(inPos, inPos + width)
}</a>
case tpl =>
<span class="extype" name={ tpl.qualifiedName }>{ string.slice(inPos, inPos + width) }</span>
}) ++ toLinksOut(inPos + width, starts.tail)
}
if (hasLinks)
toLinksOut(0, tpe.refEntity.keySet.toList)
else
xml.Text(string)
}

}
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/doc/html/page/Index.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Index(modelRoot: Package) extends HtmlPage {
def body =
<body>
<div id="browser">
<input id="quickflt" type="text"/>
<input id="quickflt" type="text" accesskey="/"/>
<div id="tpl">{
def packageElem(pack: model.Package): NodeSeq = {
<xml:group>
Expand Down
60 changes: 28 additions & 32 deletions src/compiler/scala/tools/nsc/doc/html/page/Template.scala
Original file line number Diff line number Diff line change
Expand Up @@ -137,30 +137,28 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
if (tme.isDef) "def" else if (tme.isVal) "val" else if (tme.isVar) "var" else "type"
}

def boundsToString(hi: Option[TypeEntity], lo: Option[TypeEntity]): String = {
def bound0(bnd: Option[TypeEntity], pre: String): String = bnd match {
case None => ""
case Some(tpe) => pre + typeToHtml(tpe)
def boundsToHtml(hi: Option[TypeEntity], lo: Option[TypeEntity], hasLinks: Boolean): NodeSeq = {
def bound0(bnd: Option[TypeEntity], pre: String): NodeSeq = bnd match {
case None => NodeSeq.Empty
case Some(tpe) => xml.Text(pre) ++ typeToHtml(tpe, hasLinks)
}
bound0(hi, " <: ") + bound0(lo, " >: ")
bound0(hi, " <: ") ++ bound0(lo, " >: ")
}

/** name, tparams, params, result */
def signature(mbr: MemberEntity, isSelf: Boolean): NodeSeq = {
val inside: NodeSeq =
def inside(hasLinks: Boolean): NodeSeq =
<xml:group>
<div class="kind">{ kindToString(mbr) }</div>
<div class="symbol">
<span class="name">{ if (mbr.isConstructor) tpl.name else mbr.name }</span>
{ def tparamsToHtml(tpss: List[TypeParam]): NodeSeq =
<span class="kind">{ kindToString(mbr) }</span>
<span class="symbol">
<span class="name">{ if (mbr.isConstructor) tpl.name else mbr.name }</span>{
def tparamsToHtml(tpss: List[TypeParam]): NodeSeq =
if (tpss.isEmpty) NodeSeq.Empty else {
def tparam0(tp: TypeParam): NodeSeq =
<span name={ tp.name }>{
tp.variance + tp.name + boundsToString(tp.hi, tp.lo)
}</span>
<span name={ tp.name }>{ tp.variance + tp.name }{ boundsToHtml(tp.hi, tp.lo, hasLinks)}</span>
def tparams0(tpss: List[TypeParam]): NodeSeq = (tpss: @unchecked) match {
case tp :: Nil => tparam0(tp)
case tp :: tps => tparam0(tp) ++ Text(",") ++ tparams0(tps)
case tp :: tps => tparam0(tp) ++ Text(", ") ++ tparams0(tps)
}
<span class="tparams">[{ tparams0(tpss) }]</span>
}
Expand All @@ -169,16 +167,14 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
case dfe: Def => tparamsToHtml(dfe.typeParams)
case _ => NodeSeq.Empty
}
}
{ def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = {
}{
def paramsToHtml(vlsss: List[List[ValueParam]]): NodeSeq = {
def param0(vl: ValueParam): NodeSeq =
<span name={ vl.name }>{
vl.name + ": " + typeToHtml(vl.resultType)
}</span>
<span name={ vl.name }>{ vl.name + ": " }{ typeToHtml(vl.resultType, hasLinks) }</span>
def params0(vlss: List[ValueParam]): NodeSeq = vlss match {
case Nil => NodeSeq.Empty
case vl :: Nil => param0(vl)
case vl :: vls => param0(vl) ++ Text(",") ++ params0(vls)
case vl :: vls => param0(vl) ++ Text(", ") ++ params0(vls)
}
vlsss map { vlss => <span class="params">({ params0(vlss) })</span> }
}
Expand All @@ -188,32 +184,32 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
case dfe: Def => paramsToHtml(dfe.valueParams)
case _ => NodeSeq.Empty
}
}
{ mbr match {
}{
mbr match {
case tpl: DocTemplateEntity if (!tpl.isPackage) =>
tpl.parentType match {
case Some(st) => <span class="result">extends<span>{ typeToHtml(st) }</span></span>
case Some(st) => <span class="result"> extends { typeToHtml(st, hasLinks) }</span>
case None =>NodeSeq.Empty
}
case tme: MemberEntity if (tme.isDef || tme.isVal || tme.isVar) =>
<span class="result">:<span>{ typeToHtml(tme.resultType) }</span></span>
<span class="result">: { typeToHtml(tme.resultType, hasLinks) }</span>
case abt: AbstractType =>
val b2s = boundsToString(abt.hi, abt.lo)
if (b2s != "")
<span class="result"><span>{ b2s }</span></span>
val b2s = boundsToHtml(abt.hi, abt.lo, hasLinks)
if (b2s != NodeSeq.Empty)
<span class="result">{ b2s }</span>
else NodeSeq.Empty
case alt: AliasType =>
<span class="result">=<span>{ typeToHtml(alt.alias) }</span></span>
<span class="result"> = { typeToHtml(alt.alias, hasLinks) }</span>
case _ => NodeSeq.Empty
}
}
</div>
</xml:group>
</span>
</xml:group>
mbr match {
case dte: DocTemplateEntity if !isSelf =>
<a class="signature" href={ relativeLinkTo(dte) }>{ inside }</a>
<a class="signature" href={ relativeLinkTo(dte) }>{ inside(hasLinks = false) }</a>
case _ =>
<div class="signature">{ inside }</div>
<div class="signature">{ inside(hasLinks = true) }</div>
}
}

Expand Down
50 changes: 31 additions & 19 deletions src/compiler/scala/tools/nsc/doc/html/resource/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,69 @@
<script type="text/javascript" src="lib/index.js"></script>
</head>
<body>
<h1>Documentation</h1>
<div id="browser">
<input id="quickflt" type="text"/>
<input id="quickflt" type="text" accesskey="/"/>
<div id="tpl">
<ol class="packages">
<li>
<h3><a class="tplshow" href="scala/collection/package.html">scala.collection</a></h3>
<h3><a href="scala/collection/package.html">scala.collection</a></h3>
<ol class="templates">
<li title="scala.collection.BitSet">
<a class="tplshow" href="scala/collection/BitSet.html">BitSet <span class="class">(class)</span></a>
<a class="tplshow" href="scala/collection/BitSet$.html"><span class="object">(object)</span></a>
<a href="scala/collection/BitSet$.html">
<span>(object)</span>
</a>
<a href="scala/collection/BitSet.html">
<span>(class)</span>
<span>BitSet</span>
</a>
</li>
<li title="scala.collection.BufferedIterator">
<a class="tplshow" href="scala/collection/BufferedIterator.html">BufferedIterator <span class="trait">(trait)</span></a>
<a href="scala/collection/BufferedIterator.html">
<span>(trait)</span>
<span>BufferedIterator</span>
</a>
</li>
<li title="scala.collection.DefaultMap">
<a class="tplshow" href="scala/collection/DefaultMap$.html">DefaultMap <span class="class">(object)</span></a>
<a href="scala/collection/DefaultMap$.html">
<span>(object)</span>
<span>DefaultMap</span>
</a>
</li>
<li title="scala.collection.Iterable">
<a class="tplshow" href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a class="tplshow" href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
<a href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
</li>
</ol>
<ol class="packages">
<li>
<h3>scala.collection.mutable</h3>
<h3><a class="tplshow">scala.collection.mutable</a></h3>
<ol class="templates">
<li title="scala.collection.mutable.DefaultMap">
<a class="tplshow" href="scala/collection/DefaultMap$.html">DefaultMap <span class="class">(object)</span></a>
<a href="scala/collection/DefaultMap$.html">DefaultMap <span class="class">(object)</span></a>
</li>
<li title="scala.collection.mutable.Iterable">
<a class="tplshow" href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a class="tplshow" href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
<a href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
</li>
<li title="scala.collection.mutable.Iterable">
<a class="tplshow" href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a class="tplshow" href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
<a href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
</li>
<li title="scala.collection.mutable.Truc">
<a class="tplshow" href="scala/collection/Truc.html">Truc <span class="class">(class)</span></a>
<a href="scala/collection/Truc.html">Truc <span class="class">(class)</span></a>
</li>
</ol>
</li>
<li>
<h3>scala.collection.immutable</h3>
<h3><a class="tplshow">scala.collection.immutable</a></h3>
<ol class="templates">
<li class="template" title="scala.collection.DefaultMap">
<a class="tplshow" href="scala/collection/DefaultMap$.html">DefaultMap <span class="class">(object)</span></a>
<a href="scala/collection/DefaultMap$.html">DefaultMap <span class="class">(object)</span></a>
</li>
<li class="template" title="scala.collection.Iterable">
<a class="tplshow" href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a class="tplshow" href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
<a href="scala/collection/Iterable.html">Iterable <span class="class">(class)</span></a>
<a href="scala/collection/Iterable$.html"><span class="object">(object)</span></a>
</li>
</ol>
</li>
Expand Down
Loading

0 comments on commit 6995333

Please sign in to comment.