summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/doc/html
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/doc/html')
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala16
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/Page.scala14
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Index.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala91
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala58
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css6
7 files changed, 156 insertions, 33 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index e3da8bddea..34e2f7bc53 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -116,11 +116,25 @@ abstract class HtmlPage extends Page { thisPage =>
case Superscript(in) => <sup>{ inlineToHtml(in) }</sup>
case Subscript(in) => <sub>{ inlineToHtml(in) }</sub>
case Link(raw, title) => <a href={ raw }>{ inlineToHtml(title) }</a>
- case EntityLink(entity) => templateToHtml(entity)
case Monospace(in) => <code>{ inlineToHtml(in) }</code>
case Text(text) => xml.Text(text)
case Summary(in) => inlineToHtml(in)
case HtmlTag(tag) => xml.Unparsed(tag)
+ case EntityLink(target, template) => template() match {
+ case Some(tpl) =>
+ templateToHtml(tpl)
+ case None =>
+ xml.Text(target)
+ }
+ }
+
+ def typeToHtml(tpes: List[model.TypeEntity], hasLinks: Boolean): NodeSeq = tpes match {
+ case Nil =>
+ sys.error("Internal Scaladoc error")
+ case List(tpe) =>
+ typeToHtml(tpe, hasLinks)
+ case tpe :: rest =>
+ typeToHtml(tpe, hasLinks) ++ scala.xml.Text(" with ") ++ typeToHtml(rest, hasLinks)
}
def typeToHtml(tpe: model.TypeEntity, hasLinks: Boolean): NodeSeq = {
diff --git a/src/compiler/scala/tools/nsc/doc/html/Page.scala b/src/compiler/scala/tools/nsc/doc/html/Page.scala
index c5bf3e0e37..59f4c81632 100644
--- a/src/compiler/scala/tools/nsc/doc/html/Page.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/Page.scala
@@ -83,18 +83,4 @@ abstract class Page {
}
relativize(thisPage.path.reverse, destPath.reverse).mkString("/")
}
-
- def isExcluded(dtpl: DocTemplateEntity) = {
- val qname = dtpl.qualifiedName
- ( ( qname.startsWith("scala.Tuple") || qname.startsWith("scala.Product") ||
- qname.startsWith("scala.Function") || qname.startsWith("scala.runtime.AbstractFunction")
- ) && !(
- qname == "scala.Tuple1" || qname == "scala.Tuple2" ||
- qname == "scala.Product" || qname == "scala.Product1" || qname == "scala.Product2" ||
- qname == "scala.Function" || qname == "scala.Function1" || qname == "scala.Function2" ||
- qname == "scala.runtime.AbstractFunction0" || qname == "scala.runtime.AbstractFunction1" ||
- qname == "scala.runtime.AbstractFunction2"
- )
- )
- }
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
index 8ed13e0da2..0e894a03bf 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
@@ -61,7 +61,7 @@ class Index(universe: doc.Universe, index: doc.Index) extends HtmlPage {
}
<ol class="templates">{
val tpls: Map[String, Seq[DocTemplateEntity]] =
- (pack.templates filter (t => !t.isPackage && !isExcluded(t) )) groupBy (_.name)
+ (pack.templates filter (t => !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) )) groupBy (_.name)
val placeholderSeq: NodeSeq = <div class="placeholder"></div>
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala
index 7edd4937c4..1b0599d145 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala
@@ -68,7 +68,7 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page {
def allPackagesWithTemplates = {
Map(allPackages.map((key) => {
- key -> key.templates.filter(t => !t.isPackage && !isExcluded(t))
+ key -> key.templates.filter(t => !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName))
}) : _*)
}
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index 66189a6854..ce0e6b7856 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -8,10 +8,11 @@ package doc
package html
package page
-import model._
import scala.xml.{ NodeSeq, Text, UnprefixedAttribute }
import language.postfixOps
+import model._
+
class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage {
val path =
@@ -41,9 +42,12 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
val (absValueMembers, nonAbsValueMembers) =
valueMembers partition (_.isAbstract)
- val (deprValueMembers, concValueMembers) =
+ val (deprValueMembers, nonDeprValueMembers) =
nonAbsValueMembers partition (_.deprecation.isDefined)
+ val (concValueMembers, shadowedImplicitMembers) =
+ nonDeprValueMembers partition (!Template.isShadowedOrAmbiguousImplicit(_))
+
val typeMembers =
tpl.abstractTypes ++ tpl.aliasTypes ++ tpl.templates.filter(x => x.isTrait || x.isClass) sorted
@@ -163,6 +167,13 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</div>
}
+ { if (shadowedImplicitMembers.isEmpty) NodeSeq.Empty else
+ <div id="values" class="values members">
+ <h3>Shadowed Implict Value Members</h3>
+ <ol>{ shadowedImplicitMembers map (memberToHtml(_)) }</ol>
+ </div>
+ }
+
{ if (deprValueMembers.isEmpty) NodeSeq.Empty else
<div id="values" class="values members">
<h3>Deprecated Value Members</h3>
@@ -243,11 +254,13 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
case _ => ""
}
val memberComment = memberToCommentHtml(mbr, 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}/>
- { signature(mbr, false) }
- { memberComment }
+ <li name={ mbr.definitionName }
+ visbl={ if (mbr.visibility.isProtected) "prt" else "pub" }
+ data-isabs={ mbr.isAbstract.toString }
+ fullComment={ if(memberComment.filter(_.label=="div").isEmpty) "no" else "yes" }>
+ <a id={ mbr.name +defParamsString +":"+ mbr.resultType.name}/>
+ { signature(mbr, false) }
+ { memberComment }
</li>
}
@@ -299,6 +312,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
<p class="comment cmt">{ inlineToHtml(mbr.comment.get.short) }</p>
def memberToCommentBodyHtml(mbr: MemberEntity, isSelf: Boolean, isReduced: Boolean = false): NodeSeq = {
+ val s = universe.settings
val memberComment =
if (mbr.comment.isEmpty) NodeSeq.Empty
@@ -354,7 +368,8 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
val implicitInformation = mbr.byConversion match {
- case Some(conv) =>
+ case Some(info) =>
+ val conv = info.conversion
<dt class="implicit">Implicit information</dt> ++
{
val targetType = typeToHtml(conv.targetType, true)
@@ -387,6 +402,35 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
{ targetType } performed by method { conversionMethod } in { conversionOwner }.
{ constraintText }
</dd>
+ } ++ {
+ if (Template.isShadowedOrAmbiguousImplicit(mbr)) {
+ // These are the members that are shadowing or ambiguating the current implicit
+ // see ImplicitMemberShadowing trait for more information
+ val shadowingSuggestion = {
+ val params = mbr match {
+ case d: Def => d.valueParams map (_ map (_ name) mkString("(", ", ", ")")) mkString
+ case _ => "" // no parameters
+ }
+ <br/> ++ xml.Text("To access this member you can use a ") ++
+ <a href="http://stackoverflow.com/questions/2087250/what-is-the-purpose-of-type-ascription-in-scala"
+ target="_blank">type ascription</a> ++ xml.Text(":") ++
+ <br/> ++ <div class="cmt"><pre>{"(" + Template.lowerFirstLetter(tpl.name) + ": " + conv.targetType.name + ")." + mbr.name + params }</pre></div>
+ }
+
+ val shadowingWarning: NodeSeq =
+ if (Template.isShadowedImplicit(mbr))
+ xml.Text("This implicitly inherited member is shadowed by one or more members in this " +
+ "class.") ++ shadowingSuggestion
+ else if (Template.isAmbiguousImplicit(mbr))
+ xml.Text("This implicitly inherited member is ambiguous. One or more implicitly " +
+ "inherited members have similar signatures, so calling this member may produce an ambiguous " +
+ "implicit conversion compiler error.") ++ shadowingSuggestion
+ else NodeSeq.Empty
+
+ <dt class="implicit">Shadowing</dt> ++
+ <dd>{ shadowingWarning }</dd>
+
+ } else NodeSeq.Empty
}
case _ =>
NodeSeq.Empty
@@ -562,11 +606,11 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
val subclasses = mbr match {
- case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.subClasses.nonEmpty =>
+ case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.allSubClasses.nonEmpty =>
<div class="toggleContainer block">
<span class="toggle">Known Subclasses</span>
<div class="subClasses hiddenContent">{
- templatesToHtml(dtpl.subClasses.sortBy(_.name), xml.Text(", "))
+ templatesToHtml(dtpl.allSubClasses.sortBy(_.name), xml.Text(", "))
}</div>
</div>
case _ => NodeSeq.Empty
@@ -605,13 +649,13 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
case PrivateInTemplate(owner) if (owner == mbr.inTemplate) =>
Some(Paragraph(CText("private")))
case PrivateInTemplate(owner) =>
- Some(Paragraph(Chain(List(CText("private["), EntityLink(owner), CText("]")))))
+ Some(Paragraph(Chain(List(CText("private["), EntityLink(owner.qualifiedName, () => Some(owner)), CText("]")))))
case ProtectedInInstance() =>
Some(Paragraph(CText("protected[this]")))
case ProtectedInTemplate(owner) if (owner == mbr.inTemplate) =>
Some(Paragraph(CText("protected")))
case ProtectedInTemplate(owner) =>
- Some(Paragraph(Chain(List(CText("protected["), EntityLink(owner), CText("]")))))
+ Some(Paragraph(Chain(List(CText("protected["), EntityLink(owner.qualifiedName, () => Some(owner)), CText("]")))))
case Public() =>
None
}
@@ -627,7 +671,15 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</span>
<span class="symbol">
{
- val nameClass = if (mbr.byConversion.isDefined) "implicit" else "name"
+ val nameClass =
+ if (Template.isImplicit(mbr))
+ if (Template.isShadowedOrAmbiguousImplicit(mbr))
+ "implicit shadowed"
+ else
+ "implicit"
+ else
+ "name"
+
val nameHtml = {
val value = if (mbr.isConstructor) tpl.name else mbr.name
val span = if (mbr.deprecation.isDefined)
@@ -699,8 +751,8 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
}{ if (isReduced) NodeSeq.Empty else {
mbr match {
- case tpl: DocTemplateEntity if tpl.parentType.isDefined =>
- <span class="result"> extends { typeToHtml(tpl.parentType.get, hasLinks) }</span>
+ case tpl: DocTemplateEntity if !tpl.parentTypes.isEmpty =>
+ <span class="result"> extends { typeToHtml(tpl.parentTypes.map(_._2), hasLinks) }</span>
case tme: MemberEntity if (tme.isDef || tme.isVal || tme.isLazyVal || tme.isVar) =>
<span class="result">: { typeToHtml(tme.resultType, hasLinks) }</span>
@@ -870,5 +922,14 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
xml.Text(ub.typeParamName + " is a subclass of " + ub.upperBound.name + " (" + ub.typeParamName + " <: ") ++
typeToHtml(ub.upperBound, true) ++ xml.Text(")")
}
+}
+
+object Template {
+
+ def isImplicit(mbr: MemberEntity) = mbr.byConversion.isDefined
+ def isShadowedImplicit(mbr: MemberEntity) = mbr.byConversion.isDefined && mbr.byConversion.get.isShadowed
+ def isAmbiguousImplicit(mbr: MemberEntity) = mbr.byConversion.isDefined && mbr.byConversion.get.isAmbiguous
+ def isShadowedOrAmbiguousImplicit(mbr: MemberEntity) = isShadowedImplicit(mbr) || isAmbiguousImplicit(mbr)
+ def lowerFirstLetter(s: String) = if (s.length >= 1) s.substring(0,1).toLowerCase() + s.substring(1) else s
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala
new file mode 100644
index 0000000000..16d859894f
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala
@@ -0,0 +1,58 @@
+/**
+ * @author Vlad Ureche
+ */
+package scala.tools.nsc.doc
+package html.page.diagram
+
+object DiagramStats {
+
+ class TimeTracker(title: String) {
+ var totalTime: Long = 0l
+ var maxTime: Long = 0l
+ var instances: Int = 0
+
+ def addTime(ms: Long) = {
+ if (maxTime < ms)
+ maxTime = ms
+ totalTime += ms
+ instances += 1
+ }
+
+ def printStats(print: String => Unit) = {
+ if (instances == 0)
+ print(title + ": no stats gathered")
+ else {
+ print(" " + title)
+ print(" " + "=" * title.length)
+ print(" count: " + instances + " items")
+ print(" total time: " + totalTime + " ms")
+ print(" average time: " + (totalTime/instances) + " ms")
+ print(" maximum time: " + maxTime + " ms")
+ print("")
+ }
+ }
+ }
+
+ private[this] val filterTrack = new TimeTracker("diagrams model filtering")
+ private[this] val modelTrack = new TimeTracker("diagrams model generation")
+ private[this] val dotGenTrack = new TimeTracker("dot diagram generation")
+ private[this] val dotRunTrack = new TimeTracker("dot process runnning")
+ private[this] val svgTrack = new TimeTracker("svg processing")
+
+ def printStats(settings: Settings) = {
+ if (settings.docDiagramsDebug.value) {
+ settings.printMsg("\nDiagram generation running time breakdown:\n")
+ filterTrack.printStats(settings.printMsg)
+ modelTrack.printStats(settings.printMsg)
+ dotGenTrack.printStats(settings.printMsg)
+ dotRunTrack.printStats(settings.printMsg)
+ svgTrack.printStats(settings.printMsg)
+ }
+ }
+
+ def addFilterTime(ms: Long) = filterTrack.addTime(ms)
+ def addModelTime(ms: Long) = modelTrack.addTime(ms)
+ def addDotGenerationTime(ms: Long) = dotGenTrack.addTime(ms)
+ def addDotRunningTime(ms: Long) = dotRunTrack.addTime(ms)
+ def addSvgTime(ms: Long) = svgTrack.addTime(ms)
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
index 5a1779bba5..b25f0d0b3f 100644
--- a/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
+++ b/src/compiler/scala/tools/nsc/doc/html/resource/lib/template.css
@@ -333,6 +333,10 @@ div.members > ol > li:last-child {
color: darkgreen;
}
+.signature .symbol .shadowed {
+ color: darkseagreen;
+}
+
.signature .symbol .params > .implicit {
font-style: italic;
}
@@ -802,4 +806,4 @@ div.fullcomment dl.paramcmts > dd {
#mbrsel .showall span {
color: #4C4C4C;
font-weight: bold;
-}*/ \ No newline at end of file
+}*/