summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools
diff options
context:
space:
mode:
authorVlad Ureche <vlad.ureche@gmail.com>2012-07-16 13:32:05 +0200
committerVlad Ureche <vlad.ureche@gmail.com>2012-07-16 23:41:44 +0200
commit17f745d33cbda90aa552c95bc5456ed793180333 (patch)
tree7651dbbd8ad9cd36267ddcd7168406d8375e5d32 /src/compiler/scala/tools
parent376403266c699190882ef7c9f2a7c65c86a23a3d (diff)
downloadscala-17f745d33cbda90aa552c95bc5456ed793180333.tar.gz
scala-17f745d33cbda90aa552c95bc5456ed793180333.tar.bz2
scala-17f745d33cbda90aa552c95bc5456ed793180333.zip
Scaladoc: Refactoring the entities
for SI-5784. This commit has been checked with tools/scaladoc-compare and the only difference is that the containing entities in the index are not duplicate anymore, which solves yet another bug we did not know about. :)
Diffstat (limited to 'src/compiler/scala/tools')
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/Page.scala22
-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.scala16
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/Entity.scala55
-rwxr-xr-xsrc/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala7
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala172
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala2
8 files changed, 140 insertions, 138 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/Page.scala b/src/compiler/scala/tools/nsc/doc/html/Page.scala
index 08df26e745..d30ca5dc08 100644
--- a/src/compiler/scala/tools/nsc/doc/html/Page.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/Page.scala
@@ -48,13 +48,21 @@ abstract class Page {
* @param generator The generator that is writing this page. */
def writeFor(site: HtmlFactory): Unit
- def docEntityKindToString(ety: TemplateEntity) =
- if (ety.isTrait) "trait"
- else if (ety.isCaseClass) "case class"
- else if (ety.isClass) "class"
- else if (ety.isObject) "object"
- else if (ety.isPackage) "package"
- else "class" // FIXME: an entity *should* fall into one of the above categories, but AnyRef is somehow not
+ def kindToString(mbr: MemberEntity) =
+ mbr match {
+ case c: Class => if (c.isCaseClass) "case class" else "class"
+ case _: Trait => "trait"
+ case _: Package => "package"
+ case _: Object => "object"
+ case _: AbstractType => "type"
+ case _: AliasType => "type"
+ case _: Constructor => "new"
+ case v: Def => "def"
+ case v: Val if (v.isLazyVal) => "lazy val"
+ case v: Val if (v.isVal) => "val"
+ case v: Val if (v.isVar) => "var"
+ case _ => sys.error("Cannot create kind for: " + mbr + " of class " + mbr.getClass)
+ }
def templateToPath(tpl: TemplateEntity): List[String] = {
def doName(tpl: TemplateEntity): String =
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 81fbed884d..b15d602b57 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Index.scala
@@ -68,7 +68,7 @@ class Index(universe: doc.Universe, val index: doc.Index) extends HtmlPage {
val placeholderSeq: NodeSeq = <div class="placeholder"></div>
def createLink(entity: DocTemplateEntity, includePlaceholder: Boolean, includeText: Boolean) = {
- val entityType = docEntityKindToString(entity)
+ val entityType = kindToString(entity)
val linkContent = (
{ if (includePlaceholder) placeholderSeq else NodeSeq.Empty }
++
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 e1ab479f9d..a37dd3fb8b 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala
@@ -27,7 +27,7 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page {
val ary = merged.keys.toList.sortBy(_.toLowerCase).map(key => {
val pairs = merged(key).map(
- t => docEntityKindToString(t) -> relativeLinkTo(t)
+ t => kindToString(t) -> relativeLinkTo(t)
) :+ ("name" -> key)
JSONObject(scala.collection.immutable.Map(pairs : _*))
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 417bfcfb96..d691692920 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -67,7 +67,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
nonDeprValueMembers partition (!_.isShadowedOrAmbiguousImplicit)
val typeMembers =
- tpl.abstractTypes ++ tpl.aliasTypes ++ tpl.templates.filter(x => x.isTrait || x.isClass) sorted
+ tpl.abstractTypes ++ tpl.aliasTypes ++ tpl.templates.filter(x => x.isTrait || x.isClass) sorted (implicitly[Ordering[MemberEntity]])
val constructors = (tpl match {
case cls: Class => (cls.constructors: List[MemberEntity]).sorted
@@ -615,20 +615,6 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp
memberComment ++ paramComments ++ attributesBlock ++ linearization ++ subclasses ++ typeHierarchy ++ contentHierarchy
}
- def kindToString(mbr: MemberEntity): String = {
- mbr match {
- case tpl: DocTemplateEntity => docEntityKindToString(tpl)
- case tpl: NoDocTemplateMemberEntity => docEntityKindToString(tpl)
- case ctor: Constructor => "new"
- case tme: MemberEntity =>
- ( if (tme.isDef) "def"
- else if (tme.isVal) "val"
- else if (tme.isLazyVal) "lazy val"
- else if (tme.isVar) "var"
- else "type")
- }
- }
-
def boundsToHtml(hi: Option[TypeEntity], lo: Option[TypeEntity], hasLinks: Boolean): NodeSeq = {
def bound0(bnd: Option[TypeEntity], pre: String): NodeSeq = bnd match {
case None => NodeSeq.Empty
diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
index d9758c6f2f..620aa4253f 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala
@@ -185,7 +185,7 @@ trait MemberEntity extends Entity {
/** 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
+ def useCaseOf: Option[MemberEntity]
/** If this member originates from an implicit conversion, we set the implicit information to the correct origin */
def byConversion: Option[ImplicitConversion]
@@ -225,22 +225,27 @@ trait HigherKinded {
/** A template (class, trait, object or package) which is referenced in the universe, but for which no further
* documentation is available. Only templates for which a source file is given are documented by Scaladoc. */
trait NoDocTemplate extends TemplateEntity {
- def kind = ""
- //def kind = "(not documented) template"
+ def kind =
+ if (isClass) "class"
+ else if (isTrait) "trait"
+ else if (isObject) "object"
+ else ""
}
/** An inherited template that was not documented in its original owner - example:
* in classpath: trait T { class C } -- T (and implicitly C) are not documented
- * in the source: trait U extends T -- C appears in U as a NoDocTemplateMemberImpl
+ * in the source: trait U extends T -- C appears in U as a MemberTemplateImpl
* -- that is, U has a member for it but C doesn't get its own page */
-trait NoDocTemplateMemberEntity extends TemplateEntity with MemberEntity {
- def kind = ""
- //def kind = "(not documented) member template"
+trait MemberTemplateEntity extends TemplateEntity with MemberEntity with HigherKinded {
+
+ /** The value parameters of this case class, or an empty list if this class is not a case class. As case class value
+ * parameters cannot be curried, the outer list has exactly one element. */
+ def valueParams: List[List[ValueParam]]
}
/** A template (class, trait, object or package) for which documentation is available. Only templates for which
* a source file is given are documented by Scaladoc. */
-trait DocTemplateEntity extends TemplateEntity with MemberEntity {
+trait DocTemplateEntity extends MemberTemplateEntity {
/** The list of templates such that each is a member of the template that follows it; the first template is always
* this template, the last the root package entity. */
@@ -295,6 +300,12 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
/** All type aliases that are members of this template. */
def aliasTypes: List[AliasType]
+ /** The primary constructor of this class, if it has been defined. */
+ def primaryConstructor: Option[Constructor]
+
+ /** All constructors of this class, including the primary constructor. */
+ def constructors: List[Constructor]
+
/** The companion of this template, or none. If a class and an object are defined as a pair of the same name, the
* other entity of the pair is the companion. */
def companion: Option[DocTemplateEntity]
@@ -319,39 +330,24 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity {
def contentDiagram: Option[Diagram]
}
-
/** A trait template. */
-trait Trait extends DocTemplateEntity with HigherKinded {
+trait Trait extends MemberTemplateEntity {
def kind = "trait"
}
-
/** A class template. */
-trait Class extends Trait with HigherKinded {
-
- /** The primary constructor of this class, if it has been defined. */
- def primaryConstructor: Option[Constructor]
-
- /** All constructors of this class, including the primary constructor. */
- def constructors: List[Constructor]
-
- /** The value parameters of this case class, or an empty list if this class is not a case class. As case class value
- * parameters cannot be curried, the outer list has exactly one element. */
- def valueParams: List[List[ValueParam]]
-
+trait Class extends MemberTemplateEntity {
override def kind = "class"
}
-
/** An object template. */
-trait Object extends DocTemplateEntity {
+trait Object extends MemberTemplateEntity {
def kind = "object"
}
-
/** A package template. A package is in the universe if it is declared as a package object, or if it
* contains at least one template. */
-trait Package extends Object {
+trait Package extends DocTemplateEntity {
/** The package of which this package is a member. */
def inTemplate: Package
@@ -382,7 +378,6 @@ trait NonTemplateMemberEntity extends 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
-
}
@@ -419,7 +414,7 @@ trait Val extends NonTemplateMemberEntity {
/** An abstract type member of a template. */
-trait AbstractType extends NonTemplateMemberEntity with HigherKinded {
+trait AbstractType extends MemberTemplateEntity with HigherKinded {
/** The lower bound for this abstract type, if it has been defined. */
def lo: Option[TypeEntity]
@@ -432,7 +427,7 @@ trait AbstractType extends NonTemplateMemberEntity with HigherKinded {
/** An type alias of a template. */
-trait AliasType extends NonTemplateMemberEntity with HigherKinded {
+trait AliasType extends MemberTemplateEntity with HigherKinded {
/** The type aliased by this type alias. */
def alias: TypeEntity
diff --git a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
index 6392de22ff..f4c96505a7 100755
--- a/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/IndexModelFactory.scala
@@ -36,7 +36,6 @@ object IndexModelFactory {
} + d
this(firstLetter) = letter + (d.name -> members)
}
-
}
//@scala.annotation.tailrec // TODO
@@ -46,11 +45,7 @@ object IndexModelFactory {
case tpl: DocTemplateEntity =>
result.addMember(tpl)
gather(tpl)
- case alias: AliasType =>
- result.addMember(alias)
- case absType: AbstractType =>
- result.addMember(absType)
- case non: NonTemplateMemberEntity if !non.isConstructor =>
+ case non: MemberEntity if !non.isConstructor =>
result.addMember(non)
case x @ _ =>
}
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
index 2fec832db8..fc5fde3239 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala
@@ -110,26 +110,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this))
}
- abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
+ abstract class MemberImpl(sym: Symbol, inTpl: DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity {
lazy val comment = {
- val inRealTpl =
- /* Variable precendence order for implicitly added members: Take the variable defifinitions from ...
- * 1. the target of the implicit conversion
- * 2. the definition template (owner)
- * 3. the current template
- */
- if (implConv != null) findTemplateMaybe(implConv.toType.typeSymbol) match {
- case Some(d) if d != makeRootPackage => d //in case of NoSymbol, it will give us the root package
- case _ => findTemplateMaybe(sym.owner) match {
- case Some(d) if d != makeRootPackage => d //in case of NoSymbol, it will give us the root package
- case _ => inTpl
- }
- } else inTpl
+ // If the current tpl is a DocTemplate, we consider itself as the root for resolving link targets (instead of the
+ // package the class is in) -- so people can refer to methods directly [[foo]], instead of using [[MyClass.foo]]
+ // in the doc comment of MyClass
val thisTpl = this match {
case d: DocTemplateImpl => Some(d)
case _ => None
}
- if (inRealTpl != null) thisFactory.comment(sym, thisTpl, inRealTpl) else None
+ if (inTpl != null) thisFactory.comment(sym, thisTpl, inTpl) else None
}
override def inTemplate = inTpl
override def toRoot: List[MemberImpl] = this :: inTpl.toRoot
@@ -168,7 +158,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
* }}}
* the type the method returns is TraversableOps, which has all-abstract symbols. But in reality, it couldn't have
* any abstract terms, otherwise it would fail compilation. So we reset the DEFERRED flag. */
- if (!sym.isTrait && (sym hasFlag Flags.DEFERRED) && (implConv eq null)) fgs += Paragraph(Text("abstract"))
+ if (!sym.isTrait && (sym hasFlag Flags.DEFERRED) && (!isImplicitlyInherited)) fgs += Paragraph(Text("abstract"))
if (!sym.isModule && (sym hasFlag Flags.FINAL)) fgs += Paragraph(Text("final"))
fgs.toList
}
@@ -202,7 +192,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.toType memberInfo sym
+ val tpe = if (!isImplicitlyInherited) sym.tpe else byConversion.get.toType memberInfo sym
makeTypeInTemplateContext(resultTpe(tpe), inTemplate, sym)
}
def isDef = false
@@ -214,11 +204,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def isAliasType = false
def isAbstractType = false
def isAbstract =
- // for the explanation of implConv == null see comment on flags
- ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (implConv == null)) ||
+ // for the explanation of conversion == null see comment on flags
+ ((!sym.isTrait && ((sym hasFlag Flags.ABSTRACT) || (sym hasFlag Flags.DEFERRED)) && (!isImplicitlyInherited)) ||
sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic
def isTemplate = false
- def byConversion = if (implConv ne null) Some(implConv) else None
lazy val signature = {
def defParams(mbr: Any): String = mbr match {
@@ -245,10 +234,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
(name + tParams(this) + defParams(this) +":"+ resultType.name).replaceAll("\\s","") // no spaces allowed, they break links
}
- def isImplicitlyInherited = { assert(modelFinished); byConversion.isDefined }
- def isShadowedImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isShadowed).getOrElse(false)
- def isAmbiguousImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isAmbiguous).getOrElse(false)
- def isShadowedOrAmbiguousImplicit = isShadowedImplicit || isAmbiguousImplicit
+ // these only apply for NonTemplateMemberEntities
+ def useCaseOf: Option[MemberEntity] = None
+ def byConversion: Option[ImplicitConversionImpl] = None
+ def isImplicitlyInherited = false
+ def isShadowedImplicit = false
+ def isAmbiguousImplicit = false
+ def isShadowedOrAmbiguousImplicit = false
}
/** A template that is not documented at all. The class is instantiated during lookups, to indicate that the class
@@ -263,22 +255,22 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/** An inherited template that was not documented in its original owner - example:
* in classpath: trait T { class C } -- T (and implicitly C) are not documented
- * in the source: trait U extends T -- C appears in U as a NoDocTemplateMemberImpl -- that is, U has a member for it
+ * in the source: trait U extends T -- C appears in U as a MemberTemplateImpl -- that is, U has a member for it
* but C doesn't get its own page
*/
- class NoDocTemplateMemberImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberImpl(sym, null, inTpl) with TemplateImpl with HigherKindedImpl with NoDocTemplateMemberEntity {
- assert(modelFinished)
+ abstract class MemberTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberImpl(sym, inTpl) with TemplateImpl with HigherKindedImpl with MemberTemplateEntity {
// no templates cache for this class, each owner gets its own instance
override def isTemplate = true
def isDocTemplate = false
override def isNoDocMemberTemplate = true
lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "." + name)
+ def valueParams: List[List[ValueParam]] = Nil /** TODO, these are now only computed for DocTemplates */
}
/** The instantiation of `TemplateImpl` triggers the creation of the following entities:
* All ancestors of the template and all non-package members.
*/
- abstract class DocTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberImpl(sym, null, inTpl) with TemplateImpl with HigherKindedImpl with DocTemplateEntity {
+ abstract class DocTemplateImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberTemplateImpl(sym, inTpl) with DocTemplateEntity {
assert(!modelFinished)
assert(!(docTemplatesCache isDefinedAt sym), sym)
docTemplatesCache += (sym -> this)
@@ -386,7 +378,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
// the direct members (methods, values, vars, types and directly contained templates)
var memberSymsEager = memberSyms.filter(!memberSymsLazy.contains(_))
// the members generated by the symbols in memberSymsEager
- val ownMembers = (memberSyms.flatMap(makeMember(_, null, this)))
+ val ownMembers = (memberSyms.flatMap(makeMember(_, None, this)))
// all the members that are documentented PLUS the members inherited by implicit conversions
var members: List[MemberImpl] = ownMembers
@@ -439,8 +431,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
)
override def isTemplate = true
- lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "." + name)
- def isDocTemplate = true
+ override def isDocTemplate = true
def companion = sym.companionSymbol match {
case NoSymbol => None
case comSym if !isEmptyJavaObject(comSym) && (comSym.isClass || comSym.isModule) =>
@@ -451,6 +442,15 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
case _ => None
}
+ def constructors: List[MemberImpl with Constructor] = if (isClass) members collect { case d: Constructor => d } else Nil
+ def primaryConstructor: Option[MemberImpl with Constructor] = if (isClass) constructors find { _.isPrimary } else None
+ override def valueParams =
+ // we don't want params on a class (non case class) signature
+ if (isCaseClass) primaryConstructor match {
+ case Some(const) => const.sym.paramss map (_ map (makeValueParam(_, this)))
+ case None => List()
+ }
+ else List.empty
// These are generated on-demand, make sure you don't call them more than once
def inheritanceDiagram = makeInheritanceDiagram(this)
def contentDiagram = makeContentDiagram(this)
@@ -470,23 +470,49 @@ 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: ImplicitConversionImpl, inTpl: DocTemplateImpl) extends MemberImpl(sym, implConv, inTpl) with NonTemplateMemberEntity {
+ abstract class NonTemplateMemberImpl(sym: Symbol, conversion: Option[ImplicitConversionImpl],
+ override val useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl)
+ extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity {
+ override lazy val comment = {
+ val inRealTpl =
+ /* Variable precendence order for implicitly added members: Take the variable defifinitions from ...
+ * 1. the target of the implicit conversion
+ * 2. the definition template (owner)
+ * 3. the current template
+ */
+ if (conversion.isDefined) findTemplateMaybe(conversion.get.toType.typeSymbol) match {
+ case Some(d) if d != makeRootPackage => d //in case of NoSymbol, it will give us the root package
+ case _ => findTemplateMaybe(sym.owner) match {
+ case Some(d) if d != makeRootPackage => d //in case of NoSymbol, it will give us the root package
+ case _ => inTpl
+ }
+ } else inTpl
+ if (inRealTpl != null) thisFactory.comment(sym, None, inRealTpl) else None
+ }
+
override def qualifiedName = optimize(inTemplate.qualifiedName + "#" + name)
lazy val definitionName = {
// this contrived name is here just to satisfy some older tests -- if you decide to remove it, be my guest, and
// also remove property("package object") from test/scaladoc/scalacheck/HtmlFactoryTest.scala so you don't break
// the test suite...
val packageObject = if (inPackageObject) ".package" else ""
- if (implConv == null) optimize(inDefinitionTemplates.head.qualifiedName + packageObject + "#" + name)
- else optimize(implConv.conversionQualifiedName + packageObject + "#" + name)
+ if (!conversion.isDefined) optimize(inDefinitionTemplates.head.qualifiedName + packageObject + "#" + name)
+ else optimize(conversion.get.conversionQualifiedName + packageObject + "#" + name)
}
- def isUseCase = sym.isSynthetic
def isBridge = sym.isBridge
+ def isUseCase = useCaseOf.isDefined
+ override def byConversion: Option[ImplicitConversionImpl] = conversion
+ override def isImplicitlyInherited = { assert(modelFinished); conversion.isDefined }
+ override def isShadowedImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isShadowed).getOrElse(false)
+ override def isAmbiguousImplicit = isImplicitlyInherited && inTpl.implicitsShadowing.get(this).map(_.isAmbiguous).getOrElse(false)
+ override def isShadowedOrAmbiguousImplicit = isShadowedImplicit || isAmbiguousImplicit
}
- abstract class NonTemplateParamMemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: DocTemplateImpl) extends NonTemplateMemberImpl(sym, implConv, inTpl) {
+ abstract class NonTemplateParamMemberImpl(sym: Symbol, conversion: Option[ImplicitConversionImpl],
+ useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl)
+ extends NonTemplateMemberImpl(sym, conversion, useCaseOf, inTpl) {
def valueParams = {
- val info = if (implConv eq null) sym.info else implConv.toType memberInfo sym
+ val info = if (!isImplicitlyInherited) sym.info else conversion.get.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)
}}
@@ -591,24 +617,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def createDocTemplate(bSym: Symbol, inTpl: DocTemplateImpl): DocTemplateImpl = {
assert(!modelFinished) // only created BEFORE the model is finished
if (bSym.isModule || (bSym.isAliasType && bSym.tpe.typeSymbol.isModule))
- new DocTemplateImpl(bSym, inTpl) with Object
+ new DocTemplateImpl(bSym, inTpl) with Object {}
else if (bSym.isTrait || (bSym.isAliasType && bSym.tpe.typeSymbol.isTrait))
- new DocTemplateImpl(bSym, inTpl) with Trait
+ new DocTemplateImpl(bSym, inTpl) with Trait {}
else if (bSym.isClass || (bSym.isAliasType && bSym.tpe.typeSymbol.isClass))
- new DocTemplateImpl(bSym, inTpl) with Class {
- def valueParams =
- // we don't want params on a class (non case class) signature
- if (isCaseClass) primaryConstructor match {
- case Some(const) => const.sym.paramss map (_ map (makeValueParam(_, this)))
- case None => List()
- }
- else List.empty
- val constructors =
- members collect { case d: Constructor => d }
- def primaryConstructor = constructors find { _.isPrimary }
- }
+ new DocTemplateImpl(bSym, inTpl) with Class {}
else
- sys.error("'" + bSym + "' isn't a class, trait or object thus cannot be built as a documentable template")
+ sys.error("'" + bSym + "' isn't a class, trait or object thus cannot be built as a documentable template.")
}
val bSym = normalizeTemplate(aSym)
@@ -638,7 +653,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
inTpl match {
case inPkg: PackageImpl =>
val pack = new PackageImpl(bSym, inPkg) {}
- if (pack.templates.isEmpty && pack.memberSymsLazy.isEmpty)
+ if (pack.templates.filter(_.isDocTemplate).isEmpty && pack.memberSymsLazy.isEmpty)
droppedPackages += pack
pack
case _ =>
@@ -654,15 +669,22 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
/**
* After the model is completed, no more DocTemplateEntities are created.
* Therefore any symbol that still appears is:
- * - NoDocTemplateMemberEntity (created here)
+ * - MemberTemplateEntity (created here)
* - NoDocTemplateEntity (created in makeTemplate)
*/
def createLazyTemplateMember(aSym: Symbol, inTpl: DocTemplateImpl): MemberImpl = {
// Code is duplicate because the anonymous classes are created statically
- def createNoDocMemberTemplate(bSym: Symbol, inTpl: DocTemplateImpl): NoDocTemplateMemberImpl = {
+ def createNoDocMemberTemplate(bSym: Symbol, inTpl: DocTemplateImpl): MemberTemplateImpl = {
assert(modelFinished) // only created AFTER the model is finished
- new NoDocTemplateMemberImpl(bSym, inTpl)
+ if (bSym.isModule || (bSym.isAliasType && bSym.tpe.typeSymbol.isModule))
+ new MemberTemplateImpl(bSym, inTpl) with Object {}
+ else if (bSym.isTrait || (bSym.isAliasType && bSym.tpe.typeSymbol.isTrait))
+ new MemberTemplateImpl(bSym, inTpl) with Trait {}
+ else if (bSym.isClass || (bSym.isAliasType && bSym.tpe.typeSymbol.isClass))
+ new MemberTemplateImpl(bSym, inTpl) with Class {}
+ else
+ sys.error("'" + bSym + "' isn't a class, trait or object thus cannot be built as a member template.")
}
assert(modelFinished)
@@ -687,20 +709,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
def makeRootPackage: PackageImpl = docTemplatesCache(RootPackage).asInstanceOf[PackageImpl]
// TODO: Should be able to override the type
- def makeMember(aSym: Symbol, implConv: ImplicitConversionImpl, inTpl: DocTemplateImpl): List[MemberImpl] = {
+ def makeMember(aSym: Symbol, conversion: Option[ImplicitConversionImpl], inTpl: DocTemplateImpl): List[MemberImpl] = {
- def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
+ def makeMember0(bSym: Symbol, useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
if (bSym.isGetter && bSym.isLazy)
- Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val {
override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor.
thisFactory.comment(bSym.accessed, None, inTpl.asInstanceOf[DocTemplateImpl]) // This hack should be removed after analyser is fixed.
override def isLazyVal = true
- override def useCaseOf = _useCaseOf
})
else if (bSym.isGetter && bSym.accessed.isMutable)
- Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val {
override def isVar = true
- override def useCaseOf = _useCaseOf
})
else if (bSym.isMethod && !bSym.hasAccessorFlag && !bSym.isConstructor && !bSym.isModule) {
val cSym = { // This unsightly hack closes issue #4086.
@@ -714,32 +734,30 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
}
else bSym
}
- Some(new NonTemplateParamMemberImpl(cSym, implConv, inTpl) with HigherKindedImpl with Def {
+ Some(new NonTemplateParamMemberImpl(cSym, conversion, useCaseOf, inTpl) with HigherKindedImpl with Def {
override def isDef = true
- override def useCaseOf = _useCaseOf
})
}
- else if (bSym.isConstructor && (implConv == null))
- Some(new NonTemplateParamMemberImpl(bSym, implConv, inTpl) with Constructor {
- override def isConstructor = true
- def isPrimary = sym.isPrimaryConstructor
- override def useCaseOf = _useCaseOf
- })
+ else if (bSym.isConstructor)
+ if (conversion.isDefined)
+ None // don't list constructors inherted by implicit conversion
+ else
+ Some(new NonTemplateParamMemberImpl(bSym, conversion, useCaseOf, inTpl) with Constructor {
+ override def isConstructor = true
+ def isPrimary = sym.isPrimaryConstructor
+ })
else if (bSym.isGetter) // Scala field accessor or Java field
- Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with Val {
+ Some(new NonTemplateMemberImpl(bSym, conversion, useCaseOf, inTpl) with Val {
override def isVal = true
- override def useCaseOf = _useCaseOf
})
else if (bSym.isAbstractType)
- Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
+ Some(new MemberTemplateImpl(bSym, inTpl) with TypeBoundsImpl with AbstractType {
override def isAbstractType = true
- override def useCaseOf = _useCaseOf
})
else if (bSym.isAliasType && bSym != AnyRefClass)
- Some(new NonTemplateMemberImpl(bSym, implConv, inTpl) with HigherKindedImpl with AliasType {
+ Some(new MemberTemplateImpl(bSym, inTpl) with AliasType {
override def isAliasType = true
def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym)
- override def useCaseOf = _useCaseOf
})
else if (bSym.isPackage && !modelFinished)
if (settings.skipPackage(makeQualifiedName(bSym))) None else
@@ -822,7 +840,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
val arguments = { // lazy
def noParams = annot.args map { _ => None }
val params: List[Option[ValueParam]] = annotationClass match {
- case aClass: Class =>
+ case aClass: DocTemplateEntity with Class =>
(aClass.primaryConstructor map { _.valueParams.head }) match {
case Some(vps) => vps map { Some(_) }
case None => noParams
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
index bdae09e84d..00254df7ef 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -410,7 +410,7 @@ trait ModelFactoryImplicitSupport {
// at the same time, the member itself is in the inTpl, not in the new template -- but should pick up
// variables from the old template. Ugly huh? We'll always create the member inTpl, but it will change
// the template when expanding variables in the comment :)
- makeMember(aSym, this, inTpl)
+ makeMember(aSym, Some(this), inTpl)
})
}