diff --git a/project/Build.scala b/project/Build.scala index c0c3b9dec320..59180ba22e20 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -1801,6 +1801,10 @@ object ScaladocConfigs { .add(Revision("main")) .add(SnippetCompiler(List("scaladoc-testcases/docs=compile"))) .add(SiteRoot("scaladoc-testcases/docs")) + .add(CommentSyntax(List( + "scaladoc-testcases/src/example/comment-md=markdown", + "scaladoc-testcases/src/example/comment-wiki=wiki" + ))) .add(ExternalMappings(List(dottyExternalMapping, javaExternalMapping))) .withTargets(tastyRoots) } @@ -1830,7 +1834,10 @@ object ScaladocConfigs { .add(Revision("main")) .add(ExternalMappings(List(javaExternalMapping))) .add(DocRootContent(docRootFile.toString)) - .add(CommentSyntax("wiki")) + .add(CommentSyntax(List( + s"${dottyLibRoot}=markdown", + s"${stdLibRoot}=wiki" + ))) .add(VersionsDictionaryUrl("https://scala-lang.org/api/versions.json")) .add(DocumentSyntheticTypes(true)) .add(SnippetCompiler(List( diff --git a/project/ScaladocGeneration.scala b/project/ScaladocGeneration.scala index 9c28bd74a0b4..b5f75211ea36 100644 --- a/project/ScaladocGeneration.scala +++ b/project/ScaladocGeneration.scala @@ -45,7 +45,7 @@ object ScaladocGeneration { def key: String = "-source-links" } - case class CommentSyntax(value: String) extends Arg[String] { + case class CommentSyntax(value: List[String]) extends Arg[List[String]] { def key: String = "-comment-syntax" } diff --git a/project/scripts/cmdScaladocTests b/project/scripts/cmdScaladocTests index ff25bc6a3940..c22e7c1a09ed 100755 --- a/project/scripts/cmdScaladocTests +++ b/project/scripts/cmdScaladocTests @@ -35,6 +35,7 @@ dist/target/pack/bin/scaladoc \ "-skip-by-id:scala.runtime.stdLibPatches" \ "-skip-by-id:scala.runtime.MatchCase" \ "-snippet-compiler:scaladoc-testcases/docs=compile" \ + "-comment-syntax:scaladoc-testcases/src/example/comment-md=markdown,scaladoc-testcases/src/example/comment-wiki=wiki" \ -siteroot scaladoc-testcases/docs \ -project-footer "Copyright (c) 2002-2022, LAMP/EPFL" \ -default-template static-site-main \ diff --git a/scaladoc-testcases/src/example/comment-md/CommentExample.scala b/scaladoc-testcases/src/example/comment-md/CommentExample.scala new file mode 100644 index 000000000000..2b6553fe2353 --- /dev/null +++ b/scaladoc-testcases/src/example/comment-md/CommentExample.scala @@ -0,0 +1,6 @@ +package example.comment.md +/** + * # markdown header + * Markdown syntax is used here. + */ +object CommentExample diff --git a/scaladoc-testcases/src/example/comment-wiki/CommentExample.scala b/scaladoc-testcases/src/example/comment-wiki/CommentExample.scala new file mode 100644 index 000000000000..5edeeaf2bc9d --- /dev/null +++ b/scaladoc-testcases/src/example/comment-wiki/CommentExample.scala @@ -0,0 +1,6 @@ +package example.comment.wiki +/** + * = wiki header = + * Wiki syntax is used here. + */ +object CommentExample diff --git a/scaladoc/src/dotty/tools/scaladoc/DocContext.scala b/scaladoc/src/dotty/tools/scaladoc/DocContext.scala index a10be62644f3..64c072aa3de3 100644 --- a/scaladoc/src/dotty/tools/scaladoc/DocContext.scala +++ b/scaladoc/src/dotty/tools/scaladoc/DocContext.scala @@ -74,6 +74,8 @@ case class NavigationNode(name: String, dri: DRI, nested: Seq[NavigationNode]) case class DocContext(args: Scaladoc.Args, compilerContext: CompilerContext): lazy val sourceLinks = SourceLinks.load(args.sourceLinks, args.revision)(using compilerContext) + lazy val commentSyntaxArgs = tasty.comments.CommentSyntaxArgs.load(args.defaultSyntax)(using compilerContext) + lazy val snippetCompilerArgs = snippets.SnippetCompilerArgs.load(args.snippetCompiler)(using compilerContext) lazy val snippetChecker = snippets.SnippetChecker(args)(using compilerContext) diff --git a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala index 154209b5e1e5..0b746f19035b 100644 --- a/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala +++ b/scaladoc/src/dotty/tools/scaladoc/Scaladoc.scala @@ -18,18 +18,6 @@ import dotty.tools.scaladoc.Inkuire import dotty.tools.scaladoc.Inkuire._ object Scaladoc: - enum CommentSyntax: - case Wiki - case Markdown - - object CommentSyntax: - def parse(str: String) = str match - case "wiki" => Some(CommentSyntax.Wiki) - case "markdown" => Some(CommentSyntax.Markdown) - case _ => None - - val default = CommentSyntax.Markdown - case class Args( name: String, tastyDirs: Seq[File] = Nil, @@ -41,7 +29,7 @@ object Scaladoc: projectVersion: Option[String] = None, projectLogo: Option[String] = None, projectFooter: Option[String] = None, - defaultSyntax: CommentSyntax = CommentSyntax.Markdown, + defaultSyntax: List[String] = Nil, sourceLinks: List[String] = Nil, revision: Option[String] = None, externalMappings: List[ExternalDocLink] = Nil, @@ -164,12 +152,6 @@ object Scaladoc: report.warning("Destination is not provided, please provide '-d' parameter pointing to directory where docs should be created") File("output") - val parseSyntax: CommentSyntax = syntax.nonDefault.fold(CommentSyntax.default){ str => - CommentSyntax.parse(str).getOrElse{ - report.error(s"unrecognized value for -syntax option: $str") - CommentSyntax.default - } - } val legacySourceLinkList = if legacySourceLink.get.nonEmpty then List(legacySourceLink.get) else Nil val externalMappings = @@ -219,7 +201,7 @@ object Scaladoc: projectVersion.nonDefault, projectLogo.nonDefault, projectFooter.nonDefault, - parseSyntax, + syntax.get, sourceLinks.get ++ legacySourceLinkList, revision.nonDefault, externalMappings ++ legacyExternalMappings, diff --git a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala index 0d6bc60f281a..c1e7ead9950f 100644 --- a/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala +++ b/scaladoc/src/dotty/tools/scaladoc/ScaladocSettings.scala @@ -40,8 +40,8 @@ class ScaladocSettings extends SettingGroup with AllScalaSettings: val legacySourceLink: Setting[String] = StringSetting("-doc-source-url", "sources", "Legacy option from Scala 2. Use -source-links instead.", "") - val syntax: Setting[String] = - StringSetting("-comment-syntax", "syntax", "Syntax of the comment used", "") + val syntax: Setting[List[String]] = + MultiStringSetting("-comment-syntax", "syntax", tasty.comments.CommentSyntaxArgs.usage) val revision: Setting[String] = StringSetting("-revision", "revision", "Revision (branch or ref) used to build project project", "") diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/ScalaDocSupport.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/ScalaDocSupport.scala index 1c634df8c918..6f829ea570e5 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/ScalaDocSupport.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/ScalaDocSupport.scala @@ -3,8 +3,8 @@ package tasty import scala.jdk.CollectionConverters._ -import dotty.tools.scaladoc.Scaladoc.CommentSyntax -import dotty.tools.scaladoc.tasty.comments.Comment +import dotty.tools.scaladoc.tasty.comments.{Comment, CommentSyntax} +import dotty.tools.scaladoc.tasty.SymOps.source import scala.quoted._ @@ -14,17 +14,23 @@ object ScaladocSupport: import reflect.report val preparsed = comments.Preparser.preparse(comments.Cleaner.clean(comment)) + def pathBasedCommentSyntax(): CommentSyntax = + val path = sym.source.map(_.path) + summon[DocContext].commentSyntaxArgs.get(path) + val commentSyntax = preparsed.syntax.headOption match { case Some(commentSetting) => - CommentSyntax.parse(commentSetting).getOrElse { - val msg = s"not a valid comment syntax: $commentSetting, defaulting to Markdown syntax." + CommentSyntax.CommentSyntaxParser.parse(commentSetting).getOrElse { + val defaultSyntax = pathBasedCommentSyntax() + val msg = s"not a valid comment syntax: $commentSetting, defaulting to ${defaultSyntax} syntax." // we should update pos with span from documentation pos.fold(report.warning(msg))(report.warning(msg, _)) - CommentSyntax.default + defaultSyntax } - case None => summon[DocContext].args.defaultSyntax + case None => + pathBasedCommentSyntax() } val parser = commentSyntax match { diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/CommentSyntaxArgs.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/CommentSyntaxArgs.scala new file mode 100644 index 000000000000..65bacba3cd2d --- /dev/null +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/CommentSyntaxArgs.scala @@ -0,0 +1,55 @@ +package dotty.tools.scaladoc +package tasty.comments + +import java.nio.file.Path + +enum CommentSyntax: + case Wiki + case Markdown + +object CommentSyntax: + object CommentSyntaxParser extends ArgParser[CommentSyntax]: + def parse(s: String): Either[String, CommentSyntax] = s match + case "wiki" => Right(CommentSyntax.Wiki) + case "markdown" => Right(CommentSyntax.Markdown) + case _ => Left(s"No such syntax found.") + + val default = CommentSyntax.Markdown + +case class CommentSyntaxArgs(csFormats: PathBased[CommentSyntax]): + def get(path: Option[Path]): CommentSyntax = + path + .flatMap(p => csFormats.get(p).map(_.elem)) + .getOrElse(CommentSyntax.default) + +object CommentSyntaxArgs: + val usage = + """ + |Comment Syntax arguments provide a way to set comment syntax for specified paths. + | + |This setting accepts list of arguments in format: + |args := arg{,arg} + |arg := [path=]syntax + |where `path` is a prefix of the path to source files that will have a specific comment syntax set and `syntax` specifies the one used. + | + |If the path is not present, the argument will be used as the default for all unmatched paths. + | + |Available syntaxes: + |markdown + |wiki + | + """.stripMargin + + def load(args: List[String])(using CompilerContext): CommentSyntaxArgs = { + PathBased.parse[CommentSyntax](args)(using CommentSyntax.CommentSyntaxParser) match { + case PathBased.ParsingResult(errors, res) => + if errors.nonEmpty then report.warning(s""" + |Got following errors during comment syntax args parsing: + |$errors + | + |$usage + |""".stripMargin + ) + CommentSyntaxArgs(res) + } + } \ No newline at end of file