diff --git a/scala3doc-testcases/src/tests/deprecated.scala b/scala3doc-testcases/src/tests/deprecated.scala new file mode 100644 index 000000000000..fc9e785bf9cf --- /dev/null +++ b/scala3doc-testcases/src/tests/deprecated.scala @@ -0,0 +1,19 @@ +package tests +package deprecated + +class A: + def defInt: Int = 1 + @deprecated(message = "1") + def def1: 1 = 1 + @deprecated("reason") + val valInt: Int = 1 + val val1: 1 = 1 + var varInt: Int = 1 + var var1: 1 = 1 + class InnerA: + val innerVal: Int = 1 + +class B extends A: + @deprecated(since = "1", message = "some reason") + def x: Int = 1 + val y: Int = 1 diff --git a/scala3doc/resources/dotty_res/styles/scalastyle.css b/scala3doc/resources/dotty_res/styles/scalastyle.css index 0a6bc81e8beb..6dc9acbac35d 100644 --- a/scala3doc/resources/dotty_res/styles/scalastyle.css +++ b/scala3doc/resources/dotty_res/styles/scalastyle.css @@ -292,6 +292,9 @@ th { padding-top: 0; } +span[data-unresolved-link].strikethrough, a.strikethrough, div.strikethrough { + text-decoration: line-through; +} .brief { white-space: pre-wrap; overflow: hidden; diff --git a/scala3doc/src/dotty/dokka/model/api/api.scala b/scala3doc/src/dotty/dokka/model/api/api.scala index a1863465fb1d..7bd113d64159 100644 --- a/scala3doc/src/dotty/dokka/model/api/api.scala +++ b/scala3doc/src/dotty/dokka/model/api/api.scala @@ -80,10 +80,12 @@ enum Origin: case class Annotation(val dri: DRI, val params: List[Annotation.AnnotationParameter]) object Annotation: - sealed trait AnnotationParameter - case class PrimitiveParameter(val name: Option[String] = None, val value: String) extends AnnotationParameter - case class LinkParameter(val name: Option[String] = None, val dri: DRI, val value: String) extends AnnotationParameter - case class UnresolvedParameter(val name: Option[String] = None, val unresolvedText: String) extends AnnotationParameter + sealed trait AnnotationParameter { + val name: Option[String] + } + case class PrimitiveParameter(name: Option[String] = None, value: String) extends AnnotationParameter + case class LinkParameter(name: Option[String] = None, dri: DRI, value: String) extends AnnotationParameter + case class UnresolvedParameter(name: Option[String] = None, unresolvedText: String) extends AnnotationParameter // TODO (longterm) properly represent signatures case class Link(name: String, dri: DRI) @@ -124,6 +126,7 @@ extension[T] (member: Member): def signature: Signature = memberExt.fold(Signature(name))(_.signature) def asLink: LinkToType = LinkToType(signature, dri, kind) + def deprecated: Option[Annotation] = memberExt.flatMap(_.annotations.find(a => a.dri.getPackageName == "scala" && a.dri.getClassNames == "deprecated")) def modifiers: Seq[dotty.dokka.model.api.Modifier] = memberExt.fold(Nil)(_.modifiers) def kind: Kind = memberExt.fold(Kind.Unknown)(_.kind) diff --git a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala index d6236a3f3631..861de2d75a46 100644 --- a/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala +++ b/scala3doc/src/dotty/dokka/model/api/internalExtensions.scala @@ -24,7 +24,7 @@ private [model] case class MemberExtension( visibility: Visibility, modifiers: Seq[dotty.dokka.model.api.Modifier], kind: Kind, - val annotations: List[Annotation], + annotations: List[Annotation], signature: Signature, sources: Option[TastyDocumentableSource] = None, origin: Origin = Origin.DefinedWithin, diff --git a/scala3doc/src/dotty/dokka/model/scalaModel.scala b/scala3doc/src/dotty/dokka/model/scalaModel.scala index 0973bb5c8d4b..b01f615e24c2 100644 --- a/scala3doc/src/dotty/dokka/model/scalaModel.scala +++ b/scala3doc/src/dotty/dokka/model/scalaModel.scala @@ -88,10 +88,15 @@ abstract class ScalaContentNode(params: ContentNodeParams) extends ContentNode: override def getExtra = params.extra override def withNewExtras(p: PropertyContainer[ContentNode]) = newInstance(params.copy(extra = p)) +case class DocumentableNameWithStyles( + name: String, + styles: Set[Style] = Set.empty, +) + case class DocumentableElement( annotations: Signature, modifiers: Signature, - name: String, + nameWithStyles: DocumentableNameWithStyles, signature: Signature, brief: Seq[ContentNode], originInfo: Signature, diff --git a/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala b/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala index 610a318a6f2f..a0b6a3e45349 100644 --- a/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala +++ b/scala3doc/src/dotty/dokka/site/PartiallyRenderedContent.scala @@ -40,23 +40,3 @@ case class PartiallyRenderedContent( } }// forrach does not work here document.outerHtml() - - -class A: - def defInt: Int = 1 - def def1: 1 = 1 - val valInt: Int = 1 - val val1: 1 = 1 - var varInt: Int = 1 - var var1: 1 = 1 - -object X: - def x: Int = 1 - val x2: 1 = 1 - var x3: Int = 1 - -class B: - val a = new A - export a._ - export X._ - diff --git a/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala b/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala index 2b59f5ff13f5..66aba7313cab 100644 --- a/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala +++ b/scala3doc/src/dotty/dokka/tasty/BasicSupport.scala @@ -17,16 +17,17 @@ trait BasicSupport: val dri = annotTerm.tpe.typeSymbol.dri val params = annotTerm match case Apply(target, appliedWith) => { - appliedWith.map { - case Literal(constant) => Annotation.PrimitiveParameter(None, constant.value match { + appliedWith.flatMap { + case Literal(constant) => Some(Annotation.PrimitiveParameter(None, constant.value match { case s: String => "\"" + s"$s" + "\"" case other => other.toString() - }) - case Select(qual, name) => - val dri = qual.tpe.termSymbol.companionClass.dri - Annotation.LinkParameter(None, dri, s"${dri.getClassNames}.$name") // TODO this is a nasty hack! - - case other => Annotation.UnresolvedParameter(None, other.show) + })) + case NamedArg(name, Literal(constant)) => Some(Annotation.PrimitiveParameter(Some(name), constant.value match + case s: String => "\"" + s"$s" + "\"" + case other => other.toString() + )) + case x @ Select(qual, name) => None + case other => Some(Annotation.UnresolvedParameter(None, other.show)) } } diff --git a/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala b/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala index 71d49b4a03b9..1baa6ce6e7c4 100644 --- a/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala +++ b/scala3doc/src/dotty/dokka/translators/ScalaContentBuilder.scala @@ -496,11 +496,11 @@ class ScalaPageContentBuilder( Signature("Exported from ", signatureName) case _ => Nil } - + val styles: Set[Style] = if documentable.deprecated.isDefined then Set(TextStyle.Strikethrough) else Set.empty DocumentableElement( buildAnnotations(documentable), signatureBuilder.preName.reverse, - documentable.getName, + DocumentableNameWithStyles(documentable.getName, styles), signatureBuilder.names.reverse, docs.fold(Nil)(d => reset().rawComment(d.getRoot)), originInfo, diff --git a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala index 55737a4ff25d..7fafa8f389b8 100644 --- a/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala +++ b/scala3doc/src/dotty/dokka/translators/ScalaPageCreator.scala @@ -323,14 +323,34 @@ class ScalaPageCreator( case _ => withCompanion } - d match + val withSource = d match case null => withExtensionInformation case m: Member => sourceLinks.pathTo(m).fold(withCompanion){ link => val sourceSets = m.getSourceSets.asScala.toSet withExtensionInformation.cell(sourceSets = sourceSets)(_.text("Source")) .cell(sourceSets = sourceSets)(_.resolvedLink("(source)", link)) + } + + d.deprecated match + case None => withSource + case Some(a) => + extension (b: ScalaPageContentBuilder#ScalaDocumentableContentBuilder) + def annotationParameter(p: Option[Annotation.AnnotationParameter]): ScalaPageContentBuilder#ScalaDocumentableContentBuilder = + p match + case Some(Annotation.PrimitiveParameter(_, value)) => b.text(value.stripPrefix("\"").stripSuffix("\"")) + case Some(Annotation.LinkParameter(_, dri, text)) => b.driLink(text.stripPrefix("\"").stripSuffix("\""), dri) + case Some(Annotation.UnresolvedParameter(_, value)) => b.text(value.stripPrefix("\"").stripSuffix("\"")) + case _ => b + val since = a.params.find(_.name.contains("since")) + val message = a.params.find(_.name.contains("message")) + val sourceSets = d.getSourceSets.asScala.toSet + withSource.cell(sourceSets = sourceSets)(_.text("Deprecated")) + .cell(sourceSets = sourceSets) { b => + val withPossibleSince = if (since.isDefined) b.text("(Since version ").annotationParameter(since).text(") ") else b + withPossibleSince.annotationParameter(message) + } } } } diff --git a/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala b/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala index 83c614ab1b4b..4f67e8911339 100644 --- a/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala +++ b/scala3doc/src/dotty/dokka/translators/ScalaSignatureProvider.scala @@ -22,7 +22,9 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge private def signatureContent(d: Documentable)( func: ScalaPageContentBuilder#ScalaDocumentableContentBuilder => ScalaPageContentBuilder#ScalaDocumentableContentBuilder - ) = contentBuilder.contentForDocumentable(d, kind = ContentKind.Symbol, styles = styles, buildBlock = func) + ) = + val styles = stylesIfDeprecated(d) + contentBuilder.contentForDocumentable(d, kind = ContentKind.Symbol, styles = styles, buildBlock = func) case class ContentNodeBuilder(builder: ScalaPageContentBuilder#ScalaDocumentableContentBuilder) extends SignatureBuilder{ @@ -42,6 +44,10 @@ class ScalaSignatureProvider(contentConverter: CommentsToContentConverter, logge res.asInstanceOf[ContentNodeBuilder].builder }) + private def stylesIfDeprecated(m: Member): Set[Style] = + if m.deprecated.isDefined then styles ++ Set(TextStyle.Strikethrough) else styles + + object ScalaSignatureProvider: def rawSignature(documentable: Documentable, builder: SignatureBuilder): SignatureBuilder = documentable match diff --git a/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala b/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala index c6e9fab30846..30384ee39d1f 100644 --- a/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala +++ b/scala3doc/src/dotty/dokka/translators/ScalaSignatureUtils.scala @@ -55,7 +55,7 @@ trait SignatureBuilder extends ScalaSignatureUtils { else this private def addParameterName(txt: Option[String]): SignatureBuilder = txt match { - case Some(name) => this.text(s"$txt = ") + case Some(name) => this.text(s"$name = ") case _ => this } diff --git a/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala b/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala index 5dff012f4afe..a802da443748 100644 --- a/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala +++ b/scala3doc/src/dotty/renderers/ScalaHtmlRenderer.scala @@ -85,7 +85,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext, args: Args) extends HtmlRenderer(ctx) } override def wrapGroup(f: FlowContent, node: ContentGroup, pageContext: ContentPage, childrenCallback: FlowContentConsumer) = { - val additionalClasses = node.getStyle.asScala.map(_.toString.toLowerCase).mkString("", ",", "") + val additionalClasses = node.getStyle.asScala.map(_.toString.toLowerCase).mkString("", " ", "") def buildSymbol: String = div(cls := s"symbol $additionalClasses")( raw( buildWithKotlinx(childrenCallback).toString @@ -134,7 +134,7 @@ class ScalaHtmlRenderer(ctx: DokkaContext, args: Args) extends HtmlRenderer(ctx) span(cls := "other-modifiers")(otherModifiers.map(renderElement)), span(cls := "kind")(kind.map(renderElement)), ), - renderLink(element.name, element.params.dri, cls := "documentableName monospace"), + renderLink(element.nameWithStyles.name, element.params.dri, cls := s"documentableName monospace ${element.nameWithStyles.styles.map(_.toString.toLowerCase).mkString(" ")}"), span(cls := "signature monospace")(element.signature.map(renderElement)), div( div(cls := "originInfo")(element.originInfo.map(renderElement)), diff --git a/scala3doc/test/dotty/dokka/SignatureTest.scala b/scala3doc/test/dotty/dokka/SignatureTest.scala index 9b2df12091ae..8d4b055f89fd 100644 --- a/scala3doc/test/dotty/dokka/SignatureTest.scala +++ b/scala3doc/test/dotty/dokka/SignatureTest.scala @@ -103,7 +103,7 @@ abstract class SignatureTest( case c: ContentComposite => c.getChildren.asScala.flatMap(flattenToText).toSeq case l: DocumentableElement => - (l.annotations ++ Seq(" ") ++ l.modifiers ++ Seq(l.name) ++ l.signature).map { + (l.annotations ++ Seq(" ") ++ l.modifiers ++ Seq(l.nameWithStyles.name) ++ l.signature).map { case s: String => s case Link(s: String, _) => s }