summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Suereth <Joshua.Suereth@gmail.com>2012-10-11 10:49:03 -0700
committerJosh Suereth <Joshua.Suereth@gmail.com>2012-10-11 10:49:03 -0700
commit553ee0118dbc052bed8c4580376b48cd9cb5d0f9 (patch)
tree4926c23ca47a334a5bba5863d90102ced446389c
parent90c7596c0736d56ff7b8d699bd958d28cb213bdf (diff)
parent2edf78f3a05112961ed6ad56452e9b5dc150fc3c (diff)
downloadscala-553ee0118dbc052bed8c4580376b48cd9cb5d0f9.tar.gz
scala-553ee0118dbc052bed8c4580376b48cd9cb5d0f9.tar.bz2
scala-553ee0118dbc052bed8c4580376b48cd9cb5d0f9.zip
Merge pull request #1491 from VladUreche/topic/scaladoc2
Scaladoc bugfixes for reflection
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala20
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala41
-rw-r--r--test/scaladoc/resources/SI-6509.scala24
-rw-r--r--test/scaladoc/resources/SI-6511.scala24
-rw-r--r--test/scaladoc/resources/links.scala14
-rw-r--r--test/scaladoc/run/SI-6509.check1
-rw-r--r--test/scaladoc/run/SI-6509.scala30
-rw-r--r--test/scaladoc/run/SI-6511.check1
-rw-r--r--test/scaladoc/run/SI-6511.scala22
-rw-r--r--test/scaladoc/run/groups.scala94
-rw-r--r--test/scaladoc/run/links.scala7
12 files changed, 208 insertions, 72 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/DocFactory.scala b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
index cd0c242f22..02b69034ef 100644
--- a/src/compiler/scala/tools/nsc/doc/DocFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocFactory.scala
@@ -86,7 +86,7 @@ class DocFactory(val reporter: Reporter, val settings: doc.Settings) { processor
with model.comment.CommentFactory
with model.TreeFactory
with model.MemberLookup {
- override def templateShouldDocument(sym: compiler.Symbol, inTpl: TemplateImpl) =
+ override def templateShouldDocument(sym: compiler.Symbol, inTpl: DocTemplateImpl) =
extraTemplatesToDocument(sym) || super.templateShouldDocument(sym, inTpl)
}
)
diff --git a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
index 7ab73cceff..1c783a7d2c 100644
--- a/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/MemberLookup.scala
@@ -120,19 +120,17 @@ trait MemberLookup {
private object OnlyTerm extends SearchStrategy
private def lookupInRootPackage(pos: Position, members: List[String]) =
- if (members.length == 1)
- lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage)
- else
- lookupInTemplate(pos, members, RootPackage)
+ lookupInTemplate(pos, members, EmptyPackage) ::: lookupInTemplate(pos, members, RootPackage)
private def createLinks(syms: List[(Symbol, Symbol)]): List[LinkTo] =
syms.flatMap { case (sym, owner) =>
- if (sym.isClass || sym.isModule || sym.isTrait || sym.isPackage)
- findTemplateMaybe(sym) map (LinkToTpl(_))
- else
- findTemplateMaybe(owner) flatMap { inTpl =>
- inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl))
- }
+ findTemplateMaybe(sym) match {
+ case Some(tpl) => LinkToTpl(tpl) :: Nil
+ case None =>
+ findTemplateMaybe(owner) flatMap { inTpl =>
+ inTpl.members find (_.asInstanceOf[EntityImpl].sym == sym) map (LinkToMember(_, inTpl))
+ }
+ }
}
private def lookupInTemplate(pos: Position, members: List[String], container: Symbol): List[(Symbol, Symbol)] = {
@@ -153,7 +151,7 @@ trait MemberLookup {
case tplName::rest =>
def completeSearch(syms: List[Symbol]) =
- syms filter {sym => sym.isPackage || sym.isClass || sym.isModule} flatMap (lookupInTemplate(pos, rest, _))
+ syms flatMap (lookupInTemplate(pos, rest, _))
completeSearch(lookupInTemplate(pos, tplName, container, OnlyTerm)) match {
case Nil => completeSearch(lookupInTemplate(pos, tplName, container, OnlyType))
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 48624ec28f..73b4341e95 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -31,6 +31,12 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
import definitions.{ ObjectClass, NothingClass, AnyClass, AnyValClass, AnyRefClass }
import rootMirror.{ RootPackage, RootClass, EmptyPackage }
+ // Defaults for member grouping, that may be overridden by the template
+ val defaultGroup = "Ungrouped"
+ val defaultGroupName = "Ungrouped"
+ val defaultGroupDesc = None
+ val defaultGroupPriority = 1000
+
def templatesCount = docTemplatesCache.count(_._2.isDocTemplate) - droppedPackages.size
private var _modelFinished = false
@@ -121,7 +127,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
if (inTpl != null) thisFactory.comment(sym, thisTpl, inTpl) else None
}
- def group = if (comment.isDefined) comment.get.group.getOrElse("No Group") else "No Group"
+ def group = if (comment.isDefined) comment.get.group.getOrElse(defaultGroup) else defaultGroup
override def inTemplate = inTpl
override def toRoot: List[MemberImpl] = this :: inTpl.toRoot
def inDefinitionTemplates = this match {
@@ -286,7 +292,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
val tps = (this match {
case a: AliasType => sym.tpe.dealias.parents
case a: AbstractType => sym.info.bounds match {
- case TypeBounds(lo, hi) => List(hi)
+ case TypeBounds(lo, RefinedType(parents, decls)) => parents
+ case TypeBounds(lo, hi) => hi :: Nil
case _ => Nil
}
case _ => sym.tpe.parents
@@ -493,16 +500,21 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
if (entity != default) return entity
}
// query linearization
- for (tpl <- linearizationTemplates.collect{ case dtpl: DocTemplateImpl if dtpl!=this => dtpl}) {
- val entity = tpl.groupSearch(extractor, default)
- if (entity != default) return entity
- }
- default
+ if (!sym.isPackage)
+ for (tpl <- linearizationTemplates.collect{ case dtpl: DocTemplateImpl if dtpl!=this => dtpl}) {
+ val entity = tpl.groupSearch(extractor, default)
+ if (entity != default) return entity
+ }
+ // query inTpl, going up the ownerChain
+ if (inTpl != null)
+ inTpl.groupSearch(extractor, default)
+ else
+ default
}
- def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group), None)
- def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group) match { case Some(prio) => prio; case _ => 0 }, 0)
- def groupName(group: String): String = groupSearch(_.groupNames.get(group) match { case Some(name) => name; case _ => group }, group)
+ def groupDescription(group: String): Option[Body] = groupSearch(_.groupDesc.get(group), if (group == defaultGroup) defaultGroupDesc else None)
+ def groupPriority(group: String): Int = groupSearch(_.groupPrio.get(group) match { case Some(prio) => prio; case _ => 0 }, if (group == defaultGroup) defaultGroupPriority else 0)
+ def groupName(group: String): String = groupSearch(_.groupNames.get(group) match { case Some(name) => name; case _ => group }, if (group == defaultGroup) defaultGroupName else group)
}
abstract class PackageImpl(sym: Symbol, inTpl: PackageImpl) extends DocTemplateImpl(sym, inTpl) with Package {
@@ -736,7 +748,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
else {
// no class inheritance at this point
- assert(inOriginalOwner(bSym, inTpl) || bSym.isAbstractType || bSym.isAliasType, bSym + " in " + inTpl)
+ assert(inOriginalOwner(bSym, inTpl), bSym + " in " + inTpl)
Some(createDocTemplate(bSym, inTpl))
}
}
@@ -833,7 +845,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
Some(new MemberTemplateImpl(bSym, inTpl) with AliasImpl with AliasType {
override def isAliasType = true
})
- else if (!modelFinished && (bSym.isPackage || bSym.isAliasType || bSym.isAbstractType || templateShouldDocument(bSym, inTpl)))
+ else if (!modelFinished && (bSym.isPackage || templateShouldDocument(bSym, inTpl)))
modelCreation.createTemplate(bSym, inTpl)
else
None
@@ -1040,8 +1052,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def inOriginalOwner(aSym: Symbol, inTpl: TemplateImpl): Boolean =
normalizeTemplate(aSym.owner) == normalizeTemplate(inTpl.sym)
- def templateShouldDocument(aSym: Symbol, inTpl: TemplateImpl): Boolean =
- (aSym.isTrait || aSym.isClass || aSym.isModule) &&
+ def templateShouldDocument(aSym: Symbol, inTpl: DocTemplateImpl): Boolean =
+ (aSym.isTrait || aSym.isClass || aSym.isModule || typeShouldDocument(aSym, inTpl)) &&
localShouldDocument(aSym) &&
!isEmptyJavaObject(aSym) &&
// either it's inside the original owner or we can document it later:
@@ -1081,6 +1093,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
// whether or not to create a page for an {abstract,alias} type
def typeShouldDocument(bSym: Symbol, inTpl: DocTemplateImpl) =
(settings.docExpandAllTypes.value && (bSym.sourceFile != null)) ||
+ (bSym.isAliasType || bSym.isAbstractType) &&
{ val rawComment = global.expandedDocComment(bSym, inTpl.sym)
rawComment.contains("@template") || rawComment.contains("@documentable") }
diff --git a/test/scaladoc/resources/SI-6509.scala b/test/scaladoc/resources/SI-6509.scala
new file mode 100644
index 0000000000..540ba243bd
--- /dev/null
+++ b/test/scaladoc/resources/SI-6509.scala
@@ -0,0 +1,24 @@
+package test.scaladoc.template.owners
+
+trait X {
+ /** @template */
+ type Symbol >: Null <: SymbolApi
+
+ /** @template */
+ type TypeSymbol >: Null <: Symbol with TypeSymbolApi
+
+ /** @template */
+ type TermSymbol >: Null <: Symbol with TermSymbolApi
+
+ /** @template */
+ type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
+
+ trait SymbolApi { this: Symbol => def x: Int}
+ trait TermSymbolApi extends SymbolApi { this: TermSymbol => def y: Int}
+ trait TypeSymbolApi extends SymbolApi { this: TypeSymbol => def z: Int}
+ trait MethodSymbolApi extends TermSymbolApi { this: MethodSymbol => def t: Int }
+}
+
+trait Y extends X
+trait Z extends Y
+trait T extends Z
diff --git a/test/scaladoc/resources/SI-6511.scala b/test/scaladoc/resources/SI-6511.scala
new file mode 100644
index 0000000000..1f153caeb0
--- /dev/null
+++ b/test/scaladoc/resources/SI-6511.scala
@@ -0,0 +1,24 @@
+package test.scaladoc.template.diagrams
+
+/** @contentDiagram hideNodes "*Api" */
+trait X {
+ /** @template */
+ type Symbol >: Null <: SymbolApi
+
+ /** @template */
+ type TypeSymbol >: Null <: Symbol with TypeSymbolApi
+
+ /** @template */
+ type TermSymbol >: Null <: Symbol with TermSymbolApi
+
+ /** @template */
+ type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
+
+ trait SymbolApi { this: Symbol => def x: Int}
+ trait TermSymbolApi extends SymbolApi { this: TermSymbol => def y: Int}
+ trait TypeSymbolApi extends SymbolApi { this: TypeSymbol => def z: Int}
+ trait MethodSymbolApi extends TermSymbolApi { this: MethodSymbol => def t: Int }
+}
+
+/** @contentDiagram hideNodes "*Api" */
+trait Y extends X
diff --git a/test/scaladoc/resources/links.scala b/test/scaladoc/resources/links.scala
index 09a52a4334..bd69665357 100644
--- a/test/scaladoc/resources/links.scala
+++ b/test/scaladoc/resources/links.scala
@@ -3,6 +3,9 @@
// SI-4497 "Links in ScalaDoc - Spec and implementation unsufficient"
// SI-4224 "Wiki-links should support method targets"
// SI-3695 "support non-fully-qualified type links in scaladoc comments"
+// SI-6487 "Scaladoc can't link to inner classes"
+// SI-6495 "Scaladoc won't pick up group name, priority and description from owner chain"
+// SI-6501 "Scaladoc won't link to a @template type T as a template but as a member"
package scala.test.scaladoc.links {
import language.higherKinds
class C
@@ -54,9 +57,18 @@ package scala.test.scaladoc.links {
* - [[localMethod object TEST -> localMethod]] (should use the current template to resolve link instead of inTpl, that's the package)
* - [[#localMethod object TEST -> localMethod]] (should exercise Java-style links to empty members)
* - [[ImOutside class ImOutside (check correct lookup in EmptyPackage)]]
+ * - [[ImOutside.Inner#foo class ImOutside#class Inner#method foo (check correct lookup in EmptyPackage)]]
+ * - [[ImOutside.T class ImOutside#type T (check correct linking to templates)]]
+ * - [[ImOutside.T#foo class ImOutside#type T#method foo (check correct interaction between @template and links)]]
*/
object TEST {
def localMethod = 3
}
}
-class ImOutside \ No newline at end of file
+trait ImOutside {
+ /** @template */
+ type T <: Inner
+ class Inner {
+ def foo: Any
+ }
+}
diff --git a/test/scaladoc/run/SI-6509.check b/test/scaladoc/run/SI-6509.check
new file mode 100644
index 0000000000..3925a0d464
--- /dev/null
+++ b/test/scaladoc/run/SI-6509.check
@@ -0,0 +1 @@
+Done. \ No newline at end of file
diff --git a/test/scaladoc/run/SI-6509.scala b/test/scaladoc/run/SI-6509.scala
new file mode 100644
index 0000000000..3857949d14
--- /dev/null
+++ b/test/scaladoc/run/SI-6509.scala
@@ -0,0 +1,30 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def resourceFile: String = "SI-6509.scala"
+
+ // no need for special settings
+ def scaladocSettings = ""
+
+ 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 main = rootPackage._package("test")._package("scaladoc")._package("template")._package("owners")
+ val X = main._trait("X")
+ val Y = main._trait("Y")
+ val Z = main._trait("Z")
+ val T = main._trait("T")
+
+ def checkTemplateOwner(d: DocTemplateEntity) =
+ for (mbr <- List("Symbol", "TypeSymbol", "TermSymbol", "MethodSymbol")) {
+ val tpl = d._absTypeTpl(mbr).inTemplate
+ assert(tpl == X, tpl + " == X")
+ }
+
+ for (tpl <- List(X, Y, Z, T))
+ checkTemplateOwner(tpl)
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/run/SI-6511.check b/test/scaladoc/run/SI-6511.check
new file mode 100644
index 0000000000..3925a0d464
--- /dev/null
+++ b/test/scaladoc/run/SI-6511.check
@@ -0,0 +1 @@
+Done. \ No newline at end of file
diff --git a/test/scaladoc/run/SI-6511.scala b/test/scaladoc/run/SI-6511.scala
new file mode 100644
index 0000000000..cc950a98d6
--- /dev/null
+++ b/test/scaladoc/run/SI-6511.scala
@@ -0,0 +1,22 @@
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def resourceFile: String = "SI-6511.scala"
+
+ // no need for special settings
+ def scaladocSettings = "-diagrams"
+
+ 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 main = rootPackage._package("test")._package("scaladoc")._package("template")._package("diagrams")
+ val X = main._trait("X")
+ val Y = main._trait("Y")
+
+ testDiagram(X, X.contentDiagram, nodes = 4, edges = 3)
+ testDiagram(Y, Y.contentDiagram, nodes = 4, edges = 3)
+ }
+} \ No newline at end of file
diff --git a/test/scaladoc/run/groups.scala b/test/scaladoc/run/groups.scala
index 05324c2ec9..c9e4a8679b 100644
--- a/test/scaladoc/run/groups.scala
+++ b/test/scaladoc/run/groups.scala
@@ -4,49 +4,54 @@ import scala.tools.partest.ScaladocModelTest
object Test extends ScaladocModelTest {
override def code = """
- package test.scaladoc.groups {
-
- /**
- * The trait A
- * @groupdesc A Group A is the group that contains functions starting with f
- * For example:
- * {{{
- * this is an example
- * }}}
- * @groupdesc B Group B is the group that contains functions starting with b
- * @groupname B Group B has a nice new name and a high priority
- * @groupprio B -10
- * @group Traits
- * @note This is a note
- */
- trait A {
- /** foo description
- * @group A */
- def foo = 1
-
- /** bar description
- * @group B */
- def bar = 2
- }
-
- /** The trait B
- * @group Traits
- * @groupdesc C Group C is introduced by B
- */
- trait B {
- /** baz descriptopn
- * @group C */
- def baz = 3
- }
-
- /** The class C which inherits from both A and B
- * @group Classes
- * @groupdesc B Look ma, I'm overriding group descriptions!!!
- * @groupname B And names
- */
- class C extends A with B {
- /** Oh noes, I lost my group -- or did I?!? */
- override def baz = 4
+ package test.scaladoc {
+
+ /** @groupname Z From owner chain */
+ package object `groups`
+
+ package groups {
+ /**
+ * The trait A
+ * @groupdesc A Group A is the group that contains functions starting with f
+ * For example:
+ * {{{
+ * this is an example
+ * }}}
+ * @groupdesc B Group B is the group that contains functions starting with b
+ * @groupname B Group B has a nice new name and a high priority
+ * @groupprio B -10
+ * @group Traits
+ * @note This is a note
+ */
+ trait A {
+ /** foo description
+ * @group A */
+ def foo = 1
+
+ /** bar description
+ * @group B */
+ def bar = 2
+ }
+
+ /** The trait B
+ * @group Traits
+ * @groupdesc C Group C is introduced by B
+ */
+ trait B {
+ /** baz descriptopn
+ * @group C */
+ def baz = 3
+ }
+
+ /** The class C which inherits from both A and B
+ * @group Classes
+ * @groupdesc B Look ma, I'm overriding group descriptions!!!
+ * @groupname B And names
+ */
+ class C extends A with B {
+ /** Oh noes, I lost my group -- or did I?!? */
+ override def baz = 4
+ }
}
}
"""
@@ -101,10 +106,12 @@ object Test extends ScaladocModelTest {
checkGroupDesc(A, "B", "Group B is the group that contains functions starting with b")
checkGroupName(A, "B", "Group B has a nice new name and a high priority")
checkGroupPrio(A, "B", -10)
+ checkGroupName(A, "Z", "From owner chain")
checkGroupDesc(B, "C", "Group C is introduced by B")
checkGroupName(B, "C", "C")
checkGroupPrio(B, "C", 0)
+ checkGroupName(B, "Z", "From owner chain")
checkGroupDesc(C, "A", "Group A is the group that contains functions starting with f")
checkGroupName(C, "A", "A")
@@ -115,5 +122,6 @@ object Test extends ScaladocModelTest {
checkGroupDesc(C, "C", "Group C is introduced by B")
checkGroupName(C, "C", "C")
checkGroupPrio(C, "C", 0)
+ checkGroupName(C, "Z", "From owner chain")
}
} \ No newline at end of file
diff --git a/test/scaladoc/run/links.scala b/test/scaladoc/run/links.scala
index de359539cf..0c67857e1c 100644
--- a/test/scaladoc/run/links.scala
+++ b/test/scaladoc/run/links.scala
@@ -5,6 +5,9 @@ import scala.tools.partest.ScaladocModelTest
// SI-4497 "Links in ScalaDoc - Spec and implementation unsufficient"
// SI-4224 "Wiki-links should support method targets"
// SI-3695 "support non-fully-qualified type links in scaladoc comments"
+// SI-6487 "Scaladoc can't link to inner classes"
+// SI-6495 "Scaladoc won't pick up group name, priority and description from owner chain"
+// SI-6501 "Scaladoc won't link to a @template type T as a template but as a member"
object Test extends ScaladocModelTest {
override def resourceFile = "links.scala"
@@ -22,7 +25,7 @@ object Test extends ScaladocModelTest {
val memberLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToMember])
val templateLinks = countLinks(TEST.comment.get, _.link.isInstanceOf[LinkToTpl])
- assert(memberLinks == 15, memberLinks + " == 15 (the member links in object TEST)")
- assert(templateLinks == 5, templateLinks + " == 5 (the template links in object TEST)")
+ assert(memberLinks == 17, memberLinks + " == 17 (the member links in object TEST)")
+ assert(templateLinks == 6, templateLinks + " == 6 (the template links in object TEST)")
}
} \ No newline at end of file