diff --git a/scaladoc-testcases/docs/_docs/index.md b/scaladoc-testcases/docs/_docs/index.md index 9acac71a63b3..f11b5d31b7dd 100644 --- a/scaladoc-testcases/docs/_docs/index.md +++ b/scaladoc-testcases/docs/_docs/index.md @@ -22,3 +22,14 @@ val renderer: Renderer = Renderer() extension (x: Self) def combine(y: Self): Self ``` +```scala sc:fail sc-opts:-Werror:true +def exampleShouldError(input: Option[String]): Unit = + input match + case Some("foo") => ??? +``` + +```scala sc:compile sc-opts:-Werror:false +def exampleShouldWarn(input: Option[String]): Unit = + input match + case Some("foo") => ??? +``` \ No newline at end of file diff --git a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala index 56a0f7f6d6b6..6d5eeb06267a 100644 --- a/scaladoc/src/dotty/tools/scaladoc/site/templates.scala +++ b/scaladoc/src/dotty/tools/scaladoc/site/templates.scala @@ -81,8 +81,8 @@ case class TemplateFile( val path = Some(Paths.get(file.getAbsolutePath)) val pathBasedArg = ssctx.snippetCompilerArgs.get(path) val sourceFile = dotty.tools.dotc.util.SourceFile(dotty.tools.io.AbstractFile.getFile(path.get), scala.io.Codec.UTF8) - (str: String, lineOffset: SnippetChecker.LineOffset, argOverride: Option[SCFlags]) => { - val arg = argOverride.fold(pathBasedArg)(pathBasedArg.overrideFlag(_)) + (str: String, lineOffset: SnippetChecker.LineOffset, argOverride: Option[SnippetCompilerArg]) => { + val arg = argOverride.fold(pathBasedArg)(pathBasedArg.merge(_)) val compilerData = SnippetCompilerData( "staticsitesnippet", SnippetCompilerData.Position(configOffset - 1, 0) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala index c92853816d16..a40ae317e135 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/FlexmarkSnippetProcessor.scala @@ -21,7 +21,7 @@ object FlexmarkSnippetProcessor: val lineOffset = node.getStartLineNumber + preparsed.fold(0)(_.strippedLinesBeforeNo) val info = node.getInfo.toString.split(" ") if info.contains("scala") then { - val argOverride = info + val flagOverride = info .find(_.startsWith("sc:")) .map(_.stripPrefix("sc:")) .map(SCFlagsParser.parse) @@ -34,6 +34,19 @@ object FlexmarkSnippetProcessor: ) None }) + + val scalacOptions: Seq[String] = info + .toIndexedSeq + .filter(_.startsWith("sc-opts:")) + .flatMap(_.stripPrefix("sc-opts:").split(",").map(_.trim).toSeq) + + val argOverride: Option[SnippetCompilerArg] = + (flagOverride, scalacOptions) match { + case (None, Seq()) => None + case (Some(flag), opts) => Some(SnippetCompilerArg(flag, opts)) + case (None, opts) => Some(SnippetCompilerArg(SCFlags.Compile, opts)) + } + val id = info .find(_.startsWith("sc-name:")) .map(_.stripPrefix("sc-name:")) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala index 8f8b73a576d1..4f90fbcee984 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetChecker.scala @@ -59,4 +59,4 @@ class SnippetChecker(val args: Scaladoc.Args)(using cctx: CompilerContext): object SnippetChecker: type LineOffset = Int - type SnippetCheckingFunc = (String, LineOffset, Option[SCFlags]) => Option[SnippetCompilationResult] + type SnippetCheckingFunc = (String, LineOffset, Option[SnippetCompilerArg]) => Option[SnippetCompilationResult] diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala index b13b5e9756ea..780eea53c10b 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompiler.scala @@ -86,7 +86,9 @@ class SnippetCompiler( private def additionalMessages(wrappedSnippet: WrappedSnippet, arg: SnippetCompilerArg, sourceFile: SourceFile, context: Context): Seq[SnippetCompilerMessage] = { Option.when(arg.flag == SCFlags.Fail && !context.reporter.hasErrors)( - SnippetCompilerMessage(None, "Snippet should not compile but compiled successfully", MessageLevel.Error) + SnippetCompilerMessage( + Some(Position(SourcePosition(sourceFile, NoSpan), wrappedSnippet.outerLineOffset)), + "Snippet should not compile but compiled successfully", MessageLevel.Error) ).toList } @@ -100,12 +102,19 @@ class SnippetCompiler( arg: SnippetCompilerArg, sourceFile: SourceFile ): SnippetCompilationResult = { - val context = SnippetDriver.currentCtx.fresh + val baseContext = SnippetDriver.currentCtx.fresh .setSetting( SnippetDriver.currentCtx.settings.outputDir, target ) .setReporter(new StoreReporter) + val context = + if arg.scalacOptions.isEmpty then baseContext + else + val args = arg.scalacOptions.toArray + SnippetDriver.setup(args, baseContext) match + case Some((_, ctx)) => ctx + case None => baseContext val run = newRun(using context) run.compileFromStrings(List(wrappedSnippet.snippet)) diff --git a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala index 35a89d985d8e..b5a3f7dfe123 100644 --- a/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala +++ b/scaladoc/src/dotty/tools/scaladoc/snippets/SnippetCompilerArgs.scala @@ -3,8 +3,11 @@ package snippets import java.nio.file.Path -case class SnippetCompilerArg(flag: SCFlags): +case class SnippetCompilerArg(flag: SCFlags, scalacOptions: Seq[String] = Seq.empty): def overrideFlag(f: SCFlags): SnippetCompilerArg = copy(flag = f) + def withScalacOptions(opts: Seq[String]): SnippetCompilerArg = copy(scalacOptions = scalacOptions ++ opts) + def merge(other: SnippetCompilerArg): SnippetCompilerArg = + SnippetCompilerArg(other.flag, scalacOptions ++ other.scalacOptions) enum SCFlags(val flagName: String): case Compile extends SCFlags("compile") diff --git a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala index 5b72e9eb5c42..9659bce44369 100644 --- a/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala +++ b/scaladoc/src/dotty/tools/scaladoc/tasty/comments/Comments.scala @@ -137,8 +137,8 @@ abstract class MarkupConversion[T](val repr: Repr)(using dctx: DocContext) { val scDataCollector = SnippetCompilerDataCollector[qctx.type](qctx) val data = scDataCollector.getSnippetCompilerData(s, s) val sourceFile = scDataCollector.getSourceFile(s) - (str: String, lineOffset: SnippetChecker.LineOffset, argOverride: Option[SCFlags]) => { - val arg = argOverride.fold(pathBasedArg)(pathBasedArg.overrideFlag(_)) + (str: String, lineOffset: SnippetChecker.LineOffset, argOverride: Option[SnippetCompilerArg]) => { + val arg = argOverride.fold(pathBasedArg)(pathBasedArg.merge(_)) val res = snippetChecker.checkSnippet(str, Some(data), arg, lineOffset, sourceFile) res.filter(r => !r.isSuccessful).foreach(_.reportMessages()(using compilerContext)) res