diff options
Diffstat (limited to 'src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala')
-rw-r--r-- | src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala | 120 |
1 files changed, 102 insertions, 18 deletions
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala index e3c94505ab..28304e76c7 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/IndexScript.scala @@ -1,21 +1,26 @@ /* NSC -- new Scala compiler - * Copyright 2007-2013 LAMP/EPFL - * @author David Bernard, Manohar Jonnalagedda + * Copyright 2007-2016 LAMP/EPFL + * @author David Bernard, Manohar Jonnalagedda, Felix Mulder */ -package scala.tools.nsc.doc.html.page +package scala.tools.nsc.doc +package html +package page import scala.tools.nsc.doc import scala.tools.nsc.doc.model.{Package, DocTemplateEntity} import scala.tools.nsc.doc.html.{Page, HtmlFactory} -import scala.util.parsing.json.{JSONObject, JSONArray} -class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { +class IndexScript(universe: doc.Universe) extends Page { + import model._ + import scala.tools.nsc.doc.base.comment.Text + import scala.collection.immutable.Map + def path = List("index.js") override def writeFor(site: HtmlFactory) { writeFile(site) { - _.write("Index.PACKAGES = " + packages.toString() + ";") + _.write(s"Index.PACKAGES = $packages;") } } @@ -24,33 +29,46 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { case (pack, templates) => { val merged = mergeByQualifiedName(templates) - val ary = merged.keys.toList.sortBy(_.toLowerCase).map(key => { - val pairs = merged(key).map( - t => kindToString(t) -> relativeLinkTo(t) - ) :+ ("name" -> key) + val ary = merged.keys.toVector.sortBy(_.toLowerCase).map { key => + /** One pair is generated for the class/trait and one for the + * companion object, both will have the same {"name": key} + * + * As such, we need to distinguish between the members that are + * generated by the object, and the members generated by the + * class/trait instance. Otherwise one of the member objects will be + * overwritten. + */ + val pairs = merged(key).flatMap { t: DocTemplateEntity => + val kind = kindToString(t) + Seq( + kind -> relativeLinkTo(t), + "kind" -> kind, + s"members_$kind" -> membersToJSON(t.members.toVector.filter(!_.isShadowedOrAmbiguousImplicit), t), + "shortDescription" -> shortDesc(t)) + } - JSONObject(scala.collection.immutable.Map(pairs : _*)) - }) + JSONObject(Map(pairs : _*) + ("name" -> key)) + } pack.qualifiedName -> JSONArray(ary) } }).toSeq - JSONObject(scala.collection.immutable.Map(pairs : _*)) + JSONObject(Map(pairs : _*)) } - def mergeByQualifiedName(source: List[DocTemplateEntity]) = { - var result = Map[String, List[DocTemplateEntity]]() + private def mergeByQualifiedName(source: List[DocTemplateEntity]): collection.mutable.Map[String, List[DocTemplateEntity]] = { + val result = collection.mutable.Map[String, List[DocTemplateEntity]]() for (t <- source) { val k = t.qualifiedName - result += k -> (result.getOrElse(k, List()) :+ t) + result += k -> (result.getOrElse(k, Nil) :+ t) } result } - def allPackages = { + def allPackages: List[Package] = { def f(parent: Package): List[Package] = { parent.packages.flatMap( p => f(p) :+ p @@ -59,11 +77,77 @@ class IndexScript(universe: doc.Universe, index: doc.Index) extends Page { f(universe.rootPackage).sortBy(_.toString) } - def allPackagesWithTemplates = { + def allPackagesWithTemplates: Map[Package, List[DocTemplateEntity]] = { Map(allPackages.map((key) => { key -> key.templates.collect { case t: DocTemplateEntity if !t.isPackage && !universe.settings.hardcoded.isExcluded(t.qualifiedName) => t } }) : _*) } + + /** Gets the short description i.e. the first sentence of the docstring */ + def shortDesc(mbr: MemberEntity): String = mbr.comment.fold("") { c => + Page.inlineToStr(c.short).replaceAll("\n", "") + } + + /** Returns the json representation of the supplied members */ + def membersToJSON(entities: Vector[MemberEntity], parent: DocTemplateEntity): JSONArray = + JSONArray(entities.map(memberToJSON(_, parent))) + + private def memberToJSON(mbr: MemberEntity, parent: DocTemplateEntity): JSONObject = { + /** This function takes a member and gets eventual parameters and the + * return type. For example, the definition: + * {{{ def get(key: A): Option[B] }}} + * Gets turned into: "(key: A): Option[B]" + */ + def memberTail: MemberEntity => String = { + case d: Def => d + .valueParams //List[List[ValueParam]] + .map { params => + params.map(p => p.name + ": " + p.resultType.name).mkString(", ") + } + .mkString("(", ")(", "): " + d.resultType.name) + case v: Val => ": " + v.resultType.name + case _ => "" + } + + /** This function takes a member entity and return all modifiers in a + * string, example: + * {{{ lazy val scalaProps: java.util.Properties }}} + * Gets turned into: "lazy val" + */ + def memberKindToString(mbr: MemberEntity): String = { + val kind = mbr.flags.map(_.text.asInstanceOf[Text].text).mkString(" ") + val space = if (kind == "") "" else " " + + kind + space + kindToString(mbr) + } + + /** This function turns a member entity into a JSON object that the index.js + * script can use to render search results + */ + def jsonObject(m: MemberEntity): JSONObject = + JSONObject(Map( + "label" -> "[^\\.]*\\.([^#]+#)?".r.replaceAllIn(m.definitionName, ""), // member name + "member" -> m.definitionName.replaceFirst("#", "."), // full member name + "tail" -> memberTail(m), + "kind" -> memberKindToString(m), // modifiers i.e. "abstract def" + "link" -> memberToUrl(m))) // permalink to the member + + mbr match { + case x @ (_: Def | _: Val | _: Object | _: AliasType) => jsonObject(x) + case e @ (_: Class | _: Trait) if parent.isRootPackage || !parent.isPackage => jsonObject(e) + case m: MemberEntity => + JSONObject(Map("member" -> m.definitionName, "error" -> "unsupported entity")) + } + } + + def memberToUrl(mbr: MemberEntity): String = { + val path = templateToPath(mbr.inTemplate).reverse.mkString("/") + s"$path#${mbr.signature}" + } +} + +object IndexScript { + def apply(universe: doc.Universe) = new IndexScript(universe) } |