Changed the way use cases are handled in scaladoc.
If use cases are present, the original member disappears from the list. References SI-5054, but needs more work on the html part. If use cases are present along with links, scaladoc doesn't crash anymore. Closes SI-4898. Review by kzys. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@26048 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
parent
4659eb0fa1
commit
a64ac8eb39
|
@ -301,6 +301,10 @@ trait NonTemplateMemberEntity extends MemberEntity {
|
||||||
* It corresponds to a real member, and provides a simplified, yet compatible signature for that member. */
|
* It corresponds to a real member, and provides a simplified, yet compatible signature for that member. */
|
||||||
def isUseCase: Boolean
|
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
|
/** Whether this member is a bridge member. A bridge member does only exist for binary compatibility reasons
|
||||||
* and should not appear in ScalaDoc. */
|
* and should not appear in ScalaDoc. */
|
||||||
def isBridge: Boolean
|
def isBridge: Boolean
|
||||||
|
|
|
@ -453,16 +453,18 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
|
||||||
/** */
|
/** */
|
||||||
def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = {
|
def makeMember(aSym: Symbol, inTpl: => DocTemplateImpl): List[MemberImpl] = {
|
||||||
|
|
||||||
def makeMember0(bSym: Symbol): Option[MemberImpl] = {
|
def makeMember0(bSym: Symbol, _useCaseOf: Option[MemberImpl]): Option[MemberImpl] = {
|
||||||
if (bSym.isGetter && bSym.isLazy)
|
if (bSym.isGetter && bSym.isLazy)
|
||||||
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
||||||
override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor.
|
override lazy val comment = // The analyser does not duplicate the lazy val's DocDef when it introduces its accessor.
|
||||||
thisFactory.comment(bSym.accessed, inTpl) // This hack should be removed after analyser is fixed.
|
thisFactory.comment(bSym.accessed, inTpl) // This hack should be removed after analyser is fixed.
|
||||||
override def isLazyVal = true
|
override def isLazyVal = true
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isGetter && bSym.accessed.isMutable)
|
else if (bSym.isGetter && bSym.accessed.isMutable)
|
||||||
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
||||||
override def isVar = true
|
override def isVar = true
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isMethod && !bSym.hasAccessorFlag && !bSym.isConstructor && !bSym.isModule) {
|
else if (bSym.isMethod && !bSym.hasAccessorFlag && !bSym.isConstructor && !bSym.isModule) {
|
||||||
val cSym = { // This unsightly hack closes issue #4086.
|
val cSym = { // This unsightly hack closes issue #4086.
|
||||||
|
@ -478,25 +480,30 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
|
||||||
}
|
}
|
||||||
Some(new NonTemplateParamMemberImpl(cSym, inTpl) with HigherKindedImpl with Def {
|
Some(new NonTemplateParamMemberImpl(cSym, inTpl) with HigherKindedImpl with Def {
|
||||||
override def isDef = true
|
override def isDef = true
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
else if (bSym.isConstructor)
|
else if (bSym.isConstructor)
|
||||||
Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor {
|
Some(new NonTemplateParamMemberImpl(bSym, inTpl) with Constructor {
|
||||||
override def isConstructor = true
|
override def isConstructor = true
|
||||||
def isPrimary = sym.isPrimaryConstructor
|
def isPrimary = sym.isPrimaryConstructor
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isGetter) // Scala field accessor or Java field
|
else if (bSym.isGetter) // Scala field accessor or Java field
|
||||||
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
Some(new NonTemplateMemberImpl(bSym, inTpl) with Val {
|
||||||
override def isVal = true
|
override def isVal = true
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isAbstractType)
|
else if (bSym.isAbstractType)
|
||||||
Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
|
Some(new NonTemplateMemberImpl(bSym, inTpl) with TypeBoundsImpl with HigherKindedImpl with AbstractType {
|
||||||
override def isAbstractType = true
|
override def isAbstractType = true
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isAliasType)
|
else if (bSym.isAliasType)
|
||||||
Some(new NonTemplateMemberImpl(bSym, inTpl) with HigherKindedImpl with AliasType {
|
Some(new NonTemplateMemberImpl(bSym, inTpl) with HigherKindedImpl with AliasType {
|
||||||
override def isAliasType = true
|
override def isAliasType = true
|
||||||
def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym)
|
def alias = makeTypeInTemplateContext(sym.tpe.dealias, inTpl, sym)
|
||||||
|
override def useCaseOf = _useCaseOf
|
||||||
})
|
})
|
||||||
else if (bSym.isPackage)
|
else if (bSym.isPackage)
|
||||||
inTpl match { case inPkg: PackageImpl => makePackage(bSym, inPkg) }
|
inTpl match { case inPkg: PackageImpl => makePackage(bSym, inPkg) }
|
||||||
|
@ -510,9 +517,16 @@ class ModelFactory(val global: Global, val settings: doc.Settings) {
|
||||||
Nil
|
Nil
|
||||||
else {
|
else {
|
||||||
val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) =>
|
val allSyms = useCases(aSym, inTpl.sym) map { case (bSym, bComment, bPos) =>
|
||||||
addCommentBody(bSym, inTpl, bComment, bPos)
|
docComments.put(bSym, DocComment(bComment, bPos)) // put the comment in the list, don't parse it yet, closes SI-4898
|
||||||
|
bSym
|
||||||
}
|
}
|
||||||
(allSyms :+ aSym) flatMap { makeMember0(_) }
|
|
||||||
|
val member = makeMember0(aSym, None)
|
||||||
|
if (allSyms.isEmpty)
|
||||||
|
member.toList
|
||||||
|
else
|
||||||
|
// Use cases replace the original definitions - SI-5054
|
||||||
|
allSyms flatMap { makeMember0(_, member) }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
class SI_4898 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A link to [[__root__
|
||||||
|
*
|
||||||
|
* @usecase def test(): Int
|
||||||
|
*/
|
||||||
|
def test(implicit param: Int): Int = param
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
class SI_5054 {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple comment
|
||||||
|
*
|
||||||
|
* @param lost a lost parameter
|
||||||
|
* @usecase def test(): Int
|
||||||
|
*/
|
||||||
|
def test(implicit lost: Int): Int = lost
|
||||||
|
}
|
|
@ -373,6 +373,21 @@ object Test extends Properties("HtmlFactory") {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
property("Use cases and links should not crash scaladoc") = {
|
||||||
|
createTemplate("SI_4898.scala")
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
property("Use cases should override their original members - valid until signature is added to html") = {
|
||||||
|
createTemplate("SI_5054.scala") match {
|
||||||
|
case node: scala.xml.Node =>
|
||||||
|
node.toString.contains("A simple comment") &&
|
||||||
|
! node.toString.contains("a lost parameter")
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
val files = createTemplates("basic.scala")
|
val files = createTemplates("basic.scala")
|
||||||
println(files)
|
println(files)
|
||||||
|
|
Loading…
Reference in New Issue