diff options
25 files changed, 459 insertions, 204 deletions
diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala index 51c5793d46..18cc65092b 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/html/HtmlFactory.scala @@ -138,7 +138,7 @@ class HtmlFactory(val universe: doc.Universe, index: doc.Index) { if (!(written contains tpl)) { writeForThis(new page.Template(universe, diagramGenerator, tpl)) written += tpl - tpl.templates map writeTemplate + tpl.templates collect { case d: DocTemplateEntity => d } map writeTemplate } } diff --git a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala index 4a1a8cf898..af5e90083e 100644 --- a/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala +++ b/src/compiler/scala/tools/nsc/doc/html/HtmlPage.scala @@ -155,12 +155,18 @@ abstract class HtmlPage extends Page { thisPage => def toLinksIn(inPos: Int, starts: List[Int]): NodeSeq = { val (tpl, width) = tpe.refEntity(inPos) (tpl match { - case dtpl:DocTemplateEntity if hasLinks => + case LinkToTpl(dtpl:DocTemplateEntity) if hasLinks => <a href={ relativeLinkTo(dtpl) } class="extype" name={ dtpl.qualifiedName }>{ string.slice(inPos, inPos + width) }</a> - case tpl => + case LinkToTpl(tpl) => <span class="extype" name={ tpl.qualifiedName }>{ string.slice(inPos, inPos + width) }</span> + case LinkToMember(mbr, inTpl) if hasLinks => + <a href={ relativeLinkTo(inTpl) + "#" + mbr.signature } class="extmbr" name={ mbr.qualifiedName }>{ + string.slice(inPos, inPos + width) + }</a> + case LinkToMember(mbr, inTpl) => + <span class="extmbr" name={ mbr.qualifiedName }>{ string.slice(inPos, inPos + width) }</span> }) ++ toLinksOut(inPos + width, starts.tail) } if (hasLinks) diff --git a/src/compiler/scala/tools/nsc/doc/html/Page.scala b/src/compiler/scala/tools/nsc/doc/html/Page.scala index 5e3ab87ccd..08df26e745 100644 --- a/src/compiler/scala/tools/nsc/doc/html/Page.scala +++ b/src/compiler/scala/tools/nsc/doc/html/Page.scala @@ -48,7 +48,7 @@ abstract class Page { * @param generator The generator that is writing this page. */ def writeFor(site: HtmlFactory): Unit - def docEntityKindToString(ety: DocTemplateEntity) = + def docEntityKindToString(ety: TemplateEntity) = if (ety.isTrait) "trait" else if (ety.isCaseClass) "case class" else if (ety.isClass) "class" 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..ba48bf3f9b 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,9 @@ 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 collect { + case t: DocTemplateEntity if !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) => 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 2b68ac2937..e1ab479f9d 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -62,7 +62,9 @@ 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.collect { + case t: DocTemplateEntity if !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) => 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 0d0410c7e2..47834e542c 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala @@ -238,44 +238,12 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp </body> } - def boundsToString(hi: Option[TypeEntity], lo: Option[TypeEntity]): String = { - def bound0(bnd: Option[TypeEntity], pre: String): String = bnd match { - case None => "" - case Some(tpe) => pre ++ tpe.toString - } - bound0(hi, "<:") ++ bound0(lo, ">:") - } - - def tparamsToString(tpss: List[TypeParam]): String = { - if (tpss.isEmpty) "" else { - def tparam0(tp: TypeParam): String = - tp.variance + tp.name + boundsToString(tp.hi, tp.lo) - def tparams0(tpss: List[TypeParam]): String = (tpss: @unchecked) match { - case tp :: Nil => tparam0(tp) - case tp :: tps => tparam0(tp) ++ ", " ++ tparams0(tps) - } - "[" + tparams0(tpss) + "]" - } - } - - def defParamsToString(d: MemberEntity with Def): String = { - val paramLists: List[String] = - if (d.valueParams.isEmpty) Nil - else d.valueParams map (ps => ps map (_.resultType.name) mkString ("(",",",")")) - - tparamsToString(d.typeParams) + paramLists.mkString - } - def memberToHtml(mbr: MemberEntity, inTpl: DocTemplateEntity): NodeSeq = { - val defParamsString = mbr match { - case d:MemberEntity with Def => defParamsToString(d) - case _ => "" - } val memberComment = memberToCommentHtml(mbr, inTpl, 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}/> + <a id={ mbr.signature }/> { signature(mbr, false) } { memberComment } </li> @@ -650,6 +618,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp 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" @@ -850,18 +819,13 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp val link = relativeLinkTo(mbr) myXml ++= <span class="name"><a href={link}>{str.substring(from, to)}</a></span> case mbr: MemberEntity => - val anchor = "#" + mbr.name + defParamsString(mbr) + ":" + mbr.resultType.name + val anchor = "#" + mbr.signature val link = relativeLinkTo(mbr.inTemplate) myXml ++= <span class="name"><a href={link ++ anchor}>{str.substring(from, to)}</a></span> } index = to } } - // function used in the MemberEntity case above - def defParamsString(mbr: Entity):String = mbr match { - case d:MemberEntity with Def => defParamsToString(d) - case _ => "" - } if (index <= length-1) myXml ++= codeStringToXml(str.substring(index, length )) diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala index dc6f941c30..8648fdb0a1 100644 --- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala +++ b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala @@ -74,7 +74,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator { def textTypeEntity(text: String) = new TypeEntity { val name = text - def refEntity: SortedMap[Int, (TemplateEntity, Int)] = SortedMap() + def refEntity: SortedMap[Int, (LinkTo, Int)] = SortedMap() } // it seems dot chokes on node names over 8000 chars, so let's limit the size of the string diff --git a/src/compiler/scala/tools/nsc/doc/model/Entity.scala b/src/compiler/scala/tools/nsc/doc/model/Entity.scala index 2901daafd6..4ab77b356b 100644 --- a/src/compiler/scala/tools/nsc/doc/model/Entity.scala +++ b/src/compiler/scala/tools/nsc/doc/model/Entity.scala @@ -53,6 +53,9 @@ trait Entity { /** The kind of the entity */ def kind: String + + /** Whether or not the template was defined in a package object */ + def inPackageObject: Boolean } object Entity { @@ -91,9 +94,6 @@ trait TemplateEntity extends Entity { /** Whether this template is a case class. */ def isCaseClass: Boolean - /** Whether or not the template was defined in a package object */ - def inPackageObject: Boolean - /** The self-type of this template, if it differs from the template type. */ def selfType : Option[TypeEntity] @@ -183,7 +183,11 @@ trait MemberEntity extends Entity { /** If this member originates from an implicit conversion, we set the implicit information to the correct origin */ def byConversion: Option[ImplicitConversion] + + /** The identity of this member, used for linking */ + def signature: String } + object MemberEntity { // Oh contravariance, contravariance, wherefore art thou contravariance? // Note: the above works for both the commonly misunderstood meaning of the line and the real one. @@ -205,7 +209,10 @@ trait NoDocTemplate extends TemplateEntity { def kind = "<no doc>" } -/** TODO: Document */ +/** 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 but C doesn't get its own page */ trait NoDocTemplateMemberEntity extends TemplateEntity with MemberEntity { def kind = "<no doc, mbr>" } @@ -253,7 +260,7 @@ trait DocTemplateEntity extends TemplateEntity with MemberEntity { /** All templates that are members of this template. If this template is a package, only templates for which * documentation is available in the universe (`DocTemplateEntity`) are listed. */ - def templates: List[DocTemplateEntity] + def templates: List[TemplateEntity with MemberEntity] /** All methods that are members of this template. */ def methods: List[Def] diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala index 9fa6619e9f..2efbfbe43c 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactory.scala @@ -83,6 +83,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def toRoot: List[EntityImpl] = this :: inTpl.toRoot def qualifiedName = name def annotations = sym.annotations.map(makeAnnotation) + def inPackageObject: Boolean = sym.owner.isModuleClass && sym.owner.sourceModule.isPackageObject } trait TemplateImpl extends EntityImpl with TemplateEntity { @@ -96,11 +97,25 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def isRootPackage = false def ownType = makeType(sym.tpe, this) def selfType = if (sym.thisSym eq sym) None else Some(makeType(sym.thisSym.typeOfThis, this)) - def inPackageObject: Boolean = sym.owner.isModuleClass && sym.owner.sourceModule.isPackageObject } abstract class MemberImpl(sym: Symbol, implConv: ImplicitConversionImpl, inTpl: DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity { - lazy val comment = if (inTpl != null) thisFactory.comment(sym, inTpl) else None + lazy val comment = { + val commentTpl = + /* 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 (commentTpl != null) thisFactory.comment(sym, commentTpl) else None + } override def inTemplate = inTpl override def toRoot: List[MemberImpl] = this :: inTpl.toRoot def inDefinitionTemplates = this match { @@ -189,6 +204,30 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { sym.isAbstractClass || sym.isAbstractType) && !sym.isSynthetic def isTemplate = false def byConversion = if (implConv ne null) Some(implConv) else None + lazy val signature = { + + val defParamsString = this match { + case d: MemberEntity with Def => + val paramLists: List[String] = + if (d.valueParams.isEmpty) Nil + else d.valueParams map (ps => ps map (_.resultType.name) mkString ("(",",",")")) + + val tParams = if (d.typeParams.isEmpty) "" else { + def boundsToString(hi: Option[TypeEntity], lo: Option[TypeEntity]): String = { + def bound0(bnd: Option[TypeEntity], pre: String): String = bnd match { + case None => "" + case Some(tpe) => pre ++ tpe.toString + } + bound0(hi, "<:") ++ bound0(lo, ">:") + } + "[" + d.typeParams.map(tp => tp.variance + tp.name + boundsToString(tp.hi, tp.lo)).mkString(", ") + "]" + } + + tParams + paramLists.mkString + case _ => "" + } + name + defParamsString +":"+ resultType.name + } } /** A template that is not documented at all. The class is instantiated during lookups, to indicate that the class @@ -198,7 +237,6 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { assert(modelFinished) assert(!(noDocTemplatesCache isDefinedAt sym)) noDocTemplatesCache += (sym -> this) - def isDocTemplate = false } @@ -209,7 +247,8 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { */ class NoDocTemplateMemberImpl(sym: Symbol, inTpl: DocTemplateImpl) extends MemberImpl(sym, null, inTpl) with TemplateImpl with HigherKindedImpl with NoDocTemplateMemberEntity { assert(modelFinished) - + // no templates cache for this class, each owner gets its own instance + override def isTemplate = true def isDocTemplate = false lazy val definitionName = optimize(inDefinitionTemplates.head.qualifiedName + "." + name) } @@ -330,7 +369,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { // all the members that are documentented PLUS the members inherited by implicit conversions var members: List[MemberImpl] = ownMembers - def templates = members collect { case c: DocTemplateEntity => c } + def templates = members collect { case c: TemplateEntity with MemberEntity => c } def methods = members collect { case d: Def => d } def values = members collect { case v: Val => v } def abstractTypes = members collect { case t: AbstractType => t } @@ -348,7 +387,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { case _ => } - members :::= memberSymsLazy.map(modelCreation.createLazyTemplateMember(_, inTpl)) + members :::= memberSymsLazy.map(modelCreation.createLazyTemplateMember(_, this)) // compute linearization to register subclasses linearization @@ -411,9 +450,14 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { 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.conversionQualifiedName + "#" + 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) + } def isUseCase = sym.isSynthetic def isBridge = sym.isBridge } @@ -461,7 +505,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { case ObjectClass => normalizeTemplate(AnyRefClass) case _ if aSym.isPackageObject => - aSym + normalizeTemplate(aSym.owner) case _ if aSym.isModuleClass => normalizeTemplate(aSym.sourceModule) case _ => @@ -501,6 +545,7 @@ 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 else if (bSym.isTrait || (bSym.isAliasType && bSym.tpe.typeSymbol.isTrait)) @@ -566,6 +611,13 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { * - 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 = { + assert(modelFinished) // only created AFTER the model is finished + new NoDocTemplateMemberImpl(bSym, inTpl) + } + assert(modelFinished) val bSym = normalizeTemplate(aSym) @@ -579,7 +631,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { mbrs.head case _ => // move the class completely to the new location - new NoDocTemplateMemberImpl(aSym, inTpl) + createNoDocMemberTemplate(bSym, inTpl) } } } @@ -690,7 +742,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { docTemplatesCache.get(normalizeTemplate(aSym)) } - def makeTemplate(aSym: Symbol): TemplateImpl = { + def makeTemplate(aSym: Symbol): TemplateImpl = makeTemplate(aSym, None) + + def makeTemplate(aSym: Symbol, inTpl: Option[TemplateImpl]): TemplateImpl = { assert(modelFinished) def makeNoDocTemplate(aSym: Symbol, inTpl: TemplateImpl): NoDocTemplateImpl = { @@ -706,7 +760,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { dtpl case None => val bSym = normalizeTemplate(aSym) - makeNoDocTemplate(bSym, makeTemplate(bSym.owner)) + makeNoDocTemplate(bSym, if (inTpl.isDefined) inTpl.get else makeTemplate(bSym.owner)) } } @@ -797,10 +851,10 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { /** Get the types of the parents of the current class, ignoring the refinements */ def makeParentTypes(aType: Type, tpl: Option[DocTemplateImpl], inTpl: TemplateImpl): List[(TemplateEntity, TypeEntity)] = aType match { case RefinedType(parents, defs) => - val ignoreParents = Set[Symbol](AnyRefClass, ObjectClass) + val ignoreParents = Set[Symbol](AnyClass, AnyRefClass, ObjectClass) val filtParents = // we don't want to expose too many links to AnyRef, that will just be redundant information - if (tpl.isDefined && (!tpl.get.isObject && parents.length < 2)) + if (tpl.isDefined && { val sym = tpl.get.sym; (!sym.isModule && parents.length < 2) || (sym == AnyValClass) || (sym == AnyRefClass) || (sym == AnyClass) }) parents else parents.filterNot((p: Type) => ignoreParents(p.typeSymbol)) @@ -819,7 +873,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def createTypeEntity = new TypeEntity { private val nameBuffer = new StringBuilder - private var refBuffer = new immutable.TreeMap[Int, (TemplateEntity, Int)] + private var refBuffer = new immutable.TreeMap[Int, (LinkTo, Int)] private def appendTypes0(types: List[Type], sep: String): Unit = types match { case Nil => case tp :: Nil => @@ -862,15 +916,56 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { // if (!preSym.printWithoutPrefix) { // nameBuffer append stripPrefixes.foldLeft(pre.prefixString)(_ stripPrefix _) // } + + // SI-3314/SI-4888: Classes, Traits and Types can be inherited from a template to another: + // class Enum { abstract class Value } + // class Day extends Enum { object Mon extends Value /*...*/ } + // ===> in such cases we have two options: + // (0) if there's no inheritance taking place (Enum#Value) we can link to the template directly + // (1) if we generate the doc template for Day, we can link to the correct member + // (2) if we don't generate the doc template, we should at least indicate the correct prefix in the tooltip val bSym = normalizeTemplate(aSym) - if (bSym.isNonClassType && bSym != AnyRefClass) { - nameBuffer append bSym.decodedName - } else { - val tpl = makeTemplate(bSym) - val pos0 = nameBuffer.length - refBuffer += pos0 -> (tpl, tpl.name.length) - nameBuffer append tpl.name - } + val owner = + if ((preSym != NoSymbol) && /* it needs a prefix */ + (preSym != bSym.owner) && /* prefix is different from owner */ + // ((preSym != inTpl.sym) && /* prevent prefixes from being shown inside the defining class */ + // (preSym != inTpl.sym.moduleClass)) && /* or object */ + (aSym == bSym)) /* normalization doesn't play tricks on us */ + preSym + else + bSym.owner + + val bTpl = findTemplateMaybe(bSym) + val link = + if (owner == bSym.owner && bTpl.isDefined) + // (0) the owner's class is linked AND has a template - lovely + LinkToTpl(bTpl.get) + else { + val oTpl = findTemplateMaybe(owner) + val bMbr = oTpl.map(findMember(bSym, _)) + if (oTpl.isDefined && bMbr.isDefined && bMbr.get.isDefined) + // (1) the owner's class + LinkToMember(bMbr.get.get, oTpl.get) //ugh + else + // (2) if we still couldn't find the owner, make a noDocTemplate for everything (in the correct owner!) + LinkToTpl(makeTemplate(bSym, Some(makeTemplate(owner)))) + } + + // TODO: The name might include a prefix, take care of that! + val name = bSym.nameString + val pos0 = nameBuffer.length + refBuffer += pos0 -> ((link, name.length)) + nameBuffer append name + + // if (bSym.isNonClassType && bSym != AnyRefClass) { + // nameBuffer append bSym.decodedName + // } else { + // val tpl = makeTemplate(bSym) + // val pos0 = nameBuffer.length + // refBuffer += pos0 -> ((LinkToTpl(tpl), tpl.name.length)) + // nameBuffer append tpl.name + // } + if (!targs.isEmpty) { nameBuffer append '[' appendTypes0(targs, ", ") @@ -949,12 +1044,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { * (1) sourceModule * (2) you get out of owners with .owner */ - normalizeTemplate(aSym) match { - case bSym if bSym.isPackageObject => - normalizeOwner(bSym.owner) - case bSym => - bSym - } + normalizeTemplate(aSym) def inOriginalOnwer(aSym: Symbol, inTpl: TemplateImpl): Boolean = normalizeOwner(aSym.owner) == normalizeOwner(inTpl.sym) diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 8cbf2ac1b6..493ad3d831 100644 --- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -408,25 +408,14 @@ trait ModelFactoryImplicitSupport { 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, 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, this, inTpl) - } + // we can't just pick up nodes from the original template, although that would be very convenient: + // they need the byConversion field to be attached to themselves and the types to be transformed by + // asSeenFrom + + // 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) }) } diff --git a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala b/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala index 67e955f613..a16e99bf06 100644 --- a/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala +++ b/src/compiler/scala/tools/nsc/doc/model/TypeEntity.scala @@ -9,6 +9,9 @@ package model import scala.collection._ +abstract sealed class LinkTo +case class LinkToTpl(tpl: TemplateEntity) extends LinkTo +case class LinkToMember(mbr: MemberEntity, inTpl: DocTemplateEntity) extends LinkTo /** A type. Note that types and templates contain the same information only for the simplest types. For example, a type * defines how a template's type parameters are instantiated (as in `List[Cow]`), what the template's prefix is @@ -21,7 +24,7 @@ abstract class TypeEntity { /** Maps which parts of this type's name reference entities. The map is indexed by the position of the first * character that reference some entity, and contains the entity and the position of the last referenced * character. The referenced character ranges do not to overlap or nest. The map is sorted by position. */ - def refEntity: SortedMap[Int, (TemplateEntity, Int)] + def refEntity: SortedMap[Int, (LinkTo, Int)] /** The human-readable representation of this type. */ override def toString = name diff --git a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala index 1a8ad193aa..4b05da98cd 100644 --- a/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala +++ b/src/compiler/scala/tools/nsc/doc/model/diagram/DiagramFactory.scala @@ -32,7 +32,7 @@ trait DiagramFactory extends DiagramDirectiveParser { def normalNode(sym: Symbol) = NormalNode(makeTemplate(sym).ownType, Some(makeTemplate(sym))) def aggregationNode(text: String) = - NormalNode(new TypeEntity { val name = text; val refEntity = SortedMap[Int, (TemplateEntity, Int)]() }, None) + NormalNode(new TypeEntity { val name = text; val refEntity = SortedMap[Int, (LinkTo, Int)]() }, None) /** Create the inheritance diagram for this template */ def makeInheritanceDiagram(tpl: DocTemplateImpl): Option[Diagram] = { diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala index be70a91e14..c89dd2cb8f 100644 --- a/src/partest/scala/tools/partest/ScaladocModelTest.scala +++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala @@ -103,13 +103,22 @@ abstract class ScaladocModelTest extends DirectTest { class TemplateAccess(tpl: DocTemplateEntity) { def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")") - def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: Class => c}) + def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: DocTemplateEntity with Class => c}) + + def _classMbr(name: String): NoDocTemplateMemberEntity = getTheFirst(_classesMbr(name), tpl.qualifiedName + ".classMember(" + name + ")") + def _classesMbr(name: String): List[NoDocTemplateMemberEntity] = tpl.templates.filter(_.name == name).collect({ case c: NoDocTemplateMemberEntity if c.isClass => c}) def _trait(name: String): DocTemplateEntity = getTheFirst(_traits(name), tpl.qualifiedName + ".trait(" + name + ")") - def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: Trait => t}) + def _traits(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case t: DocTemplateEntity with Trait => t}) + + def _traitMbr(name: String): NoDocTemplateMemberEntity = getTheFirst(_traitsMbr(name), tpl.qualifiedName + ".traitMember(" + name + ")") + def _traitsMbr(name: String): List[NoDocTemplateMemberEntity] = tpl.templates.filter(_.name == name).collect({ case t: NoDocTemplateMemberEntity if t.isTrait => t}) def _object(name: String): DocTemplateEntity = getTheFirst(_objects(name), tpl.qualifiedName + ".object(" + name + ")") - def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: Object => o}) + def _objects(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case o: DocTemplateEntity with Object => o}) + + def _objectMbr(name: String): NoDocTemplateMemberEntity = getTheFirst(_objectsMbr(name), tpl.qualifiedName + ".objectMember(" + name + ")") + def _objectsMbr(name: String): List[NoDocTemplateMemberEntity] = tpl.templates.filter(_.name == name).collect({ case o: NoDocTemplateMemberEntity if o.isObject => o}) def _method(name: String): Def = getTheFirst(_methods(name), tpl.qualifiedName + ".method(" + name + ")") def _methods(name: String): List[Def] = tpl.methods.filter(_.name == name) @@ -119,6 +128,12 @@ abstract class ScaladocModelTest extends DirectTest { def _conversion(name: String): ImplicitConversion = getTheFirst(_conversions(name), tpl.qualifiedName + ".conversion(" + name + ")") def _conversions(name: String): List[ImplicitConversion] = tpl.conversions.filter(_.conversionQualifiedName == name) + + def _absType(name: String): MemberEntity = getTheFirst(_methods(name), tpl.qualifiedName + ".abstractType(" + name + ")") + def _absTypes(name: String): List[MemberEntity] = tpl.members.filter(mbr => mbr.name == name && mbr.isAbstractType) + + def _aliasType(name: String): MemberEntity = getTheFirst(_methods(name), tpl.qualifiedName + ".aliasType(" + name + ")") + def _aliasTypes(name: String): List[MemberEntity] = tpl.members.filter(mbr => mbr.name == name && mbr.isAliasType) } class PackageAccess(pack: Package) extends TemplateAccess(pack) { @@ -141,7 +156,10 @@ abstract class ScaladocModelTest extends DirectTest { case 1 => list.head case 0 => sys.error("Error getting " + expl + ": No such element.") case _ => sys.error("Error getting " + expl + ": " + list.length + " elements with this name. " + - "All elements in list: [" + list.mkString(", ") + "]") + "All elements in list: [" + list.map({ + case ent: Entity => ent.kind + " " + ent.qualifiedName + case other => other.toString + }).mkString(", ") + "]") } def extractCommentText(c: Comment) = { diff --git a/test/scaladoc/resources/SI-3314.scala b/test/scaladoc/resources/SI-3314.scala new file mode 100644 index 0000000000..e5773a4970 --- /dev/null +++ b/test/scaladoc/resources/SI-3314.scala @@ -0,0 +1,70 @@ +package scala.test.scaladoc { + + package test1 { + class Enum { + abstract class Value + class Val extends Value + def Value(): Value = new Val + } + + object Constants extends Enum { + def a = Value + } + } + + package test2 { + trait WeekDayTrait extends Enumeration { + type WeekDay = Value + val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + } + + class WeekDayClass extends Enumeration { + type WeekDay = Value + val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + } + + object WeekDayObject extends Enumeration { + type WeekDay = Value + val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value + } + + object UserObject { + def isWorkingDay1(d: scala.test.scaladoc.test2.WeekDayClass#Value) = false + def isWorkingDay2(d: scala.test.scaladoc.test2.WeekDayClass#WeekDay) = false + def isWorkingDay3(d: scala.test.scaladoc.test2.WeekDayTrait#Value) = false + def isWorkingDay4(d: scala.test.scaladoc.test2.WeekDayTrait#WeekDay) = false + def isWorkingDay5(d: scala.test.scaladoc.test2.WeekDayObject.Value) = false + def isWorkingDay6(d: scala.test.scaladoc.test2.WeekDayObject.WeekDay) = false + import WeekDayObject._ + def isWorkingDay7(d: Value) = ! (d == Sat || d == Sun) + def isWorkingDay8(d: WeekDay) = ! (d == Sat || d == Sun) + def isWorkingDay9(d: WeekDayObject.Value) = ! (d == Sat || d == Sun) + } + + class UserClass { + def isWorkingDay1(d: scala.test.scaladoc.test2.WeekDayClass#Value) = false + def isWorkingDay2(d: scala.test.scaladoc.test2.WeekDayClass#WeekDay) = false + def isWorkingDay3(d: scala.test.scaladoc.test2.WeekDayTrait#Value) = false + def isWorkingDay4(d: scala.test.scaladoc.test2.WeekDayTrait#WeekDay) = false + def isWorkingDay5(d: scala.test.scaladoc.test2.WeekDayObject.Value) = false + def isWorkingDay6(d: scala.test.scaladoc.test2.WeekDayObject.WeekDay) = false + import WeekDayObject._ + def isWorkingDay7(d: Value) = ! (d == Sat || d == Sun) + def isWorkingDay8(d: WeekDay) = ! (d == Sat || d == Sun) + def isWorkingDay9(d: WeekDayObject.Value) = ! (d == Sat || d == Sun) + } + + trait UserTrait { + def isWorkingDay1(d: scala.test.scaladoc.test2.WeekDayClass#Value) = false + def isWorkingDay2(d: scala.test.scaladoc.test2.WeekDayClass#WeekDay) = false + def isWorkingDay3(d: scala.test.scaladoc.test2.WeekDayTrait#Value) = false + def isWorkingDay4(d: scala.test.scaladoc.test2.WeekDayTrait#WeekDay) = false + def isWorkingDay5(d: scala.test.scaladoc.test2.WeekDayObject.Value) = false + def isWorkingDay6(d: scala.test.scaladoc.test2.WeekDayObject.WeekDay) = false + import WeekDayObject._ + def isWorkingDay7(d: Value) = ! (d == Sat || d == Sun) + def isWorkingDay8(d: WeekDay) = ! (d == Sat || d == Sun) + def isWorkingDay9(d: WeekDayObject.Value) = ! (d == Sat || d == Sun) + } + } +} diff --git a/test/scaladoc/resources/SI_4676.scala b/test/scaladoc/resources/SI_4676.scala deleted file mode 100644 index 00c0fc7ea9..0000000000 --- a/test/scaladoc/resources/SI_4676.scala +++ /dev/null @@ -1,4 +0,0 @@ -class SI_4676 { - type SS = (String,String) - def x(ss: SS): Int = 3 -} diff --git a/test/scaladoc/resources/Trac3484.scala b/test/scaladoc/resources/Trac3484.scala deleted file mode 100644 index 9656ec268d..0000000000 --- a/test/scaladoc/resources/Trac3484.scala +++ /dev/null @@ -1,27 +0,0 @@ -class cbf[A, B, C] - -/** - * @define Coll Traversable - * @define bfreturn $Coll - */ -class Collection[A] { - /** What map does... - * - * $bfreturn - * @usecase def map[B](f: A => B): $bfreturn[B] - * - */ - def map[B, That](f: A => B)(implicit fact: cbf[Collection[A], B, That]) = - null -} - -/** - * @define b John - * @define a Mister $b - */ -class SR704 { - /** - * Hello $a. - */ - def foo = 123 -} diff --git a/test/scaladoc/run/SI-3314.check b/test/scaladoc/run/SI-3314.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-3314.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-3314.scala b/test/scaladoc/run/SI-3314.scala new file mode 100644 index 0000000000..665223098a --- /dev/null +++ b/test/scaladoc/run/SI-3314.scala @@ -0,0 +1,74 @@ +import scala.tools.nsc.doc.model._ +import scala.tools.partest.ScaladocModelTest + +object Test extends ScaladocModelTest { + + override def resourceFile = "SI-3314.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._ + + // just need to check the member exists, access methods will throw an error if there's a problem + val base = rootPackage._package("scala")._package("test")._package("scaladoc") + + val test1 = base._package("test1") + val test1Value = test1._class("Enum")._method("Value").resultType + assert(test1Value.name == "Value", test1Value.name + " == Value") + assert(test1Value.refEntity.size == 1, test1Value.refEntity.size + " == 1") + + val test1Constants = test1._object("Constants")._method("a").resultType + assert(test1Constants.name == "Value", test1Constants.name + " == Value") + assert(test1Constants.refEntity.size == 1, test1Constants.refEntity.size + " == 1") + assert(test1Constants.refEntity(0)._1 == LinkToMember(test1._object("Constants")._class("Value"), test1._object("Constants")), + test1Constants.refEntity(0)._1 + " == LinkToMember(test1.Enum.Value)") + + val test2 = base._package("test2") + def testDefinition(doc: DocTemplateEntity) = { + for (day <- List("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun")) { + assert(doc._value(day).resultType.name == "Value", + doc._value(day).resultType.name + " == Value") + assert(doc._value(day).resultType.refEntity.size == 1, + doc._value(day).resultType.refEntity.size + " == 1") + assert(doc._value(day).resultType.refEntity(0)._1 == LinkToMember(doc._classMbr("Value"), doc), + doc._value(day).resultType.refEntity(0)._1 + " == LinkToMember(" + doc.qualifiedName + ".Value)") + } + } + testDefinition(test2._trait("WeekDayTrait")) + testDefinition(test2._class("WeekDayClass")) + testDefinition(test2._object("WeekDayObject")) + + def testUsage(doc: DocTemplateEntity) = { + val ValueInClass = test2._class("WeekDayClass")._classMbr("Value") + val ValueInTrait = test2._trait("WeekDayTrait")._classMbr("Value") + val ValueInObject = test2._object("WeekDayObject")._classMbr("Value") + val WeekDayInObject = test2._object("WeekDayObject")._member("WeekDay") + + val expected = List( + ("isWorkingDay1", "Value", ValueInClass), + ("isWorkingDay2", "Value", ValueInClass), + ("isWorkingDay3", "Value", ValueInTrait), + ("isWorkingDay4", "Value", ValueInTrait), + ("isWorkingDay5", "Value", ValueInObject), + ("isWorkingDay6", "WeekDay", WeekDayInObject), + ("isWorkingDay7", "Value", ValueInObject), + ("isWorkingDay8", "WeekDay", WeekDayInObject), + ("isWorkingDay9", "Value", ValueInObject)) + + for ((method, name, ref) <- expected) { + assert(doc._method(method).valueParams(0)(0).resultType.name == name, + doc._method(method).valueParams(0)(0).resultType.name + " == " + name + " (in " + doc + "." + method + ")") + assert(doc._method(method).valueParams(0)(0).resultType.refEntity.size == 1, + doc._method(method).valueParams(0)(0).resultType.refEntity.size + " == " + 1 + " (in " + doc + "." + method + ")") + assert(doc._method(method).valueParams(0)(0).resultType.refEntity(0)._1 == LinkToMember(ref, ref.inTemplate), + doc._method(method).valueParams(0)(0).resultType.refEntity(0)._1 + " == LinkToMember(" + ref.qualifiedName + ") (in " + doc + "." + method + ")") + } + } + testUsage(test2._object("UserObject")) + testUsage(test2._class("UserClass")) + testUsage(test2._trait("UserTrait")) + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/SI-3484.check b/test/scaladoc/run/SI-3484.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-3484.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-3484.scala b/test/scaladoc/run/SI-3484.scala new file mode 100644 index 0000000000..297aebee8f --- /dev/null +++ b/test/scaladoc/run/SI-3484.scala @@ -0,0 +1,52 @@ +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 = """ + class cbf[A, B, C] + + /** + * @define Coll Collection + * @define bfreturn $Coll + */ + class Collection[A] { + /** What map does... + * + * $bfreturn + * @usecase def map[B](f: A => B): $bfreturn[B] + * + */ + def map[B, That](f: A => B)(implicit fact: cbf[Collection[A], B, That]) = + null + } + + /** + * @define b John + * @define a Mister $b + */ + class SR704 { + /** + * Hello $a. + */ + def foo = 123 + } + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + 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._ + + // check correct expansion of the use case signature + val map = rootPackage._class("Collection")._method("map") + assert(map.resultType.name == "Collection[B]", map.resultType.name + " == Traversable[B]") + + val foo = rootPackage._class("SR704")._method("foo") + assert(extractCommentText(foo.comment.get).contains("Hello Mister John."), + extractCommentText(foo.comment.get) + ".contains(Hello Mister John.)") + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/SI-4676.check b/test/scaladoc/run/SI-4676.check new file mode 100644 index 0000000000..619c56180b --- /dev/null +++ b/test/scaladoc/run/SI-4676.check @@ -0,0 +1 @@ +Done. diff --git a/test/scaladoc/run/SI-4676.scala b/test/scaladoc/run/SI-4676.scala new file mode 100644 index 0000000000..b83a59a472 --- /dev/null +++ b/test/scaladoc/run/SI-4676.scala @@ -0,0 +1,26 @@ +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 = """ + class SI_4676 { + type SS = (String,String) + def x(ss: SS): Int = 3 + } + class cbf[A, B, C] + """ + + // diagrams must be started. In case there's an error with dot, it should not report anything + 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._ + + // check correct expansion of the use case signature + val x = rootPackage._class("SI_4676")._method("x") + assert(x.valueParams(0)(0).resultType.name == "(String, String)", "parameter ss of method x has type (String, String") + } +}
\ No newline at end of file diff --git a/test/scaladoc/run/SI-5235.scala b/test/scaladoc/run/SI-5235.scala index cae70fd0a5..f0c6e1cf17 100644 --- a/test/scaladoc/run/SI-5235.scala +++ b/test/scaladoc/run/SI-5235.scala @@ -77,11 +77,11 @@ object Test extends ScaladocModelTest { assert(gcReverseType.name == "GenericColl", gcReverseType.name + " == GenericColl") assert(scReverseType.name == "BullSh", scReverseType.name + " == BullSh") assert(mcReverseType.name == "MyCollection",mcReverseType.name + " == MyCollection") - assert(gcReverseType.refEntity(0)._1 == GenericColl, + assert(gcReverseType.refEntity(0)._1 == LinkToTpl(GenericColl), gcReverse.qualifiedName + "'s return type has a link to " + GenericColl.qualifiedName) - assert(scReverseType.refEntity.isEmpty, + assert(!scReverseType.refEntity(0)._1.asInstanceOf[LinkToTpl].tpl.isDocTemplate, scReverse.qualifiedName + "'s return type does not have links") - assert(mcReverseType.refEntity(0)._1 == MyCollection, + assert(mcReverseType.refEntity(0)._1 == LinkToTpl(MyCollection), mcReverse.qualifiedName + "'s return type has a link to " + MyCollection.qualifiedName) } }
\ No newline at end of file diff --git a/test/scaladoc/run/implicits-var-exp.scala b/test/scaladoc/run/implicits-var-exp.scala index 16569fe3c2..94d2990d29 100644 --- a/test/scaladoc/run/implicits-var-exp.scala +++ b/test/scaladoc/run/implicits-var-exp.scala @@ -6,25 +6,36 @@ object Test extends ScaladocModelTest { override def code = """ package scala.test.scaladoc.variable.expansion { - /** - * Blah blah blah - */ + /** @define coll WROOOONG-A */ class A object A { import language.implicitConversions - implicit def aToB(a: A) = new B + implicit def aToC(a: A) = new C + implicit def aToE(a: A) = new E with F } - /** - * @define coll collection - */ + /** @define coll WROOOONG-B */ class B { - /** - * foo returns a $coll - */ + /** foo returns a $coll */ def foo: Nothing = ??? } + + /** @define coll collection */ + class C extends B + + /** @define coll WROOOONG-D */ + trait D { + /** bar returns a $coll */ + def bar: Nothing = ??? + } + + /** @define coll result */ + //trait E { self: D => override def bar: Nothing = ??? } + trait E extends D { override def bar: Nothing = ??? } + + /** @define coll WROOOONG-F */ + trait F } """ @@ -37,7 +48,9 @@ object Test extends ScaladocModelTest { val base = rootPackage._package("scala")._package("test")._package("scaladoc")._package("variable")._package("expansion") val foo = base._class("A")._method("foo") - assert(foo.comment.get.body.toString.contains("foo returns a collection"), "\"" + foo.comment.get.body.toString + "\".contains(\"foo returns a collection\")") + + val bar = base._class("A")._method("bar") + assert(bar.comment.get.body.toString.contains("bar returns a result"), "\"" + bar.comment.get.body.toString + "\".contains(\"bar returns a result\")") } }
\ No newline at end of file diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala index 5b6f75426e..13eacf79a5 100644 --- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala +++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala @@ -235,30 +235,6 @@ object Test extends Properties("HtmlFactory") { } } - property("Trac #3484") = { - val files = createTemplates("Trac3484.scala") - - files("Collection.html") match { - case node: scala.xml.Node => { - val s = node.toString - s.contains("""<span class="result">: Traversable[B]</span>""") - } - case _ => false - } - } - - property("Trac #3484 - SR704") = { - val files = createTemplates("Trac3484.scala") - - files("SR704.html") match { - case node: scala.xml.Node => { - val s = node.toString - s.contains("Hello Mister John.") - } - case _ => false - } - } - property("Trac #4325 - files") = { val files = createTemplates("Trac4325.scala") @@ -303,7 +279,7 @@ object Test extends Properties("HtmlFactory") { case _ => false } } - // + // // property("Trac #484 - refinements and existentials") = { // val files = createTemplates("Trac484.scala") // val lines = """ @@ -315,7 +291,7 @@ object Test extends Properties("HtmlFactory") { // |def j(x: Int): Bar // |def k(): AnyRef { type Dingus <: T forSome { type T <: String } } // """.stripMargin.trim.lines map (_.trim) - // + // // files("RefinementAndExistentials.html") match { // case node: scala.xml.Node => { // val s = node.text.replaceAll("\\s+", " ") @@ -397,26 +373,17 @@ object Test extends Properties("HtmlFactory") { } } - property("Should decode symbolic type alias name.") = { + property("SI-4714: Should decode symbolic type alias name.") = { createTemplate("SI_4715.scala") match { case node: scala.xml.Node => { val html = node.toString - html.contains(">: :+:[<") - } - case _ => false - } - } - - property("Shouldn't drop type arguments to aliased tuple.") = { - createTemplate("SI_4676.scala") match { - case node: scala.xml.Node => { - node.toString.contains(">ss: (String, String)<") + html.contains(">:+:<") } case _ => false } } - property("Default arguments of synthesized constructor") = { + property("SI-4287: Default arguments of synthesized constructor") = { val files = createTemplates("SI_4287.scala") files("ClassWithSugar.html") match { @@ -427,7 +394,7 @@ object Test extends Properties("HtmlFactory") { } } - property("Default arguments of synthesized constructor") = { + property("SI-4507: Default arguments of synthesized constructor") = { createTemplate("SI_4507.scala") match { case node: scala.xml.Node => ! node.toString.contains("<li>returns silently when evaluating true and true</li>") @@ -435,40 +402,40 @@ object Test extends Properties("HtmlFactory") { } } - property("Use cases and links should not crash scaladoc") = { + property("SI-4898: Use cases and links should not crash scaladoc") = { createTemplate("SI_4898.scala") true } - property("Use cases should override their original members") = + property("SI-5054: Use cases should override their original members") = checkText("SI_5054_q1.scala")( (None,"""def test(): Int""", true) //Disabled because the full signature is now displayed //(None,"""def test(implicit lost: Int): Int""", false) ) - property("Use cases should keep their flags - final should not be lost") = + property("SI-5054: Use cases should keep their flags - final should not be lost") = checkText("SI_5054_q2.scala")((None, """final def test(): Int""", true)) - property("Use cases should keep their flags - implicit should not be lost") = + property("SI-5054: Use cases should keep their flags - implicit should not be lost") = checkText("SI_5054_q3.scala")((None, """implicit def test(): Int""", true)) - property("Use cases should keep their flags - real abstract should not be lost") = + property("SI-5054: Use cases should keep their flags - real abstract should not be lost") = checkText("SI_5054_q4.scala")((None, """abstract def test(): Int""", true)) - property("Use cases should keep their flags - traits should not be affected") = + property("SI-5054: Use cases should keep their flags - traits should not be affected") = checkText("SI_5054_q5.scala")((None, """def test(): Int""", true)) - property("Use cases should keep their flags - traits should not be affected") = + property("SI-5054: Use cases should keep their flags - traits should not be affected") = checkText("SI_5054_q6.scala")((None, """abstract def test(): Int""", true)) - property("Use case individual signature test") = + property("SI-5054: Use case individual signature test") = checkText("SI_5054_q7.scala")( (None, """abstract def test2(explicit: Int): Int [use case] This takes the explicit value passed.""", true), (None, """abstract def test1(): Int [use case] This takes the implicit value in scope.""", true) ) - property("Display correct \"Definition classes\"") = + property("SI-5287: Display correct \"Definition classes\"") = checkText("SI_5287.scala")( (None, """def method(): Int @@ -477,7 +444,7 @@ object Test extends Properties("HtmlFactory") { Definition Classes SI_5287 SI_5287_B SI_5287_A""", true) ) // the explanation appears twice, as small comment and full comment - property("Correct comment inheritance for overriding") = + property("Comment inheritance: Correct comment inheritance for overriding") = checkText("implicit-inheritance-override.scala")( (Some("Base"), """def function[T](arg1: T, arg2: String): Double @@ -521,7 +488,7 @@ object Test extends Properties("HtmlFactory") { ) for (useCaseFile <- List("UseCaseInheritance", "UseCaseOverrideInheritance")) { - property("Correct comment inheritance for usecases") = + property("Comment inheritance: Correct comment inheritance for usecases") = checkText("implicit-inheritance-usecase.scala")( (Some(useCaseFile), """def missing_arg[T](arg1: T): Double @@ -588,7 +555,7 @@ object Test extends Properties("HtmlFactory") { ) } - property("Correct explicit inheritance for override") = + property("Comment inheritance: Correct explicit inheritance for override") = checkText("explicit-inheritance-override.scala")( (Some("InheritDocDerived"), """def function[T](arg1: T, arg2: String): Double @@ -614,7 +581,7 @@ object Test extends Properties("HtmlFactory") { See also StartSee The Manual EndSee """, true)) - property("Correct explicit inheritance for usecase") = + property("Comment inheritance: Correct explicit inheritance for usecase") = checkText("explicit-inheritance-usecase.scala")( (Some("UseCaseInheritDoc"), """def function[T](arg1: T, arg2: String): Double @@ -639,7 +606,7 @@ object Test extends Properties("HtmlFactory") { See also StartSee The Manual EndSee """, true)) - property("Correct explicit inheritance in corner cases") = + property("Comment inheritance: Correct explicit inheritance in corner cases") = checkText("inheritdoc-corner-cases.scala")( (Some("D"), """def hello1: Int |