diff options
Diffstat (limited to 'src/scaladoc')
5 files changed, 64 insertions, 85 deletions
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala index ef0a013ff2..cd1d604843 100755 --- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala @@ -22,7 +22,7 @@ import scala.language.postfixOps trait CommentFactoryBase { this: MemberLookupBase => val global: Global - import global.{ reporter, Symbol } + import global.{ reporter, Symbol, NoSymbol } /* Creates comments with necessary arguments */ def createComment ( @@ -186,7 +186,7 @@ trait CommentFactoryBase { this: MemberLookupBase => * @param comment The expanded comment string (including start and end markers) to be parsed. * @param src The raw comment source string. * @param pos The position of the comment in source. */ - protected def parseAtSymbol(comment: String, src: String, pos: Position, siteOpt: Option[Symbol] = None): Comment = { + protected def parseAtSymbol(comment: String, src: String, pos: Position, site: Symbol = NoSymbol): Comment = { /** The cleaned raw comment as a list of lines. Cleaning removes comment * start and end markers, line start markers and unnecessary whitespace. */ def clean(comment: String): List[String] = { @@ -312,7 +312,7 @@ trait CommentFactoryBase { this: MemberLookupBase => val tagsWithoutDiagram = tags.filterNot(pair => stripTags.contains(pair._1)) val bodyTags: mutable.Map[TagKey, List[Body]] = - mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, pos, siteOpt))} toSeq: _*) + mutable.Map(tagsWithoutDiagram mapValues {tag => tag map (parseWikiAtSymbol(_, pos, site))} toSeq: _*) def oneTag(key: SimpleTagKey): Option[Body] = ((bodyTags remove key): @unchecked) match { @@ -345,7 +345,7 @@ trait CommentFactoryBase { this: MemberLookupBase => } val com = createComment ( - body0 = Some(parseWikiAtSymbol(docBody.toString, pos, siteOpt)), + body0 = Some(parseWikiAtSymbol(docBody.toString, pos, site)), authors0 = allTags(SimpleTagKey("author")), see0 = allTags(SimpleTagKey("see")), result0 = oneTag(SimpleTagKey("return")), @@ -385,14 +385,14 @@ trait CommentFactoryBase { this: MemberLookupBase => * - Removed start-of-line star and one whitespace afterwards (if present). * - Removed all end-of-line whitespace. * - Only `endOfLine` is used to mark line endings. */ - def parseWikiAtSymbol(string: String, pos: Position, siteOpt: Option[Symbol]): Body = new WikiParser(string, pos, siteOpt).document() + def parseWikiAtSymbol(string: String, pos: Position, site: Symbol): Body = new WikiParser(string, pos, site).document() /** TODO * * @author Ingo Maier * @author Manohar Jonnalagedda * @author Gilles Dubochet */ - protected final class WikiParser(val buffer: String, pos: Position, siteOpt: Option[Symbol]) extends CharReader(buffer) { wiki => + protected final class WikiParser(val buffer: String, pos: Position, site: Symbol) extends CharReader(buffer) { wiki => var summaryParsed = false def document(): Body = { @@ -694,7 +694,7 @@ trait CommentFactoryBase { this: MemberLookupBase => case (SchemeUri(uri), optTitle) => Link(uri, optTitle getOrElse Text(uri)) case (qualName, optTitle) => - makeEntityLink(optTitle getOrElse Text(target), pos, target, siteOpt) + makeEntityLink(optTitle getOrElse Text(target), pos, target, site) } } diff --git a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala index 671518fbc6..cc217d2f80 100755 --- a/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala +++ b/src/scaladoc/scala/tools/nsc/doc/base/MemberLookupBase.scala @@ -21,10 +21,10 @@ trait MemberLookupBase { import global._ import rootMirror.{RootPackage, EmptyPackage} - private def isRoot(s: Symbol) = s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass + private def isRoot(s: Symbol) = (s eq NoSymbol) || s.isRootSymbol || s.isEmptyPackage || s.isEmptyPackageClass - def makeEntityLink(title: Inline, pos: Position, query: String, siteOpt: Option[Symbol]) = - new EntityLink(title) { lazy val link = memberLookup(pos, query, siteOpt) } + def makeEntityLink(title: Inline, pos: Position, query: String, site: Symbol) = + new EntityLink(title) { lazy val link = memberLookup(pos, query, site) } private var showExplanation = true private def explanation: String = @@ -45,18 +45,14 @@ trait MemberLookupBase { | - you can use \\# to escape hashes, otherwise they will be considered as delimiters, like dots.""".stripMargin } else "" - def memberLookup(pos: Position, query: String, siteOpt: Option[Symbol]): LinkTo = { + def memberLookup(pos: Position, query: String, site: Symbol): LinkTo = { val members = breakMembers(query) // (1) First look in the root package, as most of the links are qualified val fromRoot = lookupInRootPackage(pos, members) // (2) Or recursively go into each containing template. - val fromParents = siteOpt.fold(Stream.empty[Symbol]) { s => - Stream.iterate(s)(_.owner) - }.takeWhile (!isRoot(_)).map { - lookupInTemplate(pos, members, _) - } + val fromParents = Stream.iterate(site)(_.owner) takeWhile (!isRoot(_)) map (lookupInTemplate(pos, members, _)) val syms = (fromRoot +: fromParents) find (!_.isEmpty) getOrElse Nil diff --git a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala index 574d6b04f8..4e06e5bd16 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/CommentFactory.scala @@ -24,31 +24,20 @@ trait CommentFactory extends base.CommentFactoryBase { thisFactory: ModelFactory with CommentFactory with MemberLookup => val global: Global - import global.{ reporter, definitions, Symbol } + import global.{ reporter, definitions, Symbol, NoSymbol } - protected val commentCache = mutable.HashMap.empty[(Symbol, TemplateImpl), Comment] + protected val commentCache = mutable.HashMap.empty[(Symbol, DocTemplateImpl), Option[Comment]] - def addCommentBody(sym: Symbol, inTpl: TemplateImpl, docStr: String, docPos: global.Position): Symbol = { - commentCache += (sym, inTpl) -> parse(docStr, docStr, docPos, None) - sym - } - - def comment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl): Option[Comment] = { - val key = (sym, inTpl) - if (commentCache isDefinedAt key) - Some(commentCache(key)) - else { - val c = defineComment(sym, currentTpl, inTpl) - if (c isDefined) commentCache += (sym, inTpl) -> c.get - c - } - } + def comment(sym: Symbol, linkTarget: DocTemplateImpl, inTpl: DocTemplateImpl): Option[Comment] = + commentCache.getOrElseUpdate((sym, inTpl), { + defineComment(sym, linkTarget, inTpl) + }) /** A comment is usualy created by the parser, however for some special * cases we have to give some `inTpl` comments (parent class for example) * to the comment of the symbol. * This function manages some of those cases : Param accessor and Primary constructor */ - def defineComment(sym: Symbol, currentTpl: Option[DocTemplateImpl], inTpl: DocTemplateImpl):Option[Comment] = { + def defineComment(sym: Symbol, linkTarget: DocTemplateImpl, inTpl: DocTemplateImpl):Option[Comment] = { //param accessor case // We just need the @param argument, we put it into the body @@ -85,8 +74,7 @@ trait CommentFactory extends base.CommentFactoryBase { else { val rawComment = global.expandedDocComment(sym, inTpl.sym).trim if (rawComment != "") { - val tplOpt = if (currentTpl.isDefined) currentTpl else Some(inTpl) - val c = parse(rawComment, global.rawDocComment(sym), global.docCommentPos(sym), tplOpt) + val c = parse(rawComment, global.rawDocComment(sym), global.docCommentPos(sym), linkTarget) Some(c) } else None @@ -94,9 +82,9 @@ trait CommentFactory extends base.CommentFactoryBase { } - protected def parse(comment: String, src: String, pos: Position, inTplOpt: Option[DocTemplateImpl] = None): Comment = { - assert(!inTplOpt.isDefined || inTplOpt.get != null) - parseAtSymbol(comment, src, pos, inTplOpt map (_.sym)) + protected def parse(comment: String, src: String, pos: Position, linkTarget: DocTemplateImpl): Comment = { + val sym = if (linkTarget eq null) NoSymbol else linkTarget.sym + parseAtSymbol(comment, src, pos, sym) } /** Parses a string containing wiki syntax into a `Comment` object. @@ -105,8 +93,8 @@ trait CommentFactory extends base.CommentFactoryBase { * - Removed start-of-line star and one whitespace afterwards (if present). * - Removed all end-of-line whitespace. * - Only `endOfLine` is used to mark line endings. */ - def parseWiki(string: String, pos: Position, inTplOpt: Option[DocTemplateImpl]): Body = { - assert(!inTplOpt.isDefined || inTplOpt.get != null) - parseWikiAtSymbol(string,pos, inTplOpt map (_.sym)) + def parseWiki(string: String, pos: Position, inTpl: DocTemplateImpl): Body = { + val sym = if (inTpl eq null) NoSymbol else inTpl.sym + parseWikiAtSymbol(string,pos, sym) } } diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala index cc228082c1..60406f4401 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactory.scala @@ -99,22 +99,21 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } abstract class MemberImpl(sym: Symbol, inTpl: DocTemplateImpl) extends EntityImpl(sym, inTpl) with MemberEntity { + // 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 + def linkTarget: DocTemplateImpl = inTpl + lazy val comment = { - // 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 (inTpl != null) thisFactory.comment(sym, thisTpl, inTpl) else None + val documented = if (sym.hasAccessorFlag) sym.accessed else sym + thisFactory.comment(documented, linkTarget, inTpl) } def group = comment flatMap (_.group) getOrElse defaultGroup override def inTemplate = inTpl override def toRoot: List[MemberImpl] = this :: inTpl.toRoot def inDefinitionTemplates = if (inTpl == null) - List(makeRootPackage) + docTemplatesCache(RootPackage) :: Nil else makeTemplate(sym.owner)::(sym.allOverriddenSymbols map { inhSym => makeTemplate(inhSym.owner) }) def visibility = { @@ -152,9 +151,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def deprecation = if (sym.isDeprecated) Some((sym.deprecationMessage, sym.deprecationVersion) match { - case (Some(msg), Some(ver)) => parseWiki("''(Since version " + ver + ")'' " + msg, NoPosition, Some(inTpl)) - case (Some(msg), None) => parseWiki(msg, NoPosition, Some(inTpl)) - case (None, Some(ver)) => parseWiki("''(Since version " + ver + ")''", NoPosition, Some(inTpl)) + case (Some(msg), Some(ver)) => parseWiki("''(Since version " + ver + ")'' " + msg, NoPosition, inTpl) + case (Some(msg), None) => parseWiki(msg, NoPosition, inTpl) + case (None, Some(ver)) => parseWiki("''(Since version " + ver + ")''", NoPosition, inTpl) case (None, None) => Body(Nil) }) else @@ -162,9 +161,9 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { def migration = if(sym.hasMigrationAnnotation) Some((sym.migrationMessage, sym.migrationVersion) match { - case (Some(msg), Some(ver)) => parseWiki("''(Changed in version " + ver + ")'' " + msg, NoPosition, Some(inTpl)) - case (Some(msg), None) => parseWiki(msg, NoPosition, Some(inTpl)) - case (None, Some(ver)) => parseWiki("''(Changed in version " + ver + ")''", NoPosition, Some(inTpl)) + case (Some(msg), Some(ver)) => parseWiki("''(Changed in version " + ver + ")'' " + msg, NoPosition, inTpl) + case (Some(msg), None) => parseWiki(msg, NoPosition, inTpl) + case (None, Some(ver)) => parseWiki("''(Changed in version " + ver + ")''", NoPosition, inTpl) case (None, None) => Body(Nil) }) else @@ -220,7 +219,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { (name + tParams(this) + defParams(this) +":"+ resultType.name).replaceAll("\\s","") // no spaces allowed, they break links } // these only apply for NonTemplateMemberEntities - def useCaseOf: Option[MemberEntity] = None + def useCaseOf: Option[MemberImpl] = None def byConversion: Option[ImplicitConversionImpl] = None def isImplicitlyInherited = false def isShadowedImplicit = false @@ -275,6 +274,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { if (settings.verbose) inform("Creating doc template for " + sym) + override def linkTarget: DocTemplateImpl = this override def toRoot: List[DocTemplateImpl] = this :: inTpl.toRoot protected def inSourceFromSymbol(symbol: Symbol) = @@ -392,7 +392,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { outgoingImplicitlyConvertedClasses // the members generated by the symbols in memberSymsEager PLUS the members from the usecases - val allMembers = ownMembers ::: ownMembers.flatMap(_.useCaseOf.map(_.asInstanceOf[MemberImpl])).distinct + val allMembers = ownMembers ::: ownMembers.flatMap(_.useCaseOf).distinct implicitsShadowing = makeShadowingTable(allMembers, conversions, this) // finally, add the members generated by implicit conversions members :::= conversions.flatMap(_.memberImpls) @@ -484,21 +484,22 @@ 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, conversion: Option[ImplicitConversionImpl], - override val useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl) + override val useCaseOf: Option[MemberImpl], inTpl: DocTemplateImpl) extends MemberImpl(sym, inTpl) with NonTemplateMemberEntity { override lazy val comment = { - val inRealTpl = - conversion.fold(Option(inTpl)) { conv => - /* 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 - */ - findTemplateMaybe(conv.toType.typeSymbol) filterNot (_ == makeRootPackage) orElse ( - findTemplateMaybe(sym.owner) filterNot (_ == makeRootPackage) orElse Option(inTpl) - ) - } - inRealTpl flatMap (thisFactory.comment(sym, None, _)) + def nonRootTemplate(sym: Symbol): Option[DocTemplateImpl] = + if (sym eq RootPackage) None else findTemplateMaybe(sym) + /* 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 + */ + val inRealTpl = conversion.flatMap { conv => + nonRootTemplate(conv.toType.typeSymbol) + } orElse nonRootTemplate(sym.owner) orElse Option(inTpl) + inRealTpl flatMap { tpl => + thisFactory.comment(sym, tpl, tpl) + } } override def inDefinitionTemplates = useCaseOf.fold(super.inDefinitionTemplates)(_.inDefinitionTemplates) @@ -517,7 +518,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { } abstract class NonTemplateParamMemberImpl(sym: Symbol, conversion: Option[ImplicitConversionImpl], - useCaseOf: Option[MemberEntity], inTpl: DocTemplateImpl) + useCaseOf: Option[MemberImpl], inTpl: DocTemplateImpl) extends NonTemplateMemberImpl(sym, conversion, useCaseOf, inTpl) { def valueParams = { val info = conversion.fold(sym.info)(_.toType memberInfo sym) @@ -630,7 +631,7 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { import Streamable._ Path(settings.docRootContent.value) match { case f : File => { - val rootComment = closing(f.inputStream())(is => parse(slurp(is), "", NoPosition, Option(inTpl))) + val rootComment = closing(f.inputStream())(is => parse(slurp(is), "", NoPosition, inTpl)) Some(rootComment) } case _ => None @@ -738,16 +739,12 @@ 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, conversion: Option[ImplicitConversionImpl], inTpl: DocTemplateImpl): List[MemberImpl] = { def makeMember0(bSym: Symbol, useCaseOf: Option[MemberImpl]): Option[MemberImpl] = { if (bSym.isGetter && bSym.isLazy) 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 }) else if (bSym.isGetter && bSym.accessed.isMutable) @@ -1041,4 +1038,3 @@ class ModelFactory(val global: Global, val settings: doc.Settings) { { val rawComment = global.expandedDocComment(bSym, inTpl.sym) rawComment.contains("@template") || rawComment.contains("@documentable") } } - diff --git a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala index 6cefe34887..4fd8fd4270 100644 --- a/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala +++ b/src/scaladoc/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala @@ -332,13 +332,12 @@ trait ModelFactoryImplicitSupport { def targetType: TypeEntity = makeType(toType, inTpl) - def convertorOwner: TemplateEntity = - if (convSym != NoSymbol) - makeTemplate(convSym.owner) - else { + def convertorOwner: TemplateEntity = { + if (convSym eq NoSymbol) error("Scaladoc implicits: " + toString + " = NoSymbol!") - makeRootPackage - } + + makeTemplate(convSym.owner) + } def targetTypeComponents: List[(TemplateEntity, TypeEntity)] = makeParentTypes(toType, None, inTpl) |