summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormichelou <michelou@epfl.ch>2006-11-10 18:37:06 +0000
committermichelou <michelou@epfl.ch>2006-11-10 18:37:06 +0000
commit46ff81bfd585e675c1409132b3d4637736ae0c9f (patch)
tree1713c0e204f9d24b7999e8f95b4ba4623cb64512
parent12014a82a3097a3cdb48f089a16aa5f44df8d6d6 (diff)
downloadscala-46ff81bfd585e675c1409132b3d4637736ae0c9f.tar.gz
scala-46ff81bfd585e675c1409132b3d4637736ae0c9f.tar.bz2
scala-46ff81bfd585e675c1409132b3d4637736ae0c9f.zip
added list of inherited members in DocGenerator
improved quality of generated HTML code
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocGenerator.scala248
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocUtil.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/script.js4
-rw-r--r--src/compiler/scala/tools/nsc/doc/style.css56
4 files changed, 195 insertions, 119 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
index 3899c8dc6d..b18a8e5c1b 100644
--- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
@@ -11,8 +11,8 @@ import java.util.StringTokenizer
import java.util.regex.Pattern
import compat.Platform.{EOL => LINE_SEPARATOR}
-import scala.collection.immutable._
-import scala.collection.mutable.ListBuffer
+import scala.collection.immutable.{ListMap, TreeMap, TreeSet}
+import scala.collection.mutable.{HashMap, ListBuffer, Map}
import scala.tools.nsc.models.Models
import scala.tools.nsc.symtab.Flags
import scala.xml._
@@ -190,7 +190,7 @@ abstract class DocGenerator extends Models {
val path = "root-content"
val title = "All Packages"
def modules: TreeMap[String, ModuleClassSymbol]
- def body: NodeSeq = {
+ def body: NodeSeq =
<div class="page-title">
Scala 2
<br/>API Specification
@@ -210,7 +210,6 @@ abstract class DocGenerator extends Models {
</td></tr>;
} }
</table>;
- }
}
abstract class ListClassFrame extends Frame {
@@ -234,7 +233,9 @@ abstract class DocGenerator extends Models {
</table>;
val body = <div>{ { for (val kind <- KINDS; classes contains kind) yield {
- <p><b>{Text(pluralFor(kind))}</b></p>
+ <p>
+ <b>{Text(pluralFor(kind))}</b>
+ </p>
<table class="list" summary="">
<tr><td style="white-space;nowrap;">
{ {
@@ -253,14 +254,18 @@ abstract class DocGenerator extends Models {
private def extendsFor(mmbr: HasTree): NodeSeq = mmbr match {
case mmbr: ImplMod =>
- if (!mmbr.treey.impl.parents.isEmpty)
- <span><dd><code>{Text(" extends ")}</code>
- {forType(mmbr.treey.impl.parents.head.tpe)}</dd>
- { { for (val parent <- mmbr.treey.impl.parents.tail)
- yield <dd><code>{Text(" with ")}</code>
- {forType(parent.tpe)}</dd>;
- } } </span>;
- else NodeSeq.Empty
+ val parents = mmbr.treey.impl.parents
+ if (parents.isEmpty) NodeSeq.Empty
+ else
+ <dd>
+ <code>{Text(" extends ")}</code>{forType(parents.head.tpe)}
+ </dd>.concat(
+ { {
+ for (val parent <- parents.tail) yield
+ <dd>
+ <code>{Text(" with ")}</code>{forType(parent.tpe)}
+ </dd>
+ } })
case _ =>
NodeSeq.Empty
}
@@ -300,23 +305,27 @@ abstract class DocGenerator extends Models {
* @param mmbr ...
* @return ...
*/
- def fullHeader(mmbr: HasTree): NodeSeq = <span>{ {
- if (!mmbr.isInstanceOf[ImplMod])
- <a name = {Utility.escape(mmbr.tree.symbol.nameString)}></a>;
- else NodeSeq.Empty
- } }<dl><dt>
- { attrsFor(mmbr.tree) }
- <code>
- { { for (val str <- stringsFor(mmbr.mods)) yield Text(str + " ") } }
- { Text(codeFor(mmbr.kind)) }
- </code>
- <em>{ Text(nameFor(mmbr.tree)) }</em>
- { typesFor(mmbr) }{ argsFor(mmbr)}{resultFor(mmbr) }
- </dt> { extendsFor(mmbr) }
- </dl>
- { fullComment(mmbr) }
- { listSubclasses(mmbr) } <hr/>
- { lists(mmbr) } </span>;
+ def fullHeader(mmbr: HasTree): NodeSeq = Group(
+ { {
+ if (mmbr.isInstanceOf[ImplMod]) NodeSeq.Empty
+ else <a name = {Utility.escape(mmbr.tree.symbol.nameString)}></a>
+ } }.concat(
+ <dl>
+ <dt>
+ { attrsFor(mmbr.tree) }
+ <code>
+ { { for (val str <- stringsFor(mmbr.mods)) yield Text(str + " ") } }
+ { Text(codeFor(mmbr.kind)) }
+ </code>
+ <em>{ Text(nameFor(mmbr.tree)) }</em>
+ { typesFor(mmbr) }{ argsFor(mmbr)}{resultFor(mmbr) }
+ </dt>
+ <dd>{ extendsFor(mmbr) }</dd>
+ </dl>)
+ .concat(fullComment(mmbr))
+ .concat(hr(listSubclasses(mmbr)))
+ .concat(lists(mmbr)))
+// { lists(mmbr) }
/** Return a NodeSeq with the known subclasses for <code>mmbr</code>, if any.
*
@@ -334,17 +343,22 @@ abstract class DocGenerator extends Models {
</dt>
<dd>{ {
val links =
- for (val subc <- subcs) yield
- aref(urlFor(subc), contentFrame, subc.nameString)
+ for (val subc <- subcs)
+ yield aref(urlFor(subc), contentFrame, subc.nameString)
links.reduceRight { (link: Seq[Node], seq: Seq[Node]) => link.concat(Text(", ")).concat(seq) }
} }</dd>
</dl>;
}
- def lists(mmbr: HasTree) = mmbr match {
- case cmod: ImplMod => <span>{ listMembersShort(mmbr) }
- { listMembersFull (mmbr) }</span>
- case _ => NodeSeq.Empty
+ def lists(mmbr: HasTree): NodeSeq = mmbr match {
+ case cmod: ImplMod =>
+ <span>
+ { listMembersShort(mmbr) }
+ { listInheritedMembers(mmbr) }
+ { listMembersFull(mmbr) }
+ </span>
+ case _ =>
+ NodeSeq.Empty
}
/**
@@ -354,47 +368,96 @@ abstract class DocGenerator extends Models {
def listMembersShort(mmbr: HasTree): NodeSeq =
if (mmbr.isInstanceOf[Composite]) {
val map = organize(mmbr.asInstanceOf[Composite], emptyMap)
- <span> { {
- for (val kind <- KINDS; map contains kind) yield {
- val x = <table cellpadding="3" class="member" summary="">
- <tr><td colspan="2" class="title">{Text(labelFor(kind))} Summary</td></tr>
- { {
+ for (val kind <- KINDS; map contains kind) yield Group(br(
+ <table cellpadding="3" class="member" summary="">
+ <tr>
+ <td colspan="2" class="title">{Text(labelFor(kind))} Summary</td>
+ </tr>
+ { {
for (val mmbr <- map(kind).toList) yield
shortHeader(mmbr)
- } }
- </table>;
- br(x);
- }
- } } </span>
+ } }
+ </table>))
+ } else
+ NodeSeq.Empty
+
+ /**
+ * @param mmbr ...
+ * @return a sequence of HTML tables containing inherited members
+ */
+ def listInheritedMembers(mmbr: HasTree): NodeSeq =
+ if (mmbr.isInstanceOf[Composite]) {
+ val sym = mmbr.tree.symbol
+ val ignored = List(definitions.ObjectClass, definitions.ScalaObjectClass)
+ val parents = sym.info.parents
+ for (val p <- parents; !ignored.contains(p.symbol)) yield Group(br(
+ <table cellpadding="3" class="inherited" summary="">
+ <tr>
+ <td colspan="2" class="title">
+ {Text("Methods inherited from ").concat(urlFor(p, contentFrame))}
+ </td>
+ </tr>
+ <tr>
+ { {
+ if (p.decls.isEmpty) NodeSeq.Empty // scope empty
+ else {
+ def aref1(sym: Symbol): NodeSeq = {
+ val ns = sym.nameString
+ val isJava = sym hasFlag Flags.JAVA
+ if (isJava || sym.sourceFile == null) {
+ val name =
+ if (isJava && ns.equals("this")) sym.owner.nameString
+ else ns
+ val args =
+ if (isJava) "()" // todo: arguments
+ else ""
+ <a class={sym.owner.fullNameString.replace('.', '_')}
+ href={"#" + name + args}
+ target={contentFrame}>{name}</a>
+ }
+ else
+ aref(urlFor(sym), contentFrame, sym.nameString)
+ }
+ val members = p.decls.toList.sort(
+ (x, y) => (x.nameString compareTo y.nameString) < 0)
+ <td colspan="2" class="signature">
+ {aref1(members.head)}
+ {for (val m <- members.tail) yield Text(", ").concat(aref1(m))}
+ </td>
+ }
+ } }
+ </tr>
+ </table>))
} else
NodeSeq.Empty
+ /**
+ * @param mmbr ...
+ * @return ...
+ */
def listMembersFull(mmbr: HasTree): NodeSeq =
if (mmbr.isInstanceOf[Composite]) {
val map = organize(mmbr.asInstanceOf[Composite], emptyMap)
val mmbrx = mmbr
val pathx = path
- for (val kind0 <- OBJECT :: CLASS :: Nil; map contains kind0) for (val mmbr <- map(kind0)) {
- new ContentFrame {
- def clazz = mmbr.asInstanceOf[ImplMod];
- def kind = kind0;
- def title =
- labelFor(kind0) + " " + mmbr.tree.symbol.nameString + " in " +
- codeFor(mmbrx.kind) + " " + mmbr.tree.symbol.owner.fullNameString('.')
- }
- }
- <span> { {
- for (val kind <- KINDS; map.contains(kind) && kind != OBJECT && kind != CLASS) yield {
- val header =
- <table cellpadding="3" class="member-detail" summary="">
- <tr><td class="member-title">
- {Text(labelFor(kind))} Detail
- </td></tr>
- </table>
- val body = for (val mmbr <- map(kind).toList) yield <span>{fullHeader(mmbr)}</span>;
- header.concat(body)
- }
- } } </span>
+ for (val kind0 <- List(OBJECT, CLASS); map contains kind0)
+ for (val mmbr <- map(kind0))
+ new ContentFrame {
+ def clazz = mmbr.asInstanceOf[ImplMod]
+ def kind = kind0
+ def title =
+ labelFor(kind0) + " " + mmbr.tree.symbol.nameString + " in " +
+ codeFor(mmbrx.kind) + " " + mmbr.tree.symbol.owner.fullNameString('.')
+ }
+ for (val kind <- List(TRAIT, CONSTRUCTOR, VAL, VAR, DEF); map contains kind) yield Group(
+ <table cellpadding="3" class="member-detail" summary="">
+ <tr>
+ <td class="title">{Text(labelFor(kind))} Detail</td>
+ </tr>
+ </table>
+ <div>
+ {for (val mmbr <- map(kind).toList) yield fullHeader(mmbr)}
+ </div>)
} else
NodeSeq.Empty
@@ -402,7 +465,7 @@ abstract class DocGenerator extends Models {
* @param mmbr ...
* @return ...
*/
- def shortHeader(mmbr: HasTree): NodeSeq = {
+ def shortHeader(mmbr: HasTree): NodeSeq =
<tr>
<td valign="top" class="modifiers">
{ { for (val str <- stringsFor(mmbr.mods)) yield <code>{(Text(str + " "))}</code>; } }
@@ -416,7 +479,6 @@ abstract class DocGenerator extends Models {
<br>{shortComment(mmbr)}</br>
</td>
</tr>
- }
def fullComment(mmbr: HasTree): NodeSeq =
comments.get(mmbr.tree.symbol) match {
@@ -454,10 +516,9 @@ abstract class DocGenerator extends Models {
case sel: Select =>
forTree(sel.qualifier).concat(Text(sel.symbol.nameString))
case tree: AbsTypeDef =>
- (Text(tree.symbol.nameString)
- .concat(ifT(tree.hi, Text(" <: "), true))
- .concat(ifT(tree.lo, Text(" >: "), true)))
-
+ Text(tree.symbol.nameString)
+ .concat(ifT(tree.hi, Text(" <: "), true))
+ .concat(ifT(tree.lo, Text(" >: "), true))
case tpt: TypeTree =>
urlFor(tpt.tpe, contentFrame)
case id: Ident =>
@@ -535,26 +596,24 @@ abstract class DocGenerator extends Models {
def path = module.fullNameString('/') + "$content"
def title = "All Classes and Objects in " + module.fullNameString('.')
- def body: NodeSeq = {
- <span><div class="page-title">
- Scala 2
- <br/>API Specification
- </div>
+ def body: NodeSeq =
+ <div class="page-title">
+ Scala 2<br/>API Specification
+ </div>
+ <p>
This document is the API specification for Scala 2.
- <p/>
- { {
- for (val kind <- KINDS; classes contains kind) yield {
- <span><hr/><table cellpadding="3" class="member" summary="">
- <tr><td colspan="2" class="title">
+ </p>.concat(
+ for (val kind <- KINDS; classes contains kind) yield Group(hr(
+ <table cellpadding="3" class="member" summary="">
+ <tr>
+ <td colspan="2" class="title">
{labelFor(kind)} Summary
- </td></tr>{ {
+ </td>
+ </tr>
+ { {
for (val mmbr <- classes(kind).toList) yield shortHeader(mmbr)
- } }
- </table></span>
- }
- } }
- </span>;
- }
+ } }
+ </table>)))
}
abstract class ContentFrame extends ContentFrame0 {
@@ -595,6 +654,13 @@ abstract class DocGenerator extends Models {
"Constructor" -> ((s: Symbol) => s.isConstructor) +
"Def" -> ((s: Symbol) => s.isMethod)
+ /** This abstract class contains two abstract methods <code>sym</code> and
+ * <code>descr</code> which must be defined for each primitive type in
+ * order to generated the appropriate HTML documentation page.
+ *
+ * @author Stephane Micheloud
+ * @version 1.0
+ */
private abstract class PrimitiveContentFrame extends ContentFrame0 {
def sym: Symbol
def descr: String
@@ -678,8 +744,6 @@ abstract class DocGenerator extends Models {
private val loader = getClass().getClassLoader()
- import scala.collection.mutable.{Map, HashMap}
-
/** Map a class to it's known subclasses */
private val subclasses = new HashMap[Symbol, List[Symbol]] {
override def default(key: Symbol): List[Symbol] = {
diff --git a/src/compiler/scala/tools/nsc/doc/DocUtil.scala b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
index b78f2a0f8b..a2ec4c274b 100644
--- a/src/compiler/scala/tools/nsc/doc/DocUtil.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocUtil.scala
@@ -31,10 +31,8 @@ object DocUtil {
// def label = "#PCDATA"
//}
- def br(nodes: NodeSeq): NodeSeq = {
- val x = <br/>;
- nodes.concat(x)
- }
+ def br(nodes: NodeSeq): NodeSeq = nodes.concat(<br/>)
+ def hr(nodes: NodeSeq): NodeSeq = nodes.concat(<hr/>)
trait UrlContext {
def relative: String
diff --git a/src/compiler/scala/tools/nsc/doc/script.js b/src/compiler/scala/tools/nsc/doc/script.js
index 59bdde90ec..33278f2338 100644
--- a/src/compiler/scala/tools/nsc/doc/script.js
+++ b/src/compiler/scala/tools/nsc/doc/script.js
@@ -236,9 +236,11 @@ function init() {
for (i = 0; i < elems.length; i++) {
try {
key = elems[i].getAttribute('class');
+ href = elems[i].getAttribute('href');
api_root = table[key];
if (api_root != null) {
- value = api_root + key.replace(/_/g, "/") + ".html";
+ href1 = href.substring(href.lastIndexOf("#"))
+ value = api_root + key.replace(/_/g, "/") + ".html" + href1;
elems[i].setAttribute('href', value);
}
}
diff --git a/src/compiler/scala/tools/nsc/doc/style.css b/src/compiler/scala/tools/nsc/doc/style.css
index 5fecb9014e..890a4369ea 100644
--- a/src/compiler/scala/tools/nsc/doc/style.css
+++ b/src/compiler/scala/tools/nsc/doc/style.css
@@ -46,23 +46,47 @@ span.entity {
table.member {
border-collapse: collapse;
- border: 2px solid #888888;
- background-color: #ffffff;
- width: 100%;
+ border: 2px inset #888888;
+ width: 100%;
+}
+
+table.member td.title {
+ border: 2px inset #888888;
+ background-color: #ccccff;
+ font-size: x-large;
+ font-weight: bold;
+}
+
+table.inherited {
+ border-collapse: collapse;
+ border: 2px inset #888888;
+ width: 100%;
+}
+
+table.inherited td.title {
+ background-color: #eeeeff;
+ font-weight: bold;
}
table.member-detail {
margin: 10px 0px 0px 0px;
border-collapse: collapse;
- border: 2px solid #888888;
+ border: 2px inset #888888;
background-color: #ffffff;
- width: 100%;
+ width: 100%;
+}
+
+table.member-detail td.title {
+ border: 2px inset #888888;
+ background-color: #ccccff;
+ font-size: x-large;
+ font-weight: bold;
}
table.navigation {
border-collapse: collapse;
width: 100%;
- font-family: Arial,Helvetica,Sans-serif;
+ font-family: Arial,Helvetica,Sans-Serif;
}
table.list {
@@ -72,7 +96,7 @@ table.list {
}
td.inherited-members {
- border-top: 2px solid #888888;
+ border-top: 2px inset #888888;
border-right: 0px;
}
@@ -81,16 +105,9 @@ td.inherited-owner {
font-weight: bold;
}
-td.member-title {
- border: 2px solid #888888;
- background-color: #ccccff;
- font-size: x-large;
- font-weight: bold;
-}
-
td.modifiers {
- border-top: 2px solid #888888;
- border-right: 2px solid #888888;
+ border-top: 2px inset #888888;
+ border-right: 2px inset #888888;
width: 50px;
text-align: right;
}
@@ -113,12 +130,7 @@ td.navigation-selected {
}
td.signature {
- border-top: 2px solid #888888;
+ border-top: 2px inset #888888;
width: 90%;
}
-td.title {
- background-color: #ccccff;
- font-size: x-large;
- font-weight: bold;
-}