All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dotty.tools.dottydoc.model.comment.Comment.scala Maven / Gradle / Ivy

package dotty.tools
package dottydoc
package model
package comment

import dotty.tools.dottydoc.util.syntax._
import dotty.tools.dotc.core.Contexts.{Context, ctx}
import dotty.tools.dotc.util.Spans._
import com.vladsch.flexmark.util.ast.{ Node => MarkdownNode }
import HtmlParsers._
import util.MemberLookup

case class Comment (
  body:                    String,
  short:                   String,
  authors:                 List[String],
  see:                     List[String],
  result:                  Option[String],
  throws:                  Map[String, String],
  valueParams:             Map[String, String],
  typeParams:              Map[String, String],
  version:                 Option[String],
  since:                   Option[String],
  todo:                    List[String],
  deprecated:              Option[String],
  note:                    List[String],
  example:                 List[String],
  constructor:             Option[String],
  group:                   Option[String],
  groupDesc:               Map[String, String],
  groupNames:              Map[String, String],
  groupPrio:               Map[String, String],
  /** List of conversions to hide - containing e.g: `scala.Predef.FloatArrayOps` */
  hideImplicitConversions: List[String]
)

private[comment] case class ParsedComment (
  body:                    String,
  authors:                 List[String],
  see:                     List[String],
  result:                  List[String],
  throws:                  Map[String, String],
  valueParams:             Map[String, String],
  typeParams:              Map[String, String],
  version:                 List[String],
  since:                   List[String],
  todo:                    List[String],
  deprecated:              List[String],
  note:                    List[String],
  example:                 List[String],
  constructor:             List[String],
  group:                   List[String],
  groupDesc:               Map[String, String],
  groupNames:              Map[String, String],
  groupPrio:               Map[String, String],
  hideImplicitConversions: List[String],
  shortDescription:        List[String]
)

trait MarkupConversion[T] extends MemberLookup {
  def ent: Entity
  def span: Span
  def parsed: ParsedComment

  protected def linkedExceptions(m: Map[String, String])(using Context): Map[String, String]
  protected def stringToMarkup(str: String)(using Context): T
  protected def markupToHtml(t: T)(using Context): String
  protected def stringToShortHtml(str: String)(using Context): String
  protected def filterEmpty(xs: List[String])(using Context): List[T]
  protected def filterEmpty(xs: Map[String, String])(using Context): Map[String, T]

  private def single(annot: String, xs: List[String], filter: Boolean = true)(using Context): Option[T] =
    (if (filter) filterEmpty(xs) else xs.map(stringToMarkup)) match {
      case x :: xs =>
        if (xs.nonEmpty) ctx.docbase.warn(
          s"Only allowed to have a single annotation for $annot",
          ent.symbol.sourcePosition(span)
        )
        Some(x)
      case _ => None
    }

  final def comment(using Context): Comment = Comment(
    body                    = markupToHtml(stringToMarkup(parsed.body)),
    short                   = stringToShortHtml(parsed.body),
    authors                 = filterEmpty(parsed.authors).map(markupToHtml),
    see                     = filterEmpty(parsed.see).map(markupToHtml),
    result                  = single("@return", parsed.result).map(markupToHtml),
    throws                  = linkedExceptions(parsed.throws),
    valueParams             = filterEmpty(parsed.valueParams).transform((_, v) => markupToHtml(v)).toMap,
    typeParams              = filterEmpty(parsed.typeParams).transform((_, v) => markupToHtml(v)).toMap,
    version                 = single("@version", parsed.version).map(markupToHtml),
    since                   = single("@since", parsed.since).map(markupToHtml),
    todo                    = filterEmpty(parsed.todo).map(markupToHtml),
    deprecated              = single("@deprecated", parsed.deprecated, filter = false).map(markupToHtml),
    note                    = filterEmpty(parsed.note).map(markupToHtml),
    example                 = filterEmpty(parsed.example).map(markupToHtml),
    constructor             = single("@constructor", parsed.constructor).map(markupToHtml),
    group                   = single("@group", parsed.group).map(markupToHtml),
    groupDesc               = filterEmpty(parsed.groupDesc).transform((_, v) => markupToHtml(v)).toMap,
    groupNames              = filterEmpty(parsed.groupNames).transform((_, v) => markupToHtml(v)).toMap,
    groupPrio               = filterEmpty(parsed.groupPrio).transform((_, v) => markupToHtml(v)).toMap,
    hideImplicitConversions = filterEmpty(parsed.hideImplicitConversions).map(markupToHtml)
  )
}

case class MarkdownComment(ent: Entity, parsed: ParsedComment, span: Span)
extends MarkupConversion[MarkdownNode] {

  def stringToMarkup(str: String)(using Context) =
    str.toMarkdown(ent)

  def stringToShortHtml(str: String)(using Context) =
    str.toMarkdown(ent).shortenAndShow

  def markupToHtml(md: MarkdownNode)(using Context) =
    md.show

  def linkedExceptions(m: Map[String, String])(using Context) = {
    val inlineToHtml = InlineToHtml(ent)
    m.map { case (targetStr, body) =>
      val link = makeEntityLink(ent, ctx.docbase.packages, Monospace(Text(targetStr)), targetStr)
      (targetStr, inlineToHtml(link))
    }
  }

  def filterEmpty(xs: List[String])(using Context) =
    xs.map(_.trim)
      .filterNot(_.isEmpty)
      .map(stringToMarkup)

  def filterEmpty(xs: Map[String, String])(using Context) =
    xs.transform((_, v) => v.trim)
      .filterNot { case (_, v) => v.isEmpty }
      .transform((_, v) => stringToMarkup(v))
}

case class WikiComment(ent: Entity, parsed: ParsedComment, span: Span)
extends MarkupConversion[Body] {

  def filterEmpty(xs: Map[String,String])(using Context) =
    xs.transform((_, v) => v.toWiki(ent, ctx.docbase.packages, span))
      .filterNot { case (_, v) => v.blocks.isEmpty }

  def filterEmpty(xs: List[String])(using Context) =
    xs.map(_.toWiki(ent, ctx.docbase.packages, span))

  def markupToHtml(t: Body)(using Context) =
    t.show(ent)

  def stringToMarkup(str: String)(using Context) =
    str.toWiki(ent, ctx.docbase.packages, span)

  def stringToShortHtml(str: String)(using Context) = {
    val parsed = stringToMarkup(str)
    parsed.summary.getOrElse(parsed).show(ent)
  }

  def linkedExceptions(m: Map[String, String])(using Context) = {
    m.transform((_, v) => v.toWiki(ent, ctx.docbase.packages, span)).map { case (targetStr, body) =>
      val link = lookup(Some(ent), ctx.docbase.packages, targetStr)
      val newBody = body match {
        case Body(List(Paragraph(Chain(content)))) =>
          val descr = Text(" ") +: content
          val link = makeEntityLink(ent, ctx.docbase.packages, Monospace(Text(targetStr)), targetStr)
          Body(List(Paragraph(Chain(link +: descr))))
        case _ => body
      }

      (targetStr, newBody.show(ent))
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy