summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ScalaDoc.scala3
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/Settings.scala58
-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
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala96
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala109
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala134
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Body.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala6
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala140
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala143
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala248
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala197
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala4
-rw-r--r--test/scaladoc/resources/implicits-ambiguating-res.scala72
-rw-r--r--test/scaladoc/resources/implicits-base-res.scala16
-rw-r--r--test/scaladoc/resources/implicits-elimination-res.scala6
-rw-r--r--test/scaladoc/run/diagrams-base.scala73
-rw-r--r--test/scaladoc/run/diagrams-determinism.check1
-rw-r--r--test/scaladoc/run/diagrams-determinism.scala67
-rw-r--r--test/scaladoc/run/diagrams-filtering.check1
-rw-r--r--test/scaladoc/run/diagrams-filtering.scala93
-rw-r--r--test/scaladoc/run/implicits-ambiguating.check1
-rw-r--r--test/scaladoc/run/implicits-ambiguating.scala111
-rw-r--r--test/scaladoc/run/implicits-base.scala36
-rw-r--r--test/scaladoc/run/implicits-elimination.check (renamed from test/scaladoc/run/diagrams-base.check)0
-rw-r--r--test/scaladoc/run/implicits-elimination.scala23
-rw-r--r--test/scaladoc/run/implicits-shadowing.scala32
-rw-r--r--test/scaladoc/scalacheck/CommentFactoryTest.scala6
35 files changed, 224 insertions, 1649 deletions
diff --git a/src/compiler/scala/tools/nsc/ScalaDoc.scala b/src/compiler/scala/tools/nsc/ScalaDoc.scala
index c6fdb4b891..5a4b4172c6 100644
--- a/src/compiler/scala/tools/nsc/ScalaDoc.scala
+++ b/src/compiler/scala/tools/nsc/ScalaDoc.scala
@@ -20,8 +20,7 @@ class ScalaDoc {
def process(args: Array[String]): Boolean = {
var reporter: ConsoleReporter = null
- val docSettings = new doc.Settings(msg => reporter.error(FakePos("scaladoc"), msg + "\n scaladoc -help gives more information"),
- msg => reporter.printMessage(msg))
+ val docSettings = new doc.Settings(msg => reporter.error(FakePos("scaladoc"), msg + "\n scaladoc -help gives more information"))
reporter = new ConsoleReporter(docSettings) {
// need to do this so that the Global instance doesn't trash all the
// symbols just because there was an error
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index c6a9422974..e2e1ddf065 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -81,7 +81,6 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
new { override val global: compiler.type = compiler }
with model.ModelFactory(compiler, settings)
with model.ModelFactoryImplicitSupport
- with model.diagram.DiagramFactory
with model.comment.CommentFactory
with model.TreeFactory {
override def templateShouldDocument(sym: compiler.Symbol) =
@@ -91,12 +90,11 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
modelFactory.makeModel match {
case Some(madeModel) =>
- if (!settings.scaladocQuietRun)
+ if (settings.reportModel)
println("model contains " + modelFactory.templatesCount + " documentable templates")
Some(madeModel)
case None =>
- if (!settings.scaladocQuietRun)
- println("no documentable class found in compilation units")
+ println("no documentable class found in compilation units")
None
}
diff --git a/src/compiler/scala/tools/nsc/doc/Settings.scala b/src/compiler/scala/tools/nsc/doc/Settings.scala
index f8b2711c0c..4458889d55 100644
--- a/src/compiler/scala/tools/nsc/doc/Settings.scala
+++ b/src/compiler/scala/tools/nsc/doc/Settings.scala
@@ -11,9 +11,8 @@ import java.lang.System
import language.postfixOps
/** An extended version of compiler settings, with additional Scaladoc-specific options.
- * @param error A function that prints a string to the appropriate error stream
- * @param print A function that prints the string, without any extra boilerplate of error */
-class Settings(error: String => Unit, val printMsg: String => Unit = println(_)) extends scala.tools.nsc.Settings(error) {
+ * @param error A function that prints a string to the appropriate error stream. */
+class Settings(error: String => Unit) extends scala.tools.nsc.Settings(error) {
/** A setting that defines in which format the documentation is output. ''Note:'' this setting is currently always
* `html`. */
@@ -105,12 +104,6 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
"(for example conversions that require Numeric[String] to be in scope)"
)
- val docImplicitsSoundShadowing = BooleanSetting (
- "-implicits-sound-shadowing",
- "Use a sound implicit shadowing calculation. Note: this interacts badly with usecases, so " +
- "only use it if you haven't defined usecase for implicitly inherited members."
- )
-
val docDiagrams = BooleanSetting (
"-diagrams",
"Create inheritance diagrams for classes, traits and packages."
@@ -123,44 +116,10 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
val docDiagramsDotPath = PathSetting (
"-diagrams-dot-path",
- "The path to the dot executable used to generate the inheritance diagrams. Eg: /usr/bin/dot",
+ "The path to the dot executable used to generate the inheritance diagrams. Ex: /usr/bin/dot",
"dot" // by default, just pick up the system-wide dot
)
- /** The maxium nuber of normal classes to show in the diagram */
- val docDiagramsMaxNormalClasses = IntSetting(
- "-diagrams-max-classes",
- "The maximum number of superclasses or subclasses to show in a diagram",
- 15,
- None,
- _ => None
- )
-
- /** The maxium nuber of implcit classes to show in the diagram */
- val docDiagramsMaxImplicitClasses = IntSetting(
- "-diagrams-max-implicits",
- "The maximum number of implicitly converted classes to show in a diagram",
- 10,
- None,
- _ => None
- )
-
- val docDiagramsDotTimeout = IntSetting(
- "-diagrams-dot-timeout",
- "The timeout before the graphviz dot util is forecefully closed, in seconds (default: 10)",
- 10,
- None,
- _ => None
- )
-
- val docDiagramsDotRestart = IntSetting(
- "-diagrams-dot-restart",
- "The number of times to restart a malfunctioning dot process before disabling diagrams (default: 5)",
- 5,
- None,
- _ => None
- )
-
// Somewhere slightly before r18708 scaladoc stopped building unless the
// self-type check was suppressed. I hijacked the slotted-for-removal-anyway
// suppress-vt-warnings option and renamed it for this purpose.
@@ -170,16 +129,14 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
def scaladocSpecific = Set[Settings#Setting](
docformat, doctitle, docfooter, docversion, docUncompilable, docsourceurl, docgenerator, docRootContent, useStupidTypes,
docDiagrams, docDiagramsDebug, docDiagramsDotPath,
- docDiagramsDotTimeout, docDiagramsDotRestart,
- docImplicits, docImplicitsDebug, docImplicitsShowAll,
- docDiagramsMaxNormalClasses, docDiagramsMaxImplicitClasses
+ docImplicits, docImplicitsDebug, docImplicitsShowAll
)
val isScaladocSpecific: String => Boolean = scaladocSpecific map (_.name)
override def isScaladoc = true
- // set by the testsuite, when checking test output
- var scaladocQuietRun = false
+ // unset by the testsuite, we don't need to count the entities in the model
+ var reportModel = true
/**
* This is the hardcoded area of Scaladoc. This is where "undesirable" stuff gets eliminated. I know it's not pretty,
@@ -225,8 +182,7 @@ class Settings(error: String => Unit, val printMsg: String => Unit = println(_))
"scala.Predef.any2stringfmt",
"scala.Predef.any2stringadd",
"scala.Predef.any2ArrowAssoc",
- "scala.Predef.any2Ensuring",
- "scala.collection.TraversableOnce.alternateImplicit")
+ "scala.Predef.any2Ensuring")
/** There's a reason all these are specialized by hand but documenting each of them is beyond the point */
val arraySkipConversions = List(
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
index 34e2f7bc53..e3da8bddea 100644
--- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -116,25 +116,11 @@ 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 59f4c81632..c5bf3e0e37 100644
--- a/src/compiler/scala/tools/nsc/doc/html/Page.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/Page.scala
@@ -83,4 +83,18 @@ 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 0e894a03bf..8ed13e0da2 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 && !universe.settings.hardcoded.isExcluded(t.qualifiedName) )) groupBy (_.name)
+ (pack.templates filter (t => !t.isPackage && !isExcluded(t) )) 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 1b0599d145..7edd4937c4 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 && !universe.settings.hardcoded.isExcluded(t.qualifiedName))
+ key -> key.templates.filter(t => !t.isPackage && !isExcluded(t))
}) : _*)
}
}
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 ce0e6b7856..66189a6854 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -8,11 +8,10 @@ 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 =
@@ -42,12 +41,9 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
val (absValueMembers, nonAbsValueMembers) =
valueMembers partition (_.isAbstract)
- val (deprValueMembers, nonDeprValueMembers) =
+ val (deprValueMembers, concValueMembers) =
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
@@ -167,13 +163,6 @@ 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>
@@ -254,13 +243,11 @@ 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.filter(_.label=="div").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.isEmpty) "no" else "yes" }>
+ <a id={ mbr.name +defParamsString +":"+ mbr.resultType.name}/>
+ { signature(mbr, false) }
+ { memberComment }
</li>
}
@@ -312,7 +299,6 @@ 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
@@ -368,8 +354,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
val implicitInformation = mbr.byConversion match {
- case Some(info) =>
- val conv = info.conversion
+ case Some(conv) =>
<dt class="implicit">Implicit information</dt> ++
{
val targetType = typeToHtml(conv.targetType, true)
@@ -402,35 +387,6 @@ 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
@@ -606,11 +562,11 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
val subclasses = mbr match {
- case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.allSubClasses.nonEmpty =>
+ case dtpl: DocTemplateEntity if isSelf && !isReduced && dtpl.subClasses.nonEmpty =>
<div class="toggleContainer block">
<span class="toggle">Known Subclasses</span>
<div class="subClasses hiddenContent">{
- templatesToHtml(dtpl.allSubClasses.sortBy(_.name), xml.Text(", "))
+ templatesToHtml(dtpl.subClasses.sortBy(_.name), xml.Text(", "))
}</div>
</div>
case _ => NodeSeq.Empty
@@ -649,13 +605,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.qualifiedName, () => Some(owner)), CText("]")))))
+ Some(Paragraph(Chain(List(CText("private["), EntityLink(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.qualifiedName, () => Some(owner)), CText("]")))))
+ Some(Paragraph(Chain(List(CText("protected["), EntityLink(owner), CText("]")))))
case Public() =>
None
}
@@ -671,15 +627,7 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
</span>
<span class="symbol">
{
- val nameClass =
- if (Template.isImplicit(mbr))
- if (Template.isShadowedOrAmbiguousImplicit(mbr))
- "implicit shadowed"
- else
- "implicit"
- else
- "name"
-
+ val nameClass = if (mbr.byConversion.isDefined) "implicit" else "name"
val nameHtml = {
val value = if (mbr.isConstructor) tpl.name else mbr.name
val span = if (mbr.deprecation.isDefined)
@@ -751,8 +699,8 @@ class Template(universe: doc.Universe, tpl: DocTemplateEntity) extends HtmlPage
}
}{ if (isReduced) NodeSeq.Empty else {
mbr match {
- case tpl: DocTemplateEntity if !tpl.parentTypes.isEmpty =>
- <span class="result"> extends { typeToHtml(tpl.parentTypes.map(_._2), hasLinks) }</span>
+ case tpl: DocTemplateEntity if tpl.parentType.isDefined =>
+ <span class="result"> extends { typeToHtml(tpl.parentType.get, hasLinks) }</span>
case tme: MemberEntity if (tme.isDef || tme.isVal || tme.isLazyVal || tme.isVar) =>
<span class="result">: { typeToHtml(tme.resultType, hasLinks) }</span>
@@ -922,14 +870,5 @@ 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
deleted file mode 100644
index 16d859894f..0000000000
--- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DiagramStats.scala
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @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 b25f0d0b3f..5a1779bba5 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,10 +333,6 @@ div.members > ol > li:last-child {
color: darkgreen;
}
-.signature .symbol .shadowed {
- color: darkseagreen;
-}
-
.signature .symbol .params > .implicit {
font-style: italic;
}
@@ -806,4 +802,4 @@ div.fullcomment dl.paramcmts > dd {
#mbrsel .showall span {
color: #4C4C4C;
font-weight: bold;
-}*/
+}*/ \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index 5d1413abd4..6488847049 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -10,7 +10,7 @@ package model
import scala.collection._
import comment._
-import diagram._
+
/** An entity in a Scaladoc universe. Entities are declarations in the program and correspond to symbols in the
* compiler. Entities model the following Scala concepts:
@@ -86,20 +86,9 @@ trait TemplateEntity extends Entity {
/** Whether this template is a case class. */
def isCaseClass: Boolean
- /** The type of this entity, with type members */
- def ownType: TypeEntity
-
/** The self-type of this template, if it differs from the template type. */
def selfType : Option[TypeEntity]
- /** The full template name `[kind] qualifiedName` */
- def fullName =
- (if (isPackage) "package "
- else if (isCaseClass) "case class "
- else if (isClass) "class "
- else if (isTrait) "trait "
- else if (isObject) "object "
- else "") + qualifiedName
}
@@ -178,12 +167,8 @@ trait MemberEntity extends Entity {
/** Whether this member is abstract. */
def isAbstract: Boolean
- /** If this symbol is a use case, the useCaseOf will contain the member it was derived from, containing the full
- * signature and the complete parameter descriptions. */
- def useCaseOf: Option[MemberEntity] = None
-
/** If this member originates from an implicit conversion, we set the implicit information to the correct origin */
- def byConversion: Option[ImplicitConversionInfo]
+ def byConversion: Option[ImplicitConversion]
}
object MemberEntity {
// Oh contravariance, contravariance, wherefore art thou contravariance?
@@ -221,10 +206,8 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
* only if the `docsourceurl` setting has been set. */
def sourceUrl: Option[java.net.URL]
- /** The direct super-type of this template
- e.g: {{{class A extends B[C[Int]] with D[E]}}} will have two direct parents: class B and D
- NOTE: we are dropping the refinement here! */
- def parentTypes: List[(TemplateEntity, TypeEntity)]
+ /** 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)]
@@ -237,13 +220,9 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
* This template's linearization contains all of its direct and indirect super-types. */
def linearizationTypes: List[TypeEntity]
- /** All class, trait and object templates for which this template is a direct or indirect super-class or super-trait.
- * Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */
- def allSubClasses: List[DocTemplateEntity]
-
- /** All class, trait and object templates for which this template is a *direct* super-class or super-trait.
- * Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */
- def directSubClasses: List[DocTemplateEntity]
+ /**All class, trait and object templates for which this template is a direct or indirect super-class or super-trait.
+ * Only templates for which documentation is available in the universe (`DocTemplateEntity`) are listed. */
+ def subClasses: List[DocTemplateEntity]
/** All members of this template. If this template is a package, only templates for which documentation is available
* in the universe (`DocTemplateEntity`) are listed. */
@@ -271,19 +250,6 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
/** The implicit conversions this template (class or trait, objects and packages are not affected) */
def conversions: List[ImplicitConversion]
-
- /** Classes that can be implcitly converted to this class */
- def incomingImplicitlyConvertedClasses: List[DocTemplateEntity]
-
- /** Classes to which this class can be implicitly converted to
- NOTE: Some classes might not be included in the scaladoc run so they will be NoDocTemplateEntities */
- def outgoingImplicitlyConvertedClasses: List[(TemplateEntity, TypeEntity)]
-
- /** If this template takes place in inheritance and implicit conversion relations, it will be shown in this diagram */
- def inheritanceDiagram: Option[Diagram]
-
- /** If this template contains other templates, such as classes and traits, they will be shown in this diagram */
- def contentDiagram: Option[Diagram]
}
@@ -339,6 +305,10 @@ trait NonTemplateMemberEntity extends MemberEntity {
* It corresponds to a real member, and provides a simplified, yet compatible signature for that member. */
def isUseCase: Boolean
+ /** If this symbol is a use case, the useCaseOf will contain the member it was derived from, containing the full
+ * signature and the complete parameter descriptions. */
+ def useCaseOf: Option[MemberEntity]
+
/** Whether this member is a bridge member. A bridge member does only exist for binary compatibility reasons
* and should not appear in ScalaDoc. */
def isBridge: Boolean
@@ -457,15 +427,6 @@ trait ImplicitConversion {
/** The result type after the conversion */
def targetType: TypeEntity
- /** The result type after the conversion
- * Note: not all targetTypes have a corresponding template. Examples include conversions resulting in refinement
- * types. Need to check it's not option!
- */
- def targetTemplate: Option[TemplateEntity]
-
- /** The components of the implicit conversion type parents */
- def targetTypeComponents: List[(TemplateEntity, TypeEntity)]
-
/** The entity for the method that performed the conversion, if it's documented (or just its name, otherwise) */
def convertorMethod: Either[MemberEntity, String]
@@ -485,38 +446,11 @@ trait ImplicitConversion {
def members: List[MemberEntity]
}
-trait ImplicitConversionInfo {
- /** The implicit conversion this member originates from */
- def conversion: ImplicitConversion
-
- /** The shadowing information for this member */
- def shadowing: ImplicitMemberShadowing
-
- /* Quick getters */
- def isShadowed: Boolean = !shadowing.shadowingMembers.isEmpty
- def isAmbiguous: Boolean = !shadowing.ambiguatingMembers.isEmpty
-}
-
-/** Shadowing captures the information that the member is shadowed by some other members
- * There are two cases of implicitly added member shadowing:
- * 1) shadowing from a original class member (the class already has that member)
- * in this case, it won't be possible to call the member directly, the type checker will fail attempting to adapt
- * the call arguments (or if they fit it will call the original class' method)
- * 2) shadowing from other possible implicit conversions ()
- * this will result in an ambiguous implicit converion error
- */
-trait ImplicitMemberShadowing {
- /** The members that shadow the current entry use .inTemplate to get to the template name */
- def shadowingMembers: List[MemberEntity]
-
- /** The members that ambiguate this implicit conversion
- Note: for ambiguatingMembers you have the following invariant:
- assert(ambiguatingMembers.foreach(_.byConversion.isDefined) */
- def ambiguatingMembers: List[MemberEntity]
-}
-
/** A trait that encapsulates a constraint necessary for implicit conversion */
-trait Constraint
+trait Constraint {
+ // /** The implicit conversion during which this constraint appears */
+ // def conversion: ImplicitConversion
+}
/** A constraint involving a type parameter which must be in scope */
trait ImplicitInScopeConstraint extends Constraint {
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index eb916333ab..3dd77d47da 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -6,8 +6,6 @@ package model
import comment._
-import diagram._
-
import scala.collection._
import scala.util.matching.Regex
@@ -19,7 +17,7 @@ import model.{ RootPackage => RootPackageEntity }
/** This trait extracts all required information for documentation from compilation units */
class ModelFactory(val global: Global, val settings: doc.Settings) {
- thisFactory: ModelFactory with ModelFactoryImplicitSupport with DiagramFactory with CommentFactory with TreeFactory =>
+ thisFactory: ModelFactory with ModelFactoryImplicitSupport with CommentFactory with TreeFactory =>
import global._
import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass }
@@ -91,7 +89,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def isObject = sym.isModule && !sym.isPackage
def isCaseClass = sym.isCaseClass
def isRootPackage = false
- def ownType = makeType(sym.tpe, this)
def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this))
}
@@ -99,7 +96,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def isDocTemplate = false
}
- abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionInfoImpl = null, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
+ abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionImpl = null, inTpl: => DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
lazy val comment =
if (inTpl == null) None else thisFactory.comment(sym, inTpl)
override def inTemplate = inTpl
@@ -173,7 +170,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
case NullaryMethodType(res) => resultTpe(res)
case _ => tpe
}
- val tpe = if (implConv eq null) sym.tpe else implConv.conversion.toType memberInfo sym
+ val tpe = if (implConv eq null) sym.tpe else implConv.toType memberInfo sym
makeTypeInTemplateContext(resultTpe(tpe), inTemplate, sym)
}
def isDef = false
@@ -229,26 +226,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
else None
}
-
- def parentTemplates =
- if (sym.isPackage || sym == AnyClass)
- List()
- else
- sym.tpe.parents.flatMap { tpe: Type =>
- val tSym = tpe.typeSymbol
- if (tSym != NoSymbol)
- List(makeTemplate(tSym))
- else
- List()
- } filter (_.isInstanceOf[DocTemplateEntity])
-
- def parentTypes =
- if (sym.isPackage || sym == AnyClass) List() else {
+ def parentType = {
+ if (sym.isPackage || sym == AnyClass) None else {
val tps = sym.tpe.parents map { _.asSeenFrom(sym.thisType, sym) }
- makeParentTypes(RefinedType(tps, EmptyScope), inTpl)
+ Some(makeType(RefinedType(tps, EmptyScope), inTpl))
}
+ }
- protected def linearizationFromSymbol(symbol: Symbol): List[(TemplateEntity, TypeEntity)] = {
+ protected def linearizationFromSymbol(symbol: Symbol) = {
symbol.ancestors map { ancestor =>
val typeEntity = makeType(symbol.info.baseType(ancestor), this)
val tmplEntity = makeTemplate(ancestor) match {
@@ -263,7 +248,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def linearizationTemplates = linearization map { _._1 }
def linearizationTypes = linearization map { _._2 }
- /* Subclass cache */
private lazy val subClassesCache = (
if (noSubclassCache(sym)) null
else mutable.ListBuffer[DocTemplateEntity]()
@@ -272,47 +256,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
if (subClassesCache != null)
subClassesCache += sc
}
- def allSubClasses = if (subClassesCache == null) Nil else subClassesCache.toList
- def directSubClasses = allSubClasses.filter(_.parentTypes.map(_._1).contains(this))
-
- /* Implcitly convertible class cache */
- private var implicitlyConvertibleClassesCache: mutable.ListBuffer[DocTemplateEntity] = null
- def registerImplicitlyConvertibleClass(sc: DocTemplateEntity): Unit = {
- if (implicitlyConvertibleClassesCache == null)
- implicitlyConvertibleClassesCache = mutable.ListBuffer[DocTemplateEntity]()
- implicitlyConvertibleClassesCache += sc
- }
-
- def incomingImplicitlyConvertedClasses: List[DocTemplateEntity] =
- if (implicitlyConvertibleClassesCache == null)
- List()
- else
- implicitlyConvertibleClassesCache.toList
+ def subClasses = if (subClassesCache == null) Nil else subClassesCache.toList
val conversions = if (settings.docImplicits.value) makeImplicitConversions(sym, this) else Nil
- val outgoingImplicitlyConvertedClasses: List[(TemplateEntity, TypeEntity)] = conversions flatMap (conv =>
- if (!implicitExcluded(conv.conversionQualifiedName))
- conv.targetTypeComponents map {
- case pair@(template, tpe) =>
- template match {
- case d: DocTemplateImpl => d.registerImplicitlyConvertibleClass(this)
- case _ => // nothing
- }
- pair
- }
- else List()
- )
-
lazy val memberSyms =
// Only this class's constructors are part of its members, inherited constructors are not.
sym.info.members.filter(s => localShouldDocument(s) && (!s.isConstructor || s.owner == sym) && !isPureBridge(sym) )
- // in members, we also take in the members from implicit conversions
- lazy val ownMembers = (memberSyms.flatMap(makeMember(_, null, this)))
- lazy val allOwnMembers = (ownMembers ::: ownMembers.flatMap(_.useCaseOf.map(_.asInstanceOf[MemberImpl]))).distinct
-
- val members = ownMembers ::: (conversions.flatMap((_.members)))
+ val members = (memberSyms.flatMap(makeMember(_, null, this))) :::
+ (conversions.flatMap((_.members))) // also take in the members from implicit conversions
val templates = members collect { case c: DocTemplateEntity => c }
val methods = members collect { case d: Def => d }
@@ -327,10 +280,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
Some(makeDocTemplate(comSym, inTpl))
case _ => None
}
-
- // We make the diagram a lazy val, since we're not sure we'll include the diagrams in the page
- lazy val inheritanceDiagram = makeInheritanceDiagram(this)
- lazy val contentDiagram = makeContentDiagram(this)
}
abstract class PackageImpl(sym: Symbol, inTpl: => PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package {
@@ -347,18 +296,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
abstract class RootPackageImpl(sym: Symbol) extends PackageImpl(sym, null) with RootPackageEntity
- abstract class NonTemplateMemberImpl(sym: Symbol, implConv: ImplicitConversionInfoImpl, inTpl: => DocTemplateImpl) extends MemberImpl(sym, implConv, inTpl) with NonTemplateMemberEntity {
+ abstract class NonTemplateMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends MemberImpl(sym, implConv, inTpl) with NonTemplateMemberEntity {
override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name)
lazy val definitionName =
if (implConv == null) optimize(inDefinitionTemplates.head.qualifiedName + "#" + name)
- else optimize(implConv.conversion.conversionQualifiedName + "#" + name)
+ else optimize(implConv.conversionQualifiedName + "#" + name)
def isUseCase = sym.isSynthetic
def isBridge = sym.isBridge
}
- abstract class NonTemplateParamMemberImpl(sym: Symbol, implConv: ImplicitConversionInfoImpl, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, implConv, inTpl) {
+ abstract class NonTemplateParamMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl) extends NonTemplateMemberImpl(sym, implConv, inTpl) {
def valueParams = {
- val info = if (implConv eq null) sym.info else implConv.conversion.toType memberInfo sym
+ val info = if (implConv eq null) sym.info else implConv.toType memberInfo sym
info.paramss map { ps => (ps.zipWithIndex) map { case (p, i) =>
if (p.nameString contains "$") makeValueParam(p, inTpl, optimize("arg" + i)) else makeValueParam(p, inTpl)
}}
@@ -386,6 +335,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def typeParams =
sym.typeParams map (makeTypeParam(_, inTemplate))
}
+
/* ============== MAKER METHODS ============== */
/** */
@@ -533,7 +483,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
/** */
- def makeMember(aSym: Symbol, implConv: ImplicitConversionInfoImpl, inTpl: => DocTemplateImpl): List[MemberImpl] = {
+ // TODO: Should be able to override the type
+ def makeMember(aSym: Symbol, implConv: ImplicitConversionImpl, inTpl: => DocTemplateImpl): List[MemberImpl] = {
def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
if (bSym.isGetter && bSym.isLazy)
@@ -553,10 +504,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
if (bSym == definitions.Object_synchronized) {
val cSymInfo = (bSym.info: @unchecked) match {
case PolyType(ts, MethodType(List(bp), mt)) =>
- val cp = bp.cloneSymbol.setPos(bp.pos).setInfo(definitions.byNameType(bp.info))
+ val cp = bp.cloneSymbol.setInfo(definitions.byNameType(bp.info))
PolyType(ts, MethodType(List(cp), mt))
}
- bSym.cloneSymbol.setPos(bSym.pos).setInfo(cSymInfo)
+ bSym.cloneSymbol.setInfo(cSymInfo)
}
else bSym
}
@@ -668,20 +619,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
makeType(tpe, inTpl)
}
- /** Get the types of the parents of the current class, ignoring the refinements */
- def makeParentTypes(aType: Type, inTpl: => TemplateImpl): List[(TemplateEntity, TypeEntity)] = aType match {
- case RefinedType(parents, defs) =>
- val ignoreParents = Set[Symbol](AnyClass, ObjectClass)
- val filtParents = parents filterNot (x => ignoreParents(x.typeSymbol))
- filtParents.map(parent => {
- val templateEntity = makeTemplate(parent.typeSymbol)
- val typeEntity = makeType(parent, inTpl)
- (templateEntity, typeEntity)
- })
- case _ =>
- List((makeTemplate(aType.typeSymbol), makeType(aType, inTpl)))
- }
-
/** */
def makeType(aType: Type, inTpl: => TemplateImpl): TypeEntity = {
def templatePackage = closestPackage(inTpl.sym)
@@ -801,10 +738,4 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/** Filter '@bridge' methods only if *they don't override non-bridge methods*. See SI-5373 for details */
def isPureBridge(sym: Symbol) = sym.isBridge && sym.allOverriddenSymbols.forall(_.isBridge)
-
- // the classes that are excluded from the index should also be excluded from the diagrams
- def classExcluded(clazz: TemplateEntity): Boolean = settings.hardcoded.isExcluded(clazz.qualifiedName)
-
- // the implicit conversions that are excluded from the pages should not appear in the diagram
- def implicitExcluded(convertorMethod: String): Boolean = settings.hardcoded.commonConversionTargets.contains(convertorMethod)
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
index 64205104aa..c3525037cd 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -63,8 +63,8 @@ trait ModelFactoryImplicitSupport {
// debugging:
val DEBUG: Boolean = settings.docImplicitsDebug.value
val ERROR: Boolean = true // currently we show all errors
- @inline final def debug(msg: => String) = if (DEBUG) settings.printMsg(msg)
- @inline final def error(msg: => String) = if (ERROR) settings.printMsg(msg)
+ @inline final def debug(msg: => String) = if (DEBUG) println(msg)
+ @inline final def error(msg: => String) = if (ERROR) println(msg)
/** This is a flag that indicates whether to eliminate implicits that cannot be satisfied within the current scope.
* For example, if an implicit conversion requires that there is a Numeric[T] in scope:
@@ -96,17 +96,6 @@ trait ModelFactoryImplicitSupport {
def targetType: TypeEntity = makeType(toType, inTpl)
- def targetTemplate: Option[TemplateEntity] = toType match {
- // @Vlad: I'm being extra conservative in template creation -- I don't want to create templates for complex types
- // such as refinement types because the template can't represent the type corectly (a template corresponds to a
- // package, class, trait or object)
- case t: TypeRef => Some(makeTemplate(t.sym))
- case RefinedType(parents, decls) => None
- case _ => error("Scaladoc implicits: Could not create template for: " + toType + " of type " + toType.getClass); None
- }
-
- def targetTypeComponents: List[(TemplateEntity, TypeEntity)] = makeParentTypes(toType, inTpl)
-
def convertorOwner: TemplateEntity =
if (convSym != NoSymbol)
makeTemplate(convSym.owner)
@@ -137,15 +126,20 @@ trait ModelFactoryImplicitSupport {
lazy val constraints: List[Constraint] = constrs
- private val memberImpls: List[MemberImpl] = {
+ val members: List[MemberEntity] = {
// Obtain the members inherited by the implicit conversion
- val memberSyms = toType.members.filter(implicitShouldDocument(_))
- val existingSyms = sym.info.members
+ var memberSyms = toType.members.filter(implicitShouldDocument(_))
+ val existingMembers = sym.info.members
// Debugging part :)
debug(sym.nameString + "\n" + "=" * sym.nameString.length())
debug(" * conversion " + convSym + " from " + sym.tpe + " to " + toType)
+ // Members inherited by implicit conversions cannot override actual members
+ memberSyms = memberSyms.filterNot((sym1: Symbol) =>
+ existingMembers.exists(sym2 => sym1.name == sym2.name &&
+ !isDistinguishableFrom(toType.memberInfo(sym1), sym.info.memberInfo(sym2))))
+
debug(" -> full type: " + toType)
if (constraints.length != 0) {
debug(" -> constraints: ")
@@ -155,89 +149,10 @@ trait ModelFactoryImplicitSupport {
memberSyms foreach (sym => debug(" - "+ sym.decodedName +" : " + sym.info))
debug("")
- memberSyms.flatMap({ aSym =>
- makeTemplate(aSym.owner) match {
- case d: DocTemplateImpl =>
- // we can't just pick up nodes from the previous template, although that would be very convenient:
- // they need the byConversion field to be attached to themselves -- this is design decision I should
- // revisit soon
- //
- // d.ownMembers.collect({
- // // it's either a member or has a couple of usecases it's hidden behind
- // case m: MemberImpl if m.sym == aSym =>
- // m // the member itself
- // case m: MemberImpl if m.useCaseOf.isDefined && m.useCaseOf.get.asInstanceOf[MemberImpl].sym == aSym =>
- // m.useCaseOf.get.asInstanceOf[MemberImpl] // the usecase
- // })
- makeMember(aSym, new ImplicitConversionInfoImpl(this), d)
- case _ =>
- // should only happen if the code for this template is not part of the scaladoc run =>
- // members won't have any comments
- makeMember(aSym, new ImplicitConversionInfoImpl(this), inTpl)
- }
- })
- }
-
- def members: List[MemberEntity] = memberImpls
-
- def populateShadowingTables(allConvs: List[ImplicitConversionImpl]): Unit = {
-
- // TODO: This is not clean, we need to put sym.info.members here instead of tpl.memberSyms to avoid
- // the localShouldDocument(_) filtering in ModelFactory
- val originalClassMembers = inTpl.memberSyms
- val otherConversions = allConvs.filterNot(_ == this)
- assert(otherConversions.length == allConvs.length - 1)
-
- for (member <- memberImpls) {
- // for each member in our list
- val sym1 = member.sym
- val tpe1 = toType.memberInfo(sym1)
-
- // check if it's shadowed by a member in the original class
- var shadowedBySyms: List[Symbol] = List()
- for (sym2 <- originalClassMembers)
- if (sym1.name == sym2.name) {
- val shadowed = !settings.docImplicitsSoundShadowing.value || {
- val tpe2 = inTpl.sym.info.memberInfo(sym2)
- !isDistinguishableFrom(tpe1, tpe2)
- }
- if (shadowed)
- shadowedBySyms ::= sym2
- }
-
- val shadowedByMembers = inTpl.allOwnMembers.filter((mb: MemberImpl) => shadowedBySyms.contains(mb.sym))
-
- // check if it's shadowed by another member
- var ambiguousByMembers: List[MemberEntity] = List()
- for (conv <- otherConversions)
- for (member2 <- conv.memberImpls) {
- val sym2 = member2.sym
- if (sym1.name == sym2.name) {
- val tpe2 = conv.toType.memberInfo(sym2)
- // Ambiguity should be an equivalence relation
- val ambiguated = !isDistinguishableFrom(tpe1, tpe2) || !isDistinguishableFrom(tpe2, tpe1)
- if (ambiguated)
- ambiguousByMembers ::= member2
- }
- }
-
- // we finally have the shadowing info
- val shadowing = new ImplicitMemberShadowing {
- def shadowingMembers: List[MemberEntity] = shadowedByMembers
- def ambiguatingMembers: List[MemberEntity] = ambiguousByMembers
- }
-
- member.byConversion.get.asInstanceOf[ImplicitConversionInfoImpl].shadowing = shadowing
- }
+ memberSyms.flatMap((makeMember(_, this, inTpl)))
}
}
- class ImplicitConversionInfoImpl(
- val conversion: ImplicitConversionImpl) extends ImplicitConversionInfo {
- // this will be updated as a side effect
- var shadowing: ImplicitMemberShadowing = null
- }
-
/* ============== MAKER METHODS ============== */
/**
@@ -256,22 +171,18 @@ trait ModelFactoryImplicitSupport {
val results = global.analyzer.allViewsFrom(sym.tpe, context, sym.typeParams)
var conversions = results.flatMap(result => makeImplicitConversion(sym, result._1, result._2, context, inTpl))
- // also keep empty conversions, so they appear in diagrams
- // conversions = conversions.filter(!_.members.isEmpty)
+ conversions = conversions.filterNot(_.members.isEmpty)
// Filter out specialized conversions from array
if (sym == ArrayClass)
- conversions = conversions.filterNot((conv: ImplicitConversionImpl) =>
+ conversions = conversions.filterNot((conv: ImplicitConversion) =>
hardcoded.arraySkipConversions.contains(conv.conversionQualifiedName))
// Filter out non-sensical conversions from value types
if (isPrimitiveValueType(sym.tpe))
- conversions = conversions.filter((ic: ImplicitConversionImpl) =>
+ conversions = conversions.filter((ic: ImplicitConversion) =>
hardcoded.valueClassFilter(sym.nameString, ic.conversionQualifiedName))
- // side-effecting and ugly shadowing table population -- ugly but effective
- conversions.map(_.populateShadowingTables(conversions))
-
// Put the class-specific conversions in front
val (ownConversions, commonConversions) =
conversions.partition(conv => !hardcoded.commonConversionTargets.contains(conv.conversionQualifiedName))
@@ -307,7 +218,7 @@ trait ModelFactoryImplicitSupport {
* - we also need to transform implicit parameters in the view's signature into constraints, such that Numeric[T4]
* appears as a constraint
*/
- def makeImplicitConversion(sym: Symbol, result: SearchResult, constrs: List[TypeConstraint], context: Context, inTpl: => DocTemplateImpl): List[ImplicitConversionImpl] =
+ def makeImplicitConversion(sym: Symbol, result: SearchResult, constrs: List[TypeConstraint], context: Context, inTpl: => DocTemplateImpl): List[ImplicitConversion] =
if (result.tree == EmptyTree) Nil
else {
// `result` will contain the type of the view (= implicit conversion method)
@@ -582,8 +493,8 @@ trait ModelFactoryImplicitSupport {
// - common methods (in Any, AnyRef, Object) as they are automatically removed
// - private and protected members (not accessible following an implicit conversion)
// - members starting with _ (usually reserved for internal stuff)
- localShouldDocument(aSym) && (!aSym.isConstructor) && (aSym.owner != AnyValClass) &&
- (aSym.owner != AnyClass) && (aSym.owner != ObjectClass) &&
+ localShouldDocument(aSym) && (!aSym.isConstructor) && (aSym.owner != ObjectClass) &&
+ (aSym.owner != AnyClass) && (aSym.owner != AnyRefClass) &&
(!aSym.isProtected) && (!aSym.isPrivate) && (!aSym.name.startsWith("_")) &&
(aSym.isMethod || aSym.isGetter || aSym.isSetter) &&
(aSym.nameString != "getClass")
@@ -598,11 +509,12 @@ trait ModelFactoryImplicitSupport {
def isDistinguishableFrom(t1: Type, t2: Type): Boolean =
if (t1.paramss.map(_.length) == t2.paramss.map(_.length)) {
for ((t1p, t2p) <- t1.paramss.flatten zip t2.paramss.flatten)
- if (!isSubType(t1 memberInfo t1p, t2 memberInfo t2p))
- return true // if on the corresponding parameter you give a type that is in t1 but not in t2
- // def foo(a: Either[Int, Double]): Int = 3
- // def foo(b: Left[T1]): Int = 6
- // a.foo(Right(4.5d)) prints out 3 :)
+ if (!isSubType(t1 memberInfo t1p, t2 memberInfo t2p))
+ return true // if on the corresponding parameter you give a type that is in t1 but not in t2
+ // example:
+ // def foo(a: Either[Int, Double]): Int = 3
+ // def foo(b: Left[T1]): Int = 6
+ // a.foo(Right(4.5d)) prints out 3 :)
false
} else true // the member structure is different foo(3, 5) vs foo(3)(5)
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
index ecc3273903..ef4047cebf 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Body.scala
@@ -67,8 +67,8 @@ final case class Bold(text: Inline) extends Inline
final case class Underline(text: Inline) extends Inline
final case class Superscript(text: Inline) extends Inline
final case class Subscript(text: Inline) extends Inline
-final case class EntityLink(target: String, template: () => Option[TemplateEntity]) extends Inline
final case class Link(target: String, title: Inline) extends Inline
+final case class EntityLink(target: TemplateEntity) extends Inline
final case class Monospace(text: Inline) extends Inline
final case class Text(text: String) extends Inline
final case class HtmlTag(data: String) extends Inline {
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala b/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
index 7b70683db5..914275dd8d 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/Comment.scala
@@ -108,12 +108,6 @@ abstract class Comment {
/** A description for the primary constructor */
def constructor: Option[Body]
- /** A set of diagram directives for the inheritance diagram */
- def inheritDiagram: List[String]
-
- /** A set of diagram directives for the content diagram */
- def contentDiagram: List[String]
-
override def toString =
body.toString + "\n" +
(authors map ("@author " + _.toString)).mkString("\n") +
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index a46be37d60..996223b9f9 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -97,41 +97,37 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
/* Creates comments with necessary arguments */
def createComment (
- body0: Option[Body] = None,
- authors0: List[Body] = List.empty,
- see0: List[Body] = List.empty,
- result0: Option[Body] = None,
- throws0: Map[String,Body] = Map.empty,
- valueParams0: Map[String,Body] = Map.empty,
- typeParams0: Map[String,Body] = Map.empty,
- version0: Option[Body] = None,
- since0: Option[Body] = None,
- todo0: List[Body] = List.empty,
- deprecated0: Option[Body] = None,
- note0: List[Body] = List.empty,
- example0: List[Body] = List.empty,
- constructor0: Option[Body] = None,
- source0: Option[String] = None,
- inheritDiagram0: List[String] = List.empty,
- contentDiagram0: List[String] = List.empty
+ body0: Option[Body] = None,
+ authors0: List[Body] = List.empty,
+ see0: List[Body] = List.empty,
+ result0: Option[Body] = None,
+ throws0: Map[String,Body] = Map.empty,
+ valueParams0: Map[String,Body] = Map.empty,
+ typeParams0: Map[String,Body] = Map.empty,
+ version0: Option[Body] = None,
+ since0: Option[Body] = None,
+ todo0: List[Body] = List.empty,
+ deprecated0: Option[Body] = None,
+ note0: List[Body] = List.empty,
+ example0: List[Body] = List.empty,
+ constructor0: Option[Body] = None,
+ source0: Option[String] = None
) : Comment = new Comment{
- val body = if(body0 isDefined) body0.get else Body(Seq.empty)
- val authors = authors0
- val see = see0
- val result = result0
- val throws = throws0
- val valueParams = valueParams0
- val typeParams = typeParams0
- val version = version0
- val since = since0
- val todo = todo0
- val deprecated = deprecated0
- val note = note0
- val example = example0
- val constructor = constructor0
- val source = source0
- val inheritDiagram = inheritDiagram0
- val contentDiagram = contentDiagram0
+ val body = if(body0 isDefined) body0.get else Body(Seq.empty)
+ val authors = authors0
+ val see = see0
+ val result = result0
+ val throws = throws0
+ val valueParams = valueParams0
+ val typeParams = typeParams0
+ val version = version0
+ val since = since0
+ val todo = todo0
+ val deprecated = deprecated0
+ val note = note0
+ val example = example0
+ val constructor = constructor0
+ val source = source0
}
protected val endOfText = '\u0003'
@@ -190,10 +186,6 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
protected val safeTagMarker = '\u000E'
- /** A Scaladoc tag not linked to a symbol and not followed by text */
- protected val SingleTag =
- new Regex("""\s*@(\S+)\s*""")
-
/** A Scaladoc tag not linked to a symbol. Returns the name of the tag, and the rest of the line. */
protected val SimpleTag =
new Regex("""\s*@(\S+)\s+(.*)""")
@@ -314,11 +306,6 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
val value = body :: tags.getOrElse(key, Nil)
parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock)
- case SingleTag(name) :: ls if (!inCodeBlock) =>
- val key = SimpleTagKey(name)
- val value = "" :: tags.getOrElse(key, Nil)
- parse0(docBody, tags + (key -> value), Some(key), ls, inCodeBlock)
-
case line :: ls if (lastTagKey.isDefined) =>
val key = lastTagKey.get
val value =
@@ -334,24 +321,9 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
parse0(docBody, tags, lastTagKey, ls, inCodeBlock)
case Nil =>
- // Take the {inheritance, content} diagram keys aside, as it doesn't need any parsing
- val inheritDiagramTag = SimpleTagKey("inheritanceDiagram")
- val contentDiagramTag = SimpleTagKey("contentDiagram")
-
- val inheritDiagramText: List[String] = tags.get(inheritDiagramTag) match {
- case Some(list) => list
- case None => List.empty
- }
-
- val contentDiagramText: List[String] = tags.get(contentDiagramTag) match {
- case Some(list) => list
- case None => List.empty
- }
-
- val tagsWithoutDiagram = tags.filterNot(pair => pair._1 == inheritDiagramTag || pair._1 == contentDiagramTag)
val bodyTags: mutable.Map[TagKey, List[Body]] =
- mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWiki(_, pos))} toSeq: _*)
+ mutable.Map(tags mapValues {tag => tag map (parseWiki(_, pos))} toSeq: _*)
def oneTag(key: SimpleTagKey): Option[Body] =
((bodyTags remove key): @unchecked) match {
@@ -384,23 +356,21 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
}
val com = createComment (
- body0 = Some(parseWiki(docBody.toString, pos)),
- authors0 = allTags(SimpleTagKey("author")),
- see0 = allTags(SimpleTagKey("see")),
- result0 = oneTag(SimpleTagKey("return")),
- throws0 = allSymsOneTag(SimpleTagKey("throws")),
- valueParams0 = allSymsOneTag(SimpleTagKey("param")),
- typeParams0 = allSymsOneTag(SimpleTagKey("tparam")),
- version0 = oneTag(SimpleTagKey("version")),
- since0 = oneTag(SimpleTagKey("since")),
- todo0 = allTags(SimpleTagKey("todo")),
- deprecated0 = oneTag(SimpleTagKey("deprecated")),
- note0 = allTags(SimpleTagKey("note")),
- example0 = allTags(SimpleTagKey("example")),
- constructor0 = oneTag(SimpleTagKey("constructor")),
- source0 = Some(clean(src).mkString("\n")),
- inheritDiagram0 = inheritDiagramText,
- contentDiagram0 = contentDiagramText
+ body0 = Some(parseWiki(docBody.toString, pos)),
+ authors0 = allTags(SimpleTagKey("author")),
+ see0 = allTags(SimpleTagKey("see")),
+ result0 = oneTag(SimpleTagKey("return")),
+ throws0 = allSymsOneTag(SimpleTagKey("throws")),
+ valueParams0 = allSymsOneTag(SimpleTagKey("param")),
+ typeParams0 = allSymsOneTag(SimpleTagKey("tparam")),
+ version0 = oneTag(SimpleTagKey("version")),
+ since0 = oneTag(SimpleTagKey("since")),
+ todo0 = allTags(SimpleTagKey("todo")),
+ deprecated0 = oneTag(SimpleTagKey("deprecated")),
+ note0 = allTags(SimpleTagKey("note")),
+ example0 = allTags(SimpleTagKey("example")),
+ constructor0 = oneTag(SimpleTagKey("constructor")),
+ source0 = Some(clean(src).mkString("\n"))
)
for ((key, _) <- bodyTags)
@@ -716,6 +686,13 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
)
}
+ def entityLink(query: String): Inline = findTemplate(query) match {
+ case Some(tpl) =>
+ EntityLink(tpl)
+ case None =>
+ Text(query)
+ }
+
def link(): Inline = {
val SchemeUri = """([^:]+:.*)""".r
jump("[[")
@@ -740,8 +717,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
if (!qualName.contains(".") && !definitions.packageExists(qualName))
reportError(pos, "entity link to " + qualName + " should be a fully qualified name")
- // move the template resolution as late as possible
- EntityLink(qualName, () => findTemplate(qualName))
+ entityLink(qualName)
}
}
@@ -757,8 +733,8 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
nextChar()
}
- /**
- * Eliminates the (common) leading spaces in all lines, based on the first line
+ /**
+ * Eliminates the (common) leading spaces in all lines, based on the first line
* For indented pieces of code, it reduces the indent to the least whitespace prefix:
* {{{
* indented example
@@ -781,11 +757,11 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
while (index < code.length) {
code(index) match {
case ' ' =>
- if (wsArea)
+ if (wsArea)
crtSkip += 1
case c =>
wsArea = (c == '\n')
- maxSkip = if (firstLine || emptyLine) maxSkip else if (maxSkip <= crtSkip) maxSkip else crtSkip
+ maxSkip = if (firstLine || emptyLine) maxSkip else if (maxSkip <= crtSkip) maxSkip else crtSkip
crtSkip = if (c == '\n') 0 else crtSkip
firstLine = if (c == '\n') false else firstLine
emptyLine = if (c == '\n') true else false
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala
deleted file mode 100644
index 28a8c7d37d..0000000000
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/Diagram.scala
+++ /dev/null
@@ -1,143 +0,0 @@
-package scala.tools.nsc.doc
-package model
-package diagram
-
-import model._
-
-/**
- * The diagram base classes
- *
- * @author Damien Obrist
- * @author Vlad Ureche
- */
-abstract class Diagram {
- def nodes: List[Node]
- def edges: List[(Node, List[Node])]
- def isPackageDiagram = false
- def isClassDiagram = false
- def depthInfo: DepthInfo
-}
-
-case class PackageDiagram(nodes:List[/*Class*/Node], edges:List[(Node, List[Node])]) extends Diagram {
- override def isPackageDiagram = true
- lazy val depthInfo = new PackageDiagramDepth(this)
-}
-
-/** A class diagram */
-case class ClassDiagram(thisNode: ThisNode,
- superClasses: List[/*Class*/Node],
- subClasses: List[/*Class*/Node],
- incomingImplicits: List[ImplicitNode],
- outgoingImplicits: List[ImplicitNode]) extends Diagram {
- def nodes = thisNode :: superClasses ::: subClasses ::: incomingImplicits ::: outgoingImplicits
- def edges = (thisNode -> (superClasses ::: outgoingImplicits)) ::
- (subClasses ::: incomingImplicits).map(_ -> List(thisNode))
-
- override def isClassDiagram = true
- lazy val depthInfo = new DepthInfo {
- def maxDepth = 3
- def nodeDepth(node: Node) =
- if (node == thisNode) 1
- else if (superClasses.contains(node)) 0
- else if (subClasses.contains(node)) 2
- else if (incomingImplicits.contains(node) || outgoingImplicits.contains(node)) 1
- else -1
- }
-}
-
-trait DepthInfo {
- /** Gives the maximum depth */
- def maxDepth: Int
- /** Gives the depth of any node in the diagram or -1 if the node is not in the diagram */
- def nodeDepth(node: Node): Int
-}
-
-abstract class Node {
- def name = tpe.name
- def tpe: TypeEntity
- def tpl: Option[TemplateEntity]
- /** shortcut to get a DocTemplateEntity */
- def doctpl: Option[DocTemplateEntity] = tpl match {
- case Some(tpl) => tpl match {
- case d: DocTemplateEntity => Some(d)
- case _ => None
- }
- case _ => None
- }
- /* shortcuts to find the node type without matching */
- def isThisNode = false
- def isNormalNode = false
- def isClassNode = if (tpl.isDefined) (tpl.get.isClass || tpl.get.qualifiedName == "scala.AnyRef") else false
- def isTraitNode = if (tpl.isDefined) tpl.get.isTrait else false
- def isObjectNode= if (tpl.isDefined) tpl.get.isObject else false
- def isOtherNode = !(isClassNode || isTraitNode || isObjectNode)
- def isImplicitNode = false
- def isOutsideNode = false
-}
-
-// different matchers, allowing you to use the pattern matcher against any node
-// NOTE: A ThisNode or ImplicitNode can at the same time be ClassNode/TraitNode/OtherNode, not exactly according to
-// case class specification -- thus a complete match would be:
-// node match {
-// case ThisNode(tpe, _) => /* case for this node, you can still use .isClass, .isTrait and .isOther */
-// case ImplicitNode(tpe, _) => /* case for an implicit node, you can still use .isClass, .isTrait and .isOther */
-// case _ => node match {
-// case ClassNode(tpe, _) => /* case for a non-this, non-implicit Class node */
-// case TraitNode(tpe, _) => /* case for a non-this, non-implicit Trait node */
-// case OtherNode(tpe, _) => /* case for a non-this, non-implicit Other node */
-// }
-// }
-object Node { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = Some((n.tpe, n.tpl)) }
-object ClassNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isClassNode) Some((n.tpe, n.tpl)) else None }
-object TraitNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isTraitNode) Some((n.tpe, n.tpl)) else None }
-object ObjectNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isObjectNode) Some((n.tpe, n.tpl)) else None }
-object OutsideNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isOutsideNode) Some((n.tpe, n.tpl)) else None }
-object OtherNode { def unapply(n: Node): Option[(TypeEntity, Option[TemplateEntity])] = if (n.isOtherNode) Some((n.tpe, n.tpl)) else None }
-
-
-
-/** The node for the current class */
-case class ThisNode(tpe: TypeEntity, tpl: Option[TemplateEntity]) extends Node { override def isThisNode = true }
-
-/** The usual node */
-case class NormalNode(tpe: TypeEntity, tpl: Option[TemplateEntity]) extends Node { override def isNormalNode = true }
-
-/** A class or trait the thisnode can be converted to by an implicit conversion
- * TODO: I think it makes more sense to use the tpe links to templates instead of the TemplateEntity for implicit nodes
- * since some implicit conversions convert the class to complex types that cannot be represented as a single tmeplate
- */
-case class ImplicitNode(tpe: TypeEntity, tpl: Option[TemplateEntity]) extends Node { override def isImplicitNode = true }
-
-/** An outside node is shown in packages when a class from a different package makes it to the package diagram due to
- * its relation to a class in the package (and @contentDiagram showInheritedNodes annotation) */
-case class OutsideNode(tpe: TypeEntity, tpl: Option[TemplateEntity]) extends Node { override def isOutsideNode = true }
-
-
-// Computing and offering node depth information
-class PackageDiagramDepth(pack: PackageDiagram) extends DepthInfo {
- private[this] var _maxDepth = 0
- private[this] var _nodeDepth = Map[Node, Int]()
- private[this] var seedNodes = Set[Node]()
- private[this] val invertedEdges: Map[Node, List[Node]] =
- pack.edges.flatMap({case (node: Node, outgoing: List[Node]) => outgoing.map((_, node))}).groupBy(_._1).map({case (k, values) => (k, values.map(_._2))}).withDefaultValue(Nil)
- private[this] val directEdges: Map[Node, List[Node]] = pack.edges.toMap.withDefaultValue(Nil)
-
- // seed base nodes, to minimize noise - they can't all have parents, else there would only be cycles
- seedNodes ++= pack.nodes.filter(directEdges(_).isEmpty)
-
- while (!seedNodes.isEmpty) {
- var newSeedNodes = Set[Node]()
- for (node <- seedNodes) {
- val depth = 1 + (-1 :: directEdges(node).map(_nodeDepth.getOrElse(_, -1))).max
- if (depth != _nodeDepth.getOrElse(node, -1)) {
- _nodeDepth += (node -> depth)
- newSeedNodes ++= invertedEdges(node)
- if (depth > _maxDepth) _maxDepth = depth
- }
- }
- seedNodes = newSeedNodes
- }
-
- val maxDepth = _maxDepth
- def nodeDepth(node: Node) = _nodeDepth.getOrElse(node, -1)
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
deleted file mode 100644
index c06b5d50b7..0000000000
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramDirectiveParser.scala
+++ /dev/null
@@ -1,248 +0,0 @@
-package scala.tools.nsc.doc
-package model
-package diagram
-
-import model._
-import comment.CommentFactory
-import java.util.regex.{Pattern, Matcher}
-import scala.util.matching.Regex
-
-// statistics
-import html.page.diagram.DiagramStats
-
-/**
- * This trait takes care of parsing @{inheritance, content}Diagram annotations
- *
- * @author Damien Obrist
- * @author Vlad Ureche
- */
-trait DiagramDirectiveParser {
- this: ModelFactory with DiagramFactory with CommentFactory with TreeFactory =>
-
- ///// DIAGRAM FILTERS //////////////////////////////////////////////////////////////////////////////////////////////
-
- /**
- * The DiagramFilter trait directs the diagram engine about the way the diagram should be displayed
- *
- * Vlad: There's an explanation I owe to people using diagrams and not finding a way to hide a specific class from
- * all diagrams at once. So why did I choose to allow you to only control the diagrams at class level? So, the
- * reason is you would break the separate scaladoc compilation:
- * If you have an "@diagram hideMyClass" annotation in class A and you run scaladoc on it along with its subclass B
- * A will not appear in B's diagram. But if you scaladoc only on B, A's comment will not be parsed and the
- * instructions to hide class A from all diagrams will not be available. Thus I prefer to force you to control the
- * diagrams of each class locally. The problem does not appear with scalac, as scalac stores all its necessary
- * information (like scala signatures) serialized in the .class file. But we couldn't store doc comments in the class
- * file, could we? (Turns out we could, but that's another story)
- *
- * Any flaming for this decision should go to scala-internals@googlegroups.com
- */
- trait DiagramFilter {
- /** A flag to hide the diagram completely */
- def hideDiagram: Boolean
- /** Hide incoming implicit conversions (for type hierarchy diagrams) */
- def hideIncomingImplicits: Boolean
- /** Hide outgoing implicit conversions (for type hierarchy diagrams) */
- def hideOutgoingImplicits: Boolean
- /** Hide superclasses (for type hierarchy diagrams) */
- def hideSuperclasses: Boolean
- /** Hide subclasses (for type hierarchy diagrams) */
- def hideSubclasses: Boolean
- /** Show related classes from other objects/traits/packages (for content diagrams) */
- def showInheritedNodes: Boolean
- /** Hide a node from the diagram */
- def hideNode(clazz: TemplateEntity): Boolean
- /** Hide an edge from the diagram */
- def hideEdge(clazz1: TemplateEntity, clazz2: TemplateEntity): Boolean
- }
-
- /** Main entry point into this trait: generate the filter for inheritance diagrams */
- def makeInheritanceDiagramFilter(template: DocTemplateImpl): DiagramFilter = {
- val defaultFilter = if (template.isClass || template.isTrait) FullDiagram else NoDiagramAtAll
- if (template.comment.isDefined)
- makeDiagramFilter(template, template.comment.get.inheritDiagram, defaultFilter, true)
- else
- defaultFilter
- }
-
- /** Main entry point into this trait: generate the filter for content diagrams */
- def makeContentDiagramFilter(template: DocTemplateImpl): DiagramFilter = {
- val defaultFilter = if (template.isPackage || template.isObject) FullDiagram else NoDiagramAtAll
- if (template.comment.isDefined)
- makeDiagramFilter(template, template.comment.get.contentDiagram, defaultFilter, false)
- else
- defaultFilter
- }
-
- protected var tFilter = 0l
- protected var tModel = 0l
-
- /** Show the entire diagram, no filtering */
- case object FullDiagram extends DiagramFilter {
- val hideDiagram: Boolean = false
- val hideIncomingImplicits: Boolean = false
- val hideOutgoingImplicits: Boolean = false
- val hideSuperclasses: Boolean = false
- val hideSubclasses: Boolean = false
- val showInheritedNodes: Boolean = false
- def hideNode(clazz: TemplateEntity): Boolean = false
- def hideEdge(clazz1: TemplateEntity, clazz2: TemplateEntity): Boolean = false
- }
-
- /** Hide the diagram completely, no need for special filtering */
- case object NoDiagramAtAll extends DiagramFilter {
- val hideDiagram: Boolean = true
- val hideIncomingImplicits: Boolean = true
- val hideOutgoingImplicits: Boolean = true
- val hideSuperclasses: Boolean = true
- val hideSubclasses: Boolean = true
- val showInheritedNodes: Boolean = false
- def hideNode(clazz: TemplateEntity): Boolean = true
- def hideEdge(clazz1: TemplateEntity, clazz2: TemplateEntity): Boolean = true
- }
-
- /** The AnnotationDiagramFilter trait directs the diagram engine according to an annotation
- * TODO: Should document the annotation, for now see parseDiagramAnnotation in ModelFactory.scala */
- case class AnnotationDiagramFilter(hideDiagram: Boolean,
- hideIncomingImplicits: Boolean,
- hideOutgoingImplicits: Boolean,
- hideSuperclasses: Boolean,
- hideSubclasses: Boolean,
- showInheritedNodes: Boolean,
- hideNodesFilter: List[Pattern],
- hideEdgesFilter: List[(Pattern, Pattern)]) extends DiagramFilter {
-
- def hideNode(clazz: TemplateEntity): Boolean = {
- val qualifiedName = clazz.qualifiedName
- for (hideFilter <- hideNodesFilter)
- if (hideFilter.matcher(qualifiedName).matches) {
- // println(hideFilter + ".matcher(" + qualifiedName + ").matches = " + hideFilter.matcher(qualifiedName).matches)
- return true
- }
- false
- }
-
- def hideEdge(clazz1: TemplateEntity, clazz2: TemplateEntity): Boolean = {
- val clazz1Name = clazz1.qualifiedName
- val clazz2Name = clazz2.qualifiedName
- for ((clazz1Filter, clazz2Filter) <- hideEdgesFilter) {
- if (clazz1Filter.matcher(clazz1Name).matches &&
- clazz2Filter.matcher(clazz2Name).matches) {
- // println(clazz1Filter + ".matcher(" + clazz1Name + ").matches = " + clazz1Filter.matcher(clazz1Name).matches)
- // println(clazz2Filter + ".matcher(" + clazz2Name + ").matches = " + clazz2Filter.matcher(clazz2Name).matches)
- return true
- }
- }
- false
- }
- }
-
- // TODO: This could certainly be improved -- right now the only regex is *, but there's no way to match a single identifier
- private val NodeSpecRegex = "\\\"[A-Za-z\\*][A-Za-z\\.\\*]*\\\""
- private val NodeSpecPattern = Pattern.compile(NodeSpecRegex)
- private val EdgeSpecRegex = "\\(" + NodeSpecRegex + "\\s*\\->\\s*" + NodeSpecRegex + "\\)"
- private val EdgeSpecPattern = Pattern.compile(NodeSpecRegex)
- // And the composed regexes:
- private val HideNodesRegex = new Regex("^hideNodes(\\s*" + NodeSpecRegex + ")+$")
- private val HideEdgesRegex = new Regex("^hideEdges(\\s*" + EdgeSpecRegex + ")+$")
-
- private def makeDiagramFilter(template: DocTemplateImpl,
- directives: List[String],
- defaultFilter: DiagramFilter,
- isInheritanceDiagram: Boolean): DiagramFilter = directives match {
-
- // if there are no specific diagram directives, return the default filter (either FullDiagram or NoDiagramAtAll)
- case Nil =>
- defaultFilter
-
- // compute the exact filters. By including the annotation, the diagram is autmatically added
- case _ =>
- tFilter -= System.currentTimeMillis
- var hideDiagram0: Boolean = false
- var hideIncomingImplicits0: Boolean = false
- var hideOutgoingImplicits0: Boolean = false
- var hideSuperclasses0: Boolean = false
- var hideSubclasses0: Boolean = false
- var showInheritedNodes0: Boolean = false
- var hideNodesFilter0: List[Pattern] = Nil
- var hideEdgesFilter0: List[(Pattern, Pattern)] = Nil
-
- def warning(message: String) = {
- // we need the position from the package object (well, ideally its comment, but yeah ...)
- val sym = if (template.sym.isPackage) template.sym.info.member(global.nme.PACKAGE) else template.sym
- assert((sym != global.NoSymbol) || (sym == global.definitions.RootPackage))
- global.reporter.warning(sym.pos, message)
- }
-
- def preparePattern(className: String) =
- "^" + className.stripPrefix("\"").stripSuffix("\"").replaceAll("\\.", "\\\\.").replaceAll("\\*", ".*") + "$"
-
- // separate entries:
- val entries = directives.foldRight("")(_ + " " + _).split(",").map(_.trim)
- for (entry <- entries)
- entry match {
- case "hideDiagram" =>
- hideDiagram0 = true
- case "hideIncomingImplicits" if isInheritanceDiagram =>
- hideIncomingImplicits0 = true
- case "hideOutgoingImplicits" if isInheritanceDiagram =>
- hideOutgoingImplicits0 = true
- case "hideSuperclasses" if isInheritanceDiagram =>
- hideSuperclasses0 = true
- case "hideSubclasses" if isInheritanceDiagram =>
- hideSubclasses0 = true
- case "showInheritedNodes" if !isInheritanceDiagram =>
- showInheritedNodes0 = true
- case HideNodesRegex(last) =>
- val matcher = NodeSpecPattern.matcher(entry)
- while (matcher.find()) {
- val classPattern = Pattern.compile(preparePattern(matcher.group()))
- hideNodesFilter0 ::= classPattern
- }
- case HideEdgesRegex(last) =>
- val matcher = NodeSpecPattern.matcher(entry)
- while (matcher.find()) {
- val class1Pattern = Pattern.compile(preparePattern(matcher.group()))
- assert(matcher.find()) // it's got to be there, just matched it!
- val class2Pattern = Pattern.compile(preparePattern(matcher.group()))
- hideEdgesFilter0 ::= ((class1Pattern, class2Pattern))
- }
- case "" =>
- // don't need to do anything about it
- case _ =>
- warning("Could not understand diagram annotation in " + template.fullName + ": unmatched entry \"" +
- entry + "\".\n" +
- " This could be because:\n" +
- " - you forgot to separate entries by commas\n" +
- " - you used a tag that is not allowed in the current context (like @contentDiagram hideSuperclasses)\n"+
- " - you did not use one of the allowed tags (see docs.scala-lang.org for scaladoc annotations)")
- }
- val result =
- if (hideDiagram0)
- NoDiagramAtAll
- else if ((hideNodesFilter0.isEmpty) &&
- (hideEdgesFilter0.isEmpty) &&
- (hideIncomingImplicits0 == false) &&
- (hideOutgoingImplicits0 == false) &&
- (hideSuperclasses0 == false) &&
- (hideSubclasses0 == false) &&
- (showInheritedNodes0 == false) &&
- (hideDiagram0 == false))
- FullDiagram
- else
- AnnotationDiagramFilter(
- hideDiagram = hideDiagram0,
- hideIncomingImplicits = hideIncomingImplicits0,
- hideOutgoingImplicits = hideOutgoingImplicits0,
- hideSuperclasses = hideSuperclasses0,
- hideSubclasses = hideSubclasses0,
- showInheritedNodes = showInheritedNodes0,
- hideNodesFilter = hideNodesFilter0,
- hideEdgesFilter = hideEdgesFilter0)
-
- if (settings.docDiagramsDebug.value && result != NoDiagramAtAll && result != FullDiagram)
- settings.printMsg(template.fullName + " filter: " + result)
- tFilter += System.currentTimeMillis
-
- result
- }
-} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
deleted file mode 100644
index 4ae5e7a5cb..0000000000
--- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala
+++ /dev/null
@@ -1,197 +0,0 @@
-package scala.tools.nsc.doc
-package model
-package diagram
-
-import model._
-import comment.CommentFactory
-import collection.mutable
-
-// statistics
-import html.page.diagram.DiagramStats
-
-/**
- * This trait takes care of generating the diagram for classes and packages
- *
- * @author Damien Obrist
- * @author Vlad Ureche
- */
-trait DiagramFactory extends DiagramDirectiveParser {
- this: ModelFactory with DiagramFactory with CommentFactory with TreeFactory =>
-
- /** Create the inheritance diagram for this template */
- def makeInheritanceDiagram(tpl: DocTemplateImpl): Option[Diagram] = {
-
- tFilter = 0
- tModel = -System.currentTimeMillis
-
- // the diagram filter
- val diagramFilter = makeInheritanceDiagramFilter(tpl)
-
- val result =
- if (diagramFilter == NoDiagramAtAll)
- None
- else {
- // the main node
- val thisNode = ThisNode(tpl.ownType, Some(tpl))
-
- // superclasses
- var superclasses = List[Node]()
- tpl.parentTypes.collect { case p: (TemplateEntity, TypeEntity) if !classExcluded(p._1) => p } foreach {
- t: (TemplateEntity, TypeEntity) =>
- val n = NormalNode(t._2, Some(t._1))
- superclasses ::= n
- }
- val filteredSuperclasses = if (diagramFilter.hideSuperclasses) Nil else superclasses
-
- // incoming implcit conversions
- lazy val incomingImplicitNodes = tpl.incomingImplicitlyConvertedClasses.map(tpl => ImplicitNode(tpl.ownType, Some(tpl)))
- val filteredIncomingImplicits = if (diagramFilter.hideIncomingImplicits) Nil else incomingImplicitNodes
-
- // subclasses
- val subclasses = tpl.directSubClasses.flatMap {
- case d: TemplateEntity if !classExcluded(d) => List(NormalNode(d.ownType, Some(d)))
- case _ => Nil
- }
- val filteredSubclasses = if (diagramFilter.hideSubclasses) Nil else subclasses
-
- // outgoing implicit coversions
- lazy val implicitNodes = tpl.outgoingImplicitlyConvertedClasses.map(pair => ImplicitNode(pair._2, Some(pair._1)))
- val filteredImplicitOutgoingNodes = if (diagramFilter.hideOutgoingImplicits) Nil else implicitNodes
-
- // final diagram filter
- filterDiagram(ClassDiagram(thisNode, filteredSuperclasses.reverse, filteredSubclasses.reverse, filteredIncomingImplicits, filteredImplicitOutgoingNodes), diagramFilter)
- }
-
- tModel += System.currentTimeMillis
- DiagramStats.addFilterTime(tFilter)
- DiagramStats.addModelTime(tModel-tFilter)
-
- result
- }
-
- /** Create the content diagram for this template */
- def makeContentDiagram(pack: DocTemplateImpl): Option[Diagram] = {
-
- tFilter = 0
- tModel = -System.currentTimeMillis
-
- // the diagram filter
- val diagramFilter = makeContentDiagramFilter(pack)
-
- val result =
- if (diagramFilter == NoDiagramAtAll)
- None
- else {
- var mapNodes = Map[DocTemplateEntity, Node]()
- var nodesShown = Set[DocTemplateEntity]()
- var edgesAll = List[(DocTemplateEntity, List[DocTemplateEntity])]()
-
- // classes is the entire set of classes and traits in the package, they are the superset of nodes in the diagram
- // we collect classes, traits and objects without a companion, which are usually used as values(e.g. scala.None)
- val dnodes = pack.members collect {
- case d: DocTemplateEntity if d.isClass || d.isTrait || (d.isObject && !d.companion.isDefined) &&
- ((d.inTemplate == pack) || diagramFilter.showInheritedNodes) => d
- }
-
- // for each node, add its subclasses
- for (node <- dnodes if !classExcluded(node)) {
- val superClasses = node.parentTypes.collect {
- case (tpl: DocTemplateEntity, tpe) if tpl.inTemplate == pack && !classExcluded(tpl) => tpl
- case (tpl: DocTemplateEntity, tpe) if tpl.inTemplate != pack && !classExcluded(tpl) && diagramFilter.showInheritedNodes && (pack.members contains tpl) => tpl
- }
-
- if (!superClasses.isEmpty) {
- nodesShown += node
- nodesShown ++= superClasses
- }
-
- edgesAll ::= node -> superClasses
- mapNodes += node -> (if (node.inTemplate == pack) NormalNode(node.ownType, Some(node)) else OutsideNode(node.ownType, Some(node)))
- }
-
- if (nodesShown.isEmpty)
- None
- else {
- val nodes = dnodes.filter(nodesShown.contains(_)).map(mapNodes(_))
- val edges = edgesAll.map(pair => (mapNodes(pair._1), pair._2.map(mapNodes(_)))).filterNot(pair => pair._2.isEmpty)
- filterDiagram(PackageDiagram(nodes, edges), diagramFilter)
- }
- }
-
- tModel += System.currentTimeMillis
- DiagramStats.addFilterTime(tFilter)
- DiagramStats.addModelTime(tModel-tFilter)
-
- result
- }
-
- /** Diagram filtering logic */
- private def filterDiagram(diagram: Diagram, diagramFilter: DiagramFilter): Option[Diagram] = {
- tFilter -= System.currentTimeMillis
-
- val result =
- if (diagramFilter == FullDiagram)
- Some(diagram)
- else if (diagramFilter == NoDiagramAtAll)
- None
- else {
- // Final diagram, with the filtered nodes and edges
- diagram match {
- case ClassDiagram(thisNode, _, _, _, _) if diagramFilter.hideNode(thisNode.tpl.get) =>
- None
-
- case ClassDiagram(thisNode, superClasses, subClasses, incomingImplicits, outgoingImplicits) =>
-
- def hideIncoming(node: Node): Boolean =
- if (node.tpl.isDefined) diagramFilter.hideNode(node.tpl.get) || diagramFilter.hideEdge(node.tpl.get, thisNode.tpl.get)
- else false // hopefully we won't need to fallback here
-
- def hideOutgoing(node: Node): Boolean =
- if (node.tpl.isDefined) diagramFilter.hideNode(node.tpl.get) || diagramFilter.hideEdge(thisNode.tpl.get, node.tpl.get)
- else false // hopefully we won't need to fallback here
-
- // println(thisNode)
- // println(superClasses.map(cl => "super: " + cl + " " + hideOutgoing(cl)).mkString("\n"))
- // println(subClasses.map(cl => "sub: " + cl + " " + hideIncoming(cl)).mkString("\n"))
- Some(ClassDiagram(thisNode,
- superClasses.filterNot(hideOutgoing(_)),
- subClasses.filterNot(hideIncoming(_)),
- incomingImplicits.filterNot(hideIncoming(_)),
- outgoingImplicits.filterNot(hideOutgoing(_))))
-
- case PackageDiagram(nodes0, edges0) =>
- // Filter out all edges that:
- // (1) are sources of hidden classes
- // (2) are manually hidden by the user
- // (3) are destinations of hidden classes
- val edges: List[(Node, List[Node])] =
- diagram.edges.flatMap({
- case (source@Node(_, Some(tpl1)), dests) if !diagramFilter.hideNode(tpl1) =>
- val dests2 = dests.collect({ case node@Node(_, Some(tpl2)) if (!(diagramFilter.hideEdge(tpl1, tpl2) || diagramFilter.hideNode(tpl2))) => node })
- if (dests2 != Nil)
- List((source, dests2))
- else
- Nil
- case _ => Nil
- })
-
- // Only show the the non-isolated nodes
- // TODO: Decide if we really want to hide package members, I'm not sure that's a good idea (!!!)
- // TODO: Does .distinct cause any stability issues?
- val sourceNodes = edges.map(_._1)
- val sinkNodes = edges.map(_._2).flatten
- val nodes = (sourceNodes ::: sinkNodes).distinct
- Some(PackageDiagram(nodes, edges))
- }
- }
-
- tFilter += System.currentTimeMillis
-
- // eliminate all empty diagrams
- if (result.isDefined && result.get.edges.forall(_._2.isEmpty))
- None
- else
- result
- }
-
-}
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
index de5354d4a0..142f2baea5 100644
--- a/src/partest/scala/tools/partest/ScaladocModelTest.scala
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -81,9 +81,9 @@ abstract class ScaladocModelTest extends DirectTest {
private[this] var settings: Settings = null
// create a new scaladoc compiler
- private[this] def newDocFactory: DocFactory = {
+ def newDocFactory: DocFactory = {
settings = new Settings(_ => ())
- settings.scaladocQuietRun = true // yaay, no more "model contains X documentable templates"!
+ settings.reportModel = false // yaay, no more "model contains X documentable templates"!
val args = extraSettings + " " + scaladocSettings
val command = new ScalaDoc.Command((CommandLineParser tokenize (args)), settings)
val docFact = new DocFactory(new ConsoleReporter(settings), settings)
diff --git a/test/scaladoc/resources/implicits-ambiguating-res.scala b/test/scaladoc/resources/implicits-ambiguating-res.scala
deleted file mode 100644
index 6ed51366cb..0000000000
--- a/test/scaladoc/resources/implicits-ambiguating-res.scala
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Test scaladoc implicits distinguishing -- supress all members by implicit conversion that are shadowed by the
- * class' own members
- *
- * {{{
- * scala> class A { def foo(t: String) = 4 }
- * defined class A
- *
- * scala> class B { def foo(t: Any) = 5 }
- * defined class B
- *
- * scala> implicit def AtoB(a:A) = new B
- * AtoB: (a: A)B
- *
- * scala> val a = new A
- * a: A = A@28f553e3
- *
- * scala> a.foo("T")
- * res1: Int = 4
- *
- * scala> a.foo(4)
- * res2: Int = 5
- * }}}
- */
-package scala.test.scaladoc.implicits.ambiguating
-import language.implicitConversions // according to SIP18
-
-/** - conv1-5 should be ambiguous
- * - conv6-7 should not be ambiguous
- * - conv8 should be ambiguous
- * - conv9 should be ambiguous
- * - conv10 and conv11 should not be ambiguous */
-class A[T]
-/** conv1-9 should be the same, conv10 should be ambiguous, conv11 should be okay */
-class B extends A[Int]
-/** conv1-9 should be the same, conv10 and conv11 should not be ambiguous */
-class C extends A[Double]
- /** conv1-9 should be the same, conv10 should not be ambiguous while conv11 should be ambiguous */
-class D extends A[AnyRef]
-
-class X[T] {
- def conv1: AnyRef = ???
- def conv2: T = ???
- def conv3(l: Int): AnyRef = ???
- def conv4(l: AnyRef): AnyRef = ???
- def conv5(l: AnyRef): String = ???
- def conv6(l: String)(m: String): AnyRef = ???
- def conv7(l: AnyRef)(m: AnyRef): AnyRef = ???
- def conv8(l: AnyRef): AnyRef = ???
- def conv9(l: String): AnyRef = ???
- def conv10(l: T): T = ???
- def conv11(l: T): T = ???
-}
-
-class Z[T] {
- def conv1: AnyRef = ???
- def conv2: T = ???
- def conv3(p: Int): AnyRef = ???
- def conv4(p: AnyRef): String = ???
- def conv5(p: AnyRef): AnyRef = ???
- def conv6(p: String, q: String): AnyRef = ???
- def conv7(p: AnyRef, q: AnyRef): AnyRef = ???
- def conv8(p: String): AnyRef = ???
- def conv9(p: AnyRef): AnyRef = ???
- def conv10(p: Int): T = ???
- def conv11(p: String): T = ???
-}
-
-object A {
- implicit def AtoX[T](a: A[T]) = new X[T]
- implicit def AtoZ[T](a: A[T]) = new Z[T]
-}
diff --git a/test/scaladoc/resources/implicits-base-res.scala b/test/scaladoc/resources/implicits-base-res.scala
index d6c0332c10..65d7bdf67c 100644
--- a/test/scaladoc/resources/implicits-base-res.scala
+++ b/test/scaladoc/resources/implicits-base-res.scala
@@ -16,9 +16,8 @@ trait MyNumeric[R]
* def convToManifestA(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
* def convToMyNumericA(x: T) // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
* def convToNumericA(x: T) // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
- * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints, SHADOWED
- * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar, SHADOWED
- * def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED
+ * def convToPimpedA(x: Bar[Foo[T]]) // pimpA5: no constraints
+ * def convToPimpedA(x: S) // pimpA4: with 3 constraints: T = Foo[Bar[S]], S: Foo and S: Bar
* def convToTraversableOps(x: T) // pimpA7: with 2 constraints: T: Manifest and T <: Double
* // should not be abstract!
* }}}
@@ -53,10 +52,9 @@ object A {
* def convToManifestA(x: Double) // pimpA7: no constraints
* def convToMyNumericA(x: Double) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
* def convToNumericA(x: Double) // pimpA1: no constraintsd
- * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints, SHADOWED
- * def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED
+ * def convToPimpedA(x: Bar[Foo[Double]]) // pimpA5: no constraints
* def convToTraversableOps(x: Double) // pimpA7: no constraints
- * // should not be abstract!
+ * // should not be abstract!
* }}}
*/
class B extends A[Double]
@@ -70,8 +68,7 @@ object B extends A
* def convToIntA(x: Int) // pimpA2: no constraints
* def convToMyNumericA(x: Int) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
* def convToNumericA(x: Int) // pimpA1: no constraints
- * def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED
- * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints, SHADOWED
+ * def convToPimpedA(x: Bar[Foo[Int]]) // pimpA5: no constraints
* }}}
*/
class C extends A[Int]
@@ -84,8 +81,7 @@ object C extends A
* {{{
* def convToMyNumericA(x: String) // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
* def convToNumericA(x: String) // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
- * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints, SHADOWED
- * def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED
+ * def convToPimpedA(x: Bar[Foo[String]]) // pimpA5: no constraints
* }}}
*/
class D extends A[String]
diff --git a/test/scaladoc/resources/implicits-elimination-res.scala b/test/scaladoc/resources/implicits-elimination-res.scala
index 5f7135c9e8..b23667440c 100644
--- a/test/scaladoc/resources/implicits-elimination-res.scala
+++ b/test/scaladoc/resources/implicits-elimination-res.scala
@@ -2,13 +2,13 @@
* Testing scaladoc implicits elimination
*/
package scala.test.scaladoc.implicits.elimination {
-
+
import language.implicitConversions // according to SIP18
/** No conversion, as B doesn't bring any member */
class A
class B { class C; trait V; type T; }
- object A {
- implicit def toB(a: A): B = null
+ object A {
+ implicit def toB(a: A): B = null
}
}
diff --git a/test/scaladoc/run/diagrams-base.scala b/test/scaladoc/run/diagrams-base.scala
deleted file mode 100644
index 38bed06502..0000000000
--- a/test/scaladoc/run/diagrams-base.scala
+++ /dev/null
@@ -1,73 +0,0 @@
-import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.diagram._
-import scala.tools.partest.ScaladocModelTest
-
-object Test extends ScaladocModelTest {
-
- override def code = """
- package scala.test.scaladoc.diagrams
-
- import language.implicitConversions
-
- trait A
- trait B
- trait C
- class E extends A with B with C
- object E { implicit def eToT(e: E) = new T }
-
- class F extends E
- class G extends E
- private class H extends E /* since it's private, it won't go into the diagram */
- class T { def t = true }
-
- class X
- object X { implicit def xToE(x: X) = new E}
- class Y extends X
- class Z
- object Z { implicit def zToE(z: Z) = new E}
- """
-
- // diagrams must be started. In case there's an error with dot, it should not report anything
- def scaladocSettings = "-diagrams -implicits"
-
- def testModel(rootPackage: Package) = {
- // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
- import access._
-
- val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams")
- val E = base._class("E")
- val diag = E.inheritanceDiagram.get
-
- // there must be a single this node
- assert(diag.nodes.filter(_.isThisNode).length == 1)
-
- // 1. check class E diagram
- assert(diag.isClassDiagram)
-
- val (incoming, outgoing) = diag.edges.partition(!_._1.isThisNode)
- assert(incoming.length == 5)
- assert(outgoing.head._2.length == 4)
-
- val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode)
- assert(outgoingSuperclass.length == 3)
- assert(outgoingImplicit.length == 1)
-
- val (incomingSubclass, incomingImplicit) = incoming.partition(_._1.isNormalNode)
- assert(incomingSubclass.length == 2)
- assert(incomingImplicit.length == 3)
-
- val classDiag = diag.asInstanceOf[ClassDiagram]
- assert(classDiag.incomingImplicits.length == 3)
- assert(classDiag.outgoingImplicits.length == 1)
-
- // 2. check package diagram
- // NOTE: Z should be eliminated because it's isolated
- val packDiag = base.contentDiagram.get
- assert(packDiag.isPackageDiagram)
- assert(packDiag.nodes.length == 8) // check singular object removal
- assert(packDiag.edges.length == 4)
- assert(packDiag.edges.foldLeft(0)(_ + _._2.length) == 6)
-
- // TODO: Should check numbering
- }
-} \ No newline at end of file
diff --git a/test/scaladoc/run/diagrams-determinism.check b/test/scaladoc/run/diagrams-determinism.check
deleted file mode 100644
index 619c56180b..0000000000
--- a/test/scaladoc/run/diagrams-determinism.check
+++ /dev/null
@@ -1 +0,0 @@
-Done.
diff --git a/test/scaladoc/run/diagrams-determinism.scala b/test/scaladoc/run/diagrams-determinism.scala
deleted file mode 100644
index 6c8db05d78..0000000000
--- a/test/scaladoc/run/diagrams-determinism.scala
+++ /dev/null
@@ -1,67 +0,0 @@
-import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.diagram._
-import scala.tools.partest.ScaladocModelTest
-
-object Test extends ScaladocModelTest {
-
- override def code = """
- package scala.test.scaladoc.diagrams
-
- trait A
- trait B extends A
- trait C extends B
- trait D extends C with A
- trait E extends C with A with D
- """
-
- // diagrams must be started. In case there's an error with dot, it should not report anything
- def scaladocSettings = "-diagrams -implicits"
-
- def testModel(rootPackage: Package) = {
- // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
- import access._
-
- def diagramString(rootPackage: Package) = {
- val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams")
- val A = base._trait("A")
- val B = base._trait("B")
- val C = base._trait("C")
- val D = base._trait("D")
- val E = base._trait("E")
-
- base.contentDiagram.get.toString + "\n" +
- A.inheritanceDiagram.get.toString + "\n" +
- B.inheritanceDiagram.get.toString + "\n" +
- C.inheritanceDiagram.get.toString + "\n" +
- D.inheritanceDiagram.get.toString + "\n" +
- E.inheritanceDiagram.get.toString
- }
-
- // 1. check that several runs produce the same output
- val run0 = diagramString(rootPackage)
- val run1 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage)
- val run2 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage)
- val run3 = diagramString(model.getOrElse({sys.error("Scaladoc Model Test ERROR: No universe generated!")}).rootPackage)
-
- // any variance in the order of the diagram elements should crash the following tests:
- assert(run0 == run1)
- assert(run1 == run2)
- assert(run2 == run3)
-
- // 2. check the order in the diagram: this node, subclasses, and then implicit conversions
- def assertRightOrder(diagram: Diagram) = {
- for ((node, subclasses) <- diagram.edges)
- assert(subclasses == subclasses.filter(_.isThisNode) :::
- subclasses.filter(_.isNormalNode) :::
- subclasses.filter(_.isImplicitNode))
- }
-
- val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams")
- assertRightOrder(base.contentDiagram.get)
- assertRightOrder(base._trait("A").inheritanceDiagram.get)
- assertRightOrder(base._trait("B").inheritanceDiagram.get)
- assertRightOrder(base._trait("C").inheritanceDiagram.get)
- assertRightOrder(base._trait("D").inheritanceDiagram.get)
- assertRightOrder(base._trait("E").inheritanceDiagram.get)
- }
-} \ No newline at end of file
diff --git a/test/scaladoc/run/diagrams-filtering.check b/test/scaladoc/run/diagrams-filtering.check
deleted file mode 100644
index 619c56180b..0000000000
--- a/test/scaladoc/run/diagrams-filtering.check
+++ /dev/null
@@ -1 +0,0 @@
-Done.
diff --git a/test/scaladoc/run/diagrams-filtering.scala b/test/scaladoc/run/diagrams-filtering.scala
deleted file mode 100644
index dfde5cac52..0000000000
--- a/test/scaladoc/run/diagrams-filtering.scala
+++ /dev/null
@@ -1,93 +0,0 @@
-import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.diagram._
-import scala.tools.partest.ScaladocModelTest
-
-object Test extends ScaladocModelTest {
-
- override def code = """
- package scala.test.scaladoc
-
- /** @contentDiagram hideNodes "scala.test.*.A" "java.*", hideEdges ("*G" -> "*E") */
- package object diagrams {
- def foo = 4
- }
-
- package diagrams {
- import language.implicitConversions
-
- /** @inheritanceDiagram hideIncomingImplicits, hideNodes "*E" */
- trait A
- trait AA extends A
- trait B
- trait AAA extends B
-
- /** @inheritanceDiagram hideDiagram */
- trait C
- trait AAAA extends C
-
- /** @inheritanceDiagram hideEdges("*E" -> "*A") */
- class E extends A with B with C
- class F extends E
- /** @inheritanceDiagram hideNodes "*G" "G" */
- class G extends E
- private class H extends E /* since it's private, it won't go into the diagram */
- class T { def t = true }
- object E {
- implicit def eToT(e: E) = new T
- implicit def eToA(e: E) = new A { }
- }
- }
- """
-
- // diagrams must be started. In case there's an error with dot, it should not report anything
- def scaladocSettings = "-diagrams -implicits"
-
- def testModel(rootPackage: Package) = {
- // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
- import access._
-
- // base package
- // Assert we have 7 nodes and 6 edges
- val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("diagrams")
- val packDiag = base.contentDiagram.get
- assert(packDiag.nodes.length == 6)
- assert(packDiag.edges.map(_._2.length).sum == 5)
-
- // trait A
- // Assert we have just 2 nodes and 1 edge
- val A = base._trait("A")
- val ADiag = A.inheritanceDiagram.get
- assert(ADiag.nodes.length == 2)
- assert(ADiag.edges.map(_._2.length).sum == 1)
-
- // trait C
- val C = base._trait("C")
- assert(!C.inheritanceDiagram.isDefined)
-
- // trait G
- val G = base._trait("G")
- assert(!G.inheritanceDiagram.isDefined)
-
- // trait E
- val E = base._class("E")
- val EDiag = E.inheritanceDiagram.get
-
- // there must be a single this node
- assert(EDiag.nodes.filter(_.isThisNode).length == 1)
-
- // 1. check class E diagram
- val (incoming, outgoing) = EDiag.edges.partition(!_._1.isThisNode)
- assert(incoming.length == 2) // F and G
- assert(outgoing.head._2.length == 3) // B, C and T
-
- val (outgoingSuperclass, outgoingImplicit) = outgoing.head._2.partition(_.isNormalNode)
- assert(outgoingSuperclass.length == 2) // B and C
- assert(outgoingImplicit.length == 1) // T
-
- val (incomingSubclass, incomingImplicit) = incoming.partition(_._1.isNormalNode)
- assert(incomingSubclass.length == 2) // F and G
- assert(incomingImplicit.length == 0)
-
- assert(EDiag.nodes.length == 6) // E, B and C, F and G and the implicit conversion to T
- }
-} \ No newline at end of file
diff --git a/test/scaladoc/run/implicits-ambiguating.check b/test/scaladoc/run/implicits-ambiguating.check
deleted file mode 100644
index 619c56180b..0000000000
--- a/test/scaladoc/run/implicits-ambiguating.check
+++ /dev/null
@@ -1 +0,0 @@
-Done.
diff --git a/test/scaladoc/run/implicits-ambiguating.scala b/test/scaladoc/run/implicits-ambiguating.scala
deleted file mode 100644
index 19e0f72b7b..0000000000
--- a/test/scaladoc/run/implicits-ambiguating.scala
+++ /dev/null
@@ -1,111 +0,0 @@
-import scala.tools.nsc.doc.model._
-import scala.tools.partest.ScaladocModelTest
-
-object Test extends ScaladocModelTest {
-
- // test a file instead of a piece of code
- override def resourceFile = "implicits-ambiguating-res.scala"
-
- // start implicits
- def scaladocSettings = "-implicits"
-
- def testModel(root: Package) = {
- // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
- import access._
-
- // SEE THE test/resources/implicits-chaining-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
- val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._object("ambiguating")
- var conv1: ImplicitConversion = null
- var conv2: ImplicitConversion = null
-
-//// class A ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- val A = base._class("A")
-
- conv1 = A._conversion(base._object("A").qualifiedName + ".AtoX")
- conv2 = A._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv1.members.length == 11)
- assert(conv2.members.length == 11)
- assert(conv1.constraints.length == 0)
- assert(conv2.constraints.length == 0)
-
- /** - conv1-5 should be ambiguous
- * - conv6-7 should not be ambiguous
- * - conv8 should be ambiguous
- * - conv9 should be ambiguous
- * - conv10 and conv11 should not be ambiguous */
- def check1to9(cls: String): Unit = {
- for (conv <- (1 to 5).map("conv" + _)) {
- assert(conv1._member(conv).byConversion.get.isAmbiguous, cls + " - AtoX." + conv + " is ambiguous")
- assert(conv2._member(conv).byConversion.get.isAmbiguous, cls + " - AtoZ." + conv + " is ambiguous")
- }
- for (conv <- (6 to 7).map("conv" + _)) {
- assert(!conv1._member(conv).byConversion.get.isAmbiguous, cls + " - AtoX." + conv + " is not ambiguous")
- assert(!conv2._member(conv).byConversion.get.isAmbiguous, cls + " - AtoZ." + conv + " is not ambiguous")
- }
- assert(conv1._member("conv8").byConversion.get.isAmbiguous, cls + " - AtoX.conv8 is ambiguous")
- assert(conv2._member("conv8").byConversion.get.isAmbiguous, cls + " - AtoZ.conv8 is ambiguous")
- assert(conv1._member("conv9").byConversion.get.isAmbiguous, cls + " - AtoX.conv9 is ambiguous")
- assert(conv2._member("conv9").byConversion.get.isAmbiguous, cls + " - AtoZ.conv9 is ambiguous")
- }
- check1to9("A")
- assert(!conv1._member("conv10").byConversion.get.isAmbiguous, "A - AtoX.conv10 is not ambiguous")
- assert(!conv2._member("conv10").byConversion.get.isAmbiguous, "A - AtoZ.conv10 is not ambiguous")
- assert(!conv1._member("conv11").byConversion.get.isAmbiguous, "A - AtoX.conv11 is not ambiguous")
- assert(!conv2._member("conv11").byConversion.get.isAmbiguous, "A - AtoZ.conv11 is not ambiguous")
-
-//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- val B = base._class("B")
-
- conv1 = B._conversion(base._object("A").qualifiedName + ".AtoX")
- conv2 = B._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv1.members.length == 11)
- assert(conv2.members.length == 11)
- assert(conv1.constraints.length == 0)
- assert(conv2.constraints.length == 0)
-
- /** conv1-9 should be the same, conv10 should be ambiguous, conv11 should be okay */
- check1to9("B")
- assert(conv1._member("conv10").byConversion.get.isAmbiguous, "B - AtoX.conv10 is ambiguous")
- assert(conv2._member("conv10").byConversion.get.isAmbiguous, "B - AtoZ.conv10 is ambiguous")
- assert(!conv1._member("conv11").byConversion.get.isAmbiguous, "B - AtoX.conv11 is not ambiguous")
- assert(!conv2._member("conv11").byConversion.get.isAmbiguous, "B - AtoZ.conv11 is not ambiguous")
-
-//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- val C = base._class("C")
-
- conv1 = C._conversion(base._object("A").qualifiedName + ".AtoX")
- conv2 = C._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv1.members.length == 11)
- assert(conv2.members.length == 11)
- assert(conv1.constraints.length == 0)
- assert(conv2.constraints.length == 0)
-
- /** conv1-9 should be the same, conv10 and conv11 should not be ambiguous */
- check1to9("C")
- assert(!conv1._member("conv10").byConversion.get.isAmbiguous, "C - AtoX.conv10 is not ambiguous")
- assert(!conv2._member("conv10").byConversion.get.isAmbiguous, "C - AtoZ.conv10 is not ambiguous")
- assert(!conv1._member("conv11").byConversion.get.isAmbiguous, "C - AtoX.conv11 is not ambiguous")
- assert(!conv2._member("conv11").byConversion.get.isAmbiguous, "C - AtoZ.conv11 is not ambiguous")
-
-//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
-
- val D = base._class("D")
-
- conv1 = D._conversion(base._object("A").qualifiedName + ".AtoX")
- conv2 = D._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv1.members.length == 11)
- assert(conv2.members.length == 11)
- assert(conv1.constraints.length == 0)
- assert(conv2.constraints.length == 0)
-
- /** conv1-9 should be the same, conv10 should not be ambiguous while conv11 should be ambiguous */
- check1to9("D")
- assert(!conv1._member("conv10").byConversion.get.isAmbiguous, "D - AtoX.conv10 is not ambiguous")
- assert(!conv2._member("conv10").byConversion.get.isAmbiguous, "D - AtoZ.conv10 is not ambiguous")
- assert(conv1._member("conv11").byConversion.get.isAmbiguous, "D - AtoX.conv11 is ambiguous")
- assert(conv2._member("conv11").byConversion.get.isAmbiguous, "D - AtoZ.conv11 is ambiguous")
- }
-} \ No newline at end of file
diff --git a/test/scaladoc/run/implicits-base.scala b/test/scaladoc/run/implicits-base.scala
index ce2d025511..06d017ed70 100644
--- a/test/scaladoc/run/implicits-base.scala
+++ b/test/scaladoc/run/implicits-base.scala
@@ -22,12 +22,8 @@ object Test extends ScaladocModelTest {
val A = base._class("A")
- // def convToPimpedA(x: T) // pimpA0: with no constraints, SHADOWED
- conv = A._conversion(A.qualifiedName + ".pimpA0")
- assert(conv.members.length == 1)
- assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
- assert(conv._member("convToPimpedA").resultType.name == "T")
+ // the method pimped on by pimpA0 should be shadowed by the method in class A
+ assert(A._conversions(A.qualifiedName + ".pimpA0").isEmpty)
// def convToNumericA: T // pimpA1: with a constraint that there is x: Numeric[T] implicit in scope
conv = A._conversion(A.qualifiedName + ".pimpA1")
@@ -57,7 +53,6 @@ object Test extends ScaladocModelTest {
conv = A._conversion(A.qualifiedName + ".pimpA5")
assert(conv.members.length == 1)
assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[T]]")
// def convToMyNumericA: T // pimpA6: with a constraint that there is x: MyNumeric[T] implicit in scope
@@ -81,16 +76,10 @@ object Test extends ScaladocModelTest {
val B = base._class("B")
// these conversions should not affect B
+ assert(B._conversions(A.qualifiedName + ".pimpA0").isEmpty)
assert(B._conversions(A.qualifiedName + ".pimpA2").isEmpty)
assert(B._conversions(A.qualifiedName + ".pimpA4").isEmpty)
- // def convToPimpedA(x: Double) // pimpA0: no constraints, SHADOWED
- conv = B._conversion(A.qualifiedName + ".pimpA0")
- assert(conv.members.length == 1)
- assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
- assert(conv._member("convToPimpedA").resultType.name == "Double")
-
// def convToNumericA: Double // pimpA1: no constraintsd
conv = B._conversion(A.qualifiedName + ".pimpA1")
assert(conv.members.length == 1)
@@ -107,7 +96,6 @@ object Test extends ScaladocModelTest {
conv = B._conversion(A.qualifiedName + ".pimpA5")
assert(conv.members.length == 1)
assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Double]]")
// def convToMyNumericA: Double // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Double] implicit in scope
@@ -131,17 +119,11 @@ object Test extends ScaladocModelTest {
val C = base._class("C")
// these conversions should not affect C
+ assert(C._conversions(A.qualifiedName + ".pimpA0").isEmpty)
assert(C._conversions(A.qualifiedName + ".pimpA3").isEmpty)
assert(C._conversions(A.qualifiedName + ".pimpA4").isEmpty)
assert(C._conversions(A.qualifiedName + ".pimpA7").isEmpty)
- // def convToPimpedA(x: Int) // pimpA0: no constraints, SHADOWED
- conv = C._conversion(A.qualifiedName + ".pimpA0")
- assert(conv.members.length == 1)
- assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
- assert(conv._member("convToPimpedA").resultType.name == "Int")
-
// def convToNumericA: Int // pimpA1: no constraints
conv = C._conversion(A.qualifiedName + ".pimpA1")
assert(conv.members.length == 1)
@@ -158,7 +140,6 @@ object Test extends ScaladocModelTest {
conv = C._conversion(A.qualifiedName + ".pimpA5")
assert(conv.members.length == 1)
assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[Int]]")
// def convToMyNumericA: Int // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[Int] implicit in scope
@@ -172,18 +153,12 @@ object Test extends ScaladocModelTest {
val D = base._class("D")
// these conversions should not affect D
+ assert(D._conversions(A.qualifiedName + ".pimpA0").isEmpty)
assert(D._conversions(A.qualifiedName + ".pimpA2").isEmpty)
assert(D._conversions(A.qualifiedName + ".pimpA3").isEmpty)
assert(D._conversions(A.qualifiedName + ".pimpA4").isEmpty)
assert(D._conversions(A.qualifiedName + ".pimpA7").isEmpty)
- // def convToPimpedA(x: String) // pimpA0: no constraints, SHADOWED
- conv = D._conversion(A.qualifiedName + ".pimpA0")
- assert(conv.members.length == 1)
- assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
- assert(conv._member("convToPimpedA").resultType.name == "String")
-
// def convToNumericA: String // pimpA1: (if showAll is set) with a constraint that there is x: Numeric[String] implicit in scope
conv = D._conversion(A.qualifiedName + ".pimpA1")
assert(conv.members.length == 1)
@@ -194,7 +169,6 @@ object Test extends ScaladocModelTest {
conv = D._conversion(A.qualifiedName + ".pimpA5")
assert(conv.members.length == 1)
assert(conv.constraints.length == 0)
- assert(conv._member("convToPimpedA").byConversion.get.isShadowed)
assert(conv._member("convToPimpedA").resultType.name == "Bar[Foo[String]]")
// def convToMyNumericA: String // pimpA6: (if showAll is set) with a constraint that there is x: MyNumeric[String] implicit in scope
diff --git a/test/scaladoc/run/diagrams-base.check b/test/scaladoc/run/implicits-elimination.check
index 619c56180b..619c56180b 100644
--- a/test/scaladoc/run/diagrams-base.check
+++ b/test/scaladoc/run/implicits-elimination.check
diff --git a/test/scaladoc/run/implicits-elimination.scala b/test/scaladoc/run/implicits-elimination.scala
new file mode 100644
index 0000000000..ed37b9cd90
--- /dev/null
+++ b/test/scaladoc/run/implicits-elimination.scala
@@ -0,0 +1,23 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+import language._
+
+object Test extends ScaladocModelTest {
+
+ // test a file instead of a piece of code
+ override def resourceFile = "implicits-elimination-res.scala"
+
+ // start implicits
+ def scaladocSettings = "-implicits"
+
+ def testModel(root: Package) = {
+ // get the quick access implicit defs in scope (_package(s), _class(es), _trait(s), object(s) _method(s), _value(s))
+ import access._
+
+ // SEE THE test/resources/implicits-elimination-res.scala FOR THE EXPLANATION OF WHAT'S CHECKED HERE:
+ val base = root._package("scala")._package("test")._package("scaladoc")._package("implicits")._package("elimination")
+ val A = base._class("A")
+
+ assert(A._conversions(A.qualifiedName + ".toB").isEmpty)
+ }
+}
diff --git a/test/scaladoc/run/implicits-shadowing.scala b/test/scaladoc/run/implicits-shadowing.scala
index f8a016fac9..7835223d21 100644
--- a/test/scaladoc/run/implicits-shadowing.scala
+++ b/test/scaladoc/run/implicits-shadowing.scala
@@ -22,8 +22,12 @@ object Test extends ScaladocModelTest {
val A = base._class("A")
conv = A._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv.members.length == 11)
- assert(conv.members.forall(_.byConversion.get.isShadowed))
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
assert(conv.constraints.length == 0)
//// class B ///////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -31,8 +35,11 @@ object Test extends ScaladocModelTest {
val B = base._class("B")
conv = B._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv.members.length == 11)
- assert(conv.members.forall(_.byConversion.get.isShadowed))
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv11")
assert(conv.constraints.length == 0)
//// class C ///////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -40,8 +47,12 @@ object Test extends ScaladocModelTest {
val C = base._class("C")
conv = C._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv.members.length == 11)
- assert(conv.members.forall(_.byConversion.get.isShadowed))
+ assert(conv.members.length == 5)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
+ conv._member("conv11")
assert(conv.constraints.length == 0)
//// class D ///////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -49,8 +60,11 @@ object Test extends ScaladocModelTest {
val D = base._class("D")
conv = D._conversion(base._object("A").qualifiedName + ".AtoZ")
- assert(conv.members.length == 11)
- assert(conv.members.forall(_.byConversion.get.isShadowed))
+ assert(conv.members.length == 4)
+ conv._member("conv5")
+ conv._member("conv8")
+ conv._member("conv9")
+ conv._member("conv10")
assert(conv.constraints.length == 0)
}
-}
+} \ No newline at end of file
diff --git a/test/scaladoc/scalacheck/CommentFactoryTest.scala b/test/scaladoc/scalacheck/CommentFactoryTest.scala
index b576ba5544..68ca68efdd 100644
--- a/test/scaladoc/scalacheck/CommentFactoryTest.scala
+++ b/test/scaladoc/scalacheck/CommentFactoryTest.scala
@@ -5,12 +5,10 @@ import scala.tools.nsc.Global
import scala.tools.nsc.doc
import scala.tools.nsc.doc.model._
import scala.tools.nsc.doc.model.comment._
-import scala.tools.nsc.doc.model._
-import scala.tools.nsc.doc.model.diagram._
class Factory(val g: Global, val s: doc.Settings)
extends doc.model.ModelFactory(g, s) {
- thisFactory: Factory with ModelFactoryImplicitSupport with DiagramFactory with CommentFactory with doc.model.TreeFactory =>
+ thisFactory: Factory with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory =>
def strip(c: Comment): Option[Inline] = {
c.body match {
@@ -31,7 +29,7 @@ object Test extends Properties("CommentFactory") {
val settings = new doc.Settings((str: String) => {})
val reporter = new scala.tools.nsc.reporters.ConsoleReporter(settings)
val g = new Global(settings, reporter)
- (new Factory(g, settings) with ModelFactoryImplicitSupport with DiagramFactory with CommentFactory with doc.model.TreeFactory)
+ (new Factory(g, settings) with ModelFactoryImplicitSupport with CommentFactory with doc.model.TreeFactory)
}
def parse(src: String, dst: Inline) = {