From 20698b7cf5c2394b77fc747717f11394350e63d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Sat, 4 May 2019 15:04:16 +0200 Subject: [PATCH] Implement `compile-only` modifier for JVM and Scala.js. Fixes #145. --- .scalafmt.conf | 1 + bin/scalafmt | Bin 28226 -> 18121 bytes docs/js.md | 17 ++++ docs/modifiers.md | 12 +++ .../scala/mdoc/modifiers/JsModifier.scala | 8 +- .../main/scala/mdoc/modifiers/JsMods.scala | 19 +++- .../test/scala/tests/RelativizeSuite.scala | 18 ++-- .../mdoc/internal/markdown/BlockInput.scala | 12 +++ .../mdoc/internal/markdown/Instrumenter.scala | 8 ++ .../scala/mdoc/internal/markdown/Mod.scala | 4 + .../mdoc/internal/markdown/Modifier.scala | 5 +- .../tests/markdown/CompileOnlySuite.scala | 82 ++++++++++++++++++ .../scala/tests/markdown/JsModsSuite.scala | 7 ++ .../test/scala/tests/markdown/JsSuite.scala | 28 ++++++ .../scala/tests/markdown/MultiModsSuite.scala | 25 ++++++ 15 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 tests/unit/src/test/scala/tests/markdown/CompileOnlySuite.scala diff --git a/.scalafmt.conf b/.scalafmt.conf index 0ccee77d5..6199d293a 100644 --- a/.scalafmt.conf +++ b/.scalafmt.conf @@ -1,3 +1,4 @@ +version=2.0.0-RC7 maxColumn = 100 project.git=true align = none diff --git a/bin/scalafmt b/bin/scalafmt index 785c29f50b586cd695556eaeb94f7988ba1cc2c4..df1339916e78f3e0b49604ecf72833ecef309b50 100755 GIT binary patch literal 18121 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 H>(l=SK1Z}( literal 28226 zcmaHS19WD=mTo%i*tTukw(b0}`Ny`Cj%{>o+qRRAZKpeUedo@bd3R>Ld)7K@?NjU9 zRcF^er|PR+yGV%{-CUd*O|0x00ru`hE|xGZo-T&Q&K55GBqT7#j*kB&Tk$jV5_wo! z*#d}kiAcz-NQmhFie#ij`n*JD4lqPS0C!_sqQ9E_dSu>YR=$5rOpRUsBK{T;S=s-6 zBqE}hp{Jq#4~dBAzuO`EzakNt_g^q6y^Jr(e}Z^<|3mmMrT=~*vi~doM+5(Y2e=rU z{#CQ$C!?aWBBCW?rly85bFc@%zyN>%QzC0)cVnXeZj;{H*!izLOeB9R`cHFVlw`rc z(Lg}He+RM3YL>&b8V}6{0ReIP1_FWx0uCZCt|m+`tsucDFRUOfA+D;%ATRMb0Rj>m z&x;Vuge2xocD)O`rckWLkPJi3cDRV!*eA2we0lUq3_(I7CC!`p;@;9kpesd}hlHBM zxnGXpsS#rwfXt_xE9xmp&=-*zfhvjH14H;YHF^KTq7?)|*HyNk6D?Lq1;5UfZ5m|A z?kZl?A)YQXuQEp(ceSVkXP!0Otm!)8PlZODL^sw`<&J(mYeCcL5ulD5yT16m%P-l2 z@gFw9{Iv<>KWzGI&VOCde?XxRZi{BZ&)3zx0+g z2{dvPY;rnE;$acZZZWKzk1zf;O5(n0ChelwDG3Y7HHNVx5iJQN3FH2cfJKs-2(HOJ z@7E}A@h!@IUy>chT|Z>R+iC(=W7-+$*MMk_FCt7|slISApS4hsnaJ1g;Q|xmqg-!o z5sHrEicvtVp)xT(l6__5JdC^ah}j5WcIR6NEbg7Qf&k?%-(XZsL7v)vyD@i~*)3f5 z55@6eEE2hMyIA?m^X*sIObZWD*0A=%0DGt=$g_!-KkG}97Sovk-? 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 { }, 1000) ``` +### `:compile-only` + +Use `:compile-only` to validate that a code example compiles successfully +without evaluating it at runtime. + +````md +```scala mdoc:js:compile-only +org.scalajs.dom.window.setInterval(() => { + println("I'm only compiled, never executed") +}, 1000) +``` +```` + +Note that `compile-only` blocks do not automatically have access to a `node` DOM +element. Create a leading code fence with `shared:invisible` to expose a hidden +`node` instance in the scope of a `compile-only` code block. + ## Loading HTML By default, the `node` variable points to an empty div element. Prefix the code diff --git a/docs/modifiers.md b/docs/modifiers.md index 9fd850018..da8cd4581 100644 --- a/docs/modifiers.md +++ b/docs/modifiers.md @@ -178,6 +178,18 @@ List("with quotes") ``` ```` +## `compile-only` + +The `compile-only` modifier ensures the code example compiles without evaluating +the program at runtime. This can be helpful to demonstrate code examples that +perform side-effects. + +````scala mdoc:mdoc +```scala mdoc:compile-only +val name = scala.io.StdIn.readLine("Enter your name: ") +``` +```` + ## `scastie` The `scastie` modifier transforms a Scala code block into a diff --git a/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala b/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala index 76958f46d..29384a8d3 100644 --- a/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala +++ b/mdoc-js/src/main/scala/mdoc/modifiers/JsModifier.scala @@ -202,6 +202,12 @@ class JsModifier extends mdoc.PreModifier { val code: String = if (mods.isShared) { input.text + } else if (mods.isCompileOnly) { + new CodeBuilder() + .println(s"""object ${gensym.fresh("compile")} {""") + .println(input.text) + .println("}") + .toString } else { new CodeBuilder() .println(s""" @_root_.scala.scalajs.js.annotation.JSExportTopLevel("$id") """) @@ -213,7 +219,7 @@ class JsModifier extends mdoc.PreModifier { runs += code new CodeBuilder() .printlnIf(!mods.isInvisible, s"```scala\n${input.text}\n```") - .printlnIf(!mods.isShared, s"""
$body
""") + .printlnIf(mods.isEntrypoint, s"""
$body
""") .toString } } diff --git a/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala b/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala index 8a95950fd..588f6360a 100644 --- a/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala +++ b/mdoc-js/src/main/scala/mdoc/modifiers/JsMods.scala @@ -5,13 +5,15 @@ import mdoc.internal.pos.PositionSyntax._ import scala.annotation.tailrec import scala.meta.inputs.Input -class JsMods private (mods: Set[String]) { +class JsMods private (val mods: Set[String]) { def isShared: Boolean = mods("shared") def isInvisible: Boolean = mods("invisible") + def isCompileOnly: Boolean = mods("compile-only") + def isEntrypoint: Boolean = !isShared && !isCompileOnly } object JsMods { - val all = Set("shared", "invisible") + val all = Set("shared", "invisible", "compile-only") def parse(info: Input, reporter: Reporter): Option[JsMods] = { val text = info.text @tailrec def loop(from: Int, accum: Set[String]): Option[Set[String]] = { @@ -34,6 +36,17 @@ object JsMods { } } } - loop(0, Set.empty).map(new JsMods(_)) + loop(0, Set.empty).map(new JsMods(_)).flatMap { mods => + if (mods.isCompileOnly && mods.mods.size > 1) { + val others = (mods.mods - "compile-only").mkString(", ") + reporter.error( + info.toPosition.addStart(0), + s"compile-only cannot be used in combination with $others" + ) + None + } else { + Some(mods) + } + } } } diff --git a/mdoc-sbt/src/test/scala/tests/RelativizeSuite.scala b/mdoc-sbt/src/test/scala/tests/RelativizeSuite.scala index 8792da26d..e7fd62415 100644 --- a/mdoc-sbt/src/test/scala/tests/RelativizeSuite.scala +++ b/mdoc-sbt/src/test/scala/tests/RelativizeSuite.scala @@ -23,7 +23,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { "", "", "", - "", + "" ) val obtained = StringFS .asString(root) @@ -44,7 +44,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { """ |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -56,7 +56,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { """ |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -68,7 +68,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { """ |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -80,7 +80,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { """ |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -97,7 +97,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { | |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -111,7 +111,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { |/index.html | | - |""".stripMargin, + |""".stripMargin ) check( @@ -123,7 +123,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { """ |/index.html | - |""".stripMargin, + |""".stripMargin ) check( @@ -145,7 +145,7 @@ class RelativizeSuite extends FunSuite with DiffAssertions { | |/users/index.html |Users - |""".stripMargin, + |""".stripMargin ) } diff --git a/mdoc/src/main/scala/mdoc/internal/markdown/BlockInput.scala b/mdoc/src/main/scala/mdoc/internal/markdown/BlockInput.scala index 908173e19..3d7e674dc 100644 --- a/mdoc/src/main/scala/mdoc/internal/markdown/BlockInput.scala +++ b/mdoc/src/main/scala/mdoc/internal/markdown/BlockInput.scala @@ -70,6 +70,18 @@ class BlockInput(ctx: Context, baseInput: Input) { invalidCombination(block, "crash", "fail") } else if (mod.isSilent && mod.isInvisible) { invalidCombination(block, "silent", "invisible") + } else if (mod.isCompileOnly) { + val others = mod.mods - Mod.CompileOnly + if (others.isEmpty) { + true + } else { + val all = others.map(_.toString.toLowerCase).mkString(", ") + invalid( + block, + s"""compile-only cannot be used in combination with $all""" + ) + false + } } else { true } diff --git a/mdoc/src/main/scala/mdoc/internal/markdown/Instrumenter.scala b/mdoc/src/main/scala/mdoc/internal/markdown/Instrumenter.scala index 05acfde51..3427e7ab0 100644 --- a/mdoc/src/main/scala/mdoc/internal/markdown/Instrumenter.scala +++ b/mdoc/src/main/scala/mdoc/internal/markdown/Instrumenter.scala @@ -36,6 +36,14 @@ class Instrumenter(sections: List[SectionInput]) { .append(");") printBinder(binder, section.source.pos) sb.println("\n$doc.endStatement();") + } else if (section.mod.isCompileOnly) { + section.source.stats.foreach { stat => + sb.println(s"$$doc.startStatement(${position(stat.pos)});") + sb.println("\n$doc.endStatement();") + } + sb.println(s"""object ${gensym.fresh("compile")} {""") + sb.println(section.source.pos.text) + sb.println("\n}") } else { section.source.stats.foreach { stat => sb.println(s"$$doc.startStatement(${position(stat.pos)});") diff --git a/mdoc/src/main/scala/mdoc/internal/markdown/Mod.scala b/mdoc/src/main/scala/mdoc/internal/markdown/Mod.scala index c62491314..d17f133b2 100644 --- a/mdoc/src/main/scala/mdoc/internal/markdown/Mod.scala +++ b/mdoc/src/main/scala/mdoc/internal/markdown/Mod.scala @@ -7,6 +7,9 @@ object Mod { case object Silent extends Mod case object Passthrough extends Mod case object Invisible extends Mod + case object CompileOnly extends Mod { + override def toString: String = "compile-only" + } case object Reset extends Mod case object ResetClass extends Mod { override def toString: String = "reset-class" @@ -18,6 +21,7 @@ object Mod { def all: List[Mod] = List( Passthrough, Invisible, + CompileOnly, Reset, ResetClass, Fail, diff --git a/mdoc/src/main/scala/mdoc/internal/markdown/Modifier.scala b/mdoc/src/main/scala/mdoc/internal/markdown/Modifier.scala index 661aefbe4..f22a44581 100644 --- a/mdoc/src/main/scala/mdoc/internal/markdown/Modifier.scala +++ b/mdoc/src/main/scala/mdoc/internal/markdown/Modifier.scala @@ -14,7 +14,7 @@ import mdoc.internal.markdown.Mod._ * * Currently, only supports parsing one modifier per code block. */ -sealed abstract class Modifier(mods: Set[Mod]) { +sealed abstract class Modifier(val mods: Set[Mod]) { def isDefault: Boolean = mods.isEmpty def isFail: Boolean = mods(Fail) def isPassthrough: Boolean = mods(Passthrough) @@ -24,6 +24,7 @@ sealed abstract class Modifier(mods: Set[Mod]) { def isCrash: Boolean = mods(Crash) def isSilent: Boolean = mods(Silent) def isInvisible: Boolean = mods(Invisible) + def isCompileOnly: Boolean = mods(CompileOnly) def isReset: Boolean = mods(Reset) || isResetClass def isResetClass: Boolean = mods(ResetClass) def isToString: Boolean = mods(ToString) @@ -57,7 +58,7 @@ object Modifier { } } - case class Builtin(mods: Set[Mod]) extends Modifier(mods) + case class Builtin(override val mods: Set[Mod]) extends Modifier(mods) case class Str(mod: StringModifier, info: String) extends Modifier(Set.empty) case class Post(mod: mdoc.PostModifier, info: String) extends Modifier(Set.empty) case class Pre(mod: mdoc.PreModifier, info: String) extends Modifier(Set.empty) diff --git a/tests/unit/src/test/scala/tests/markdown/CompileOnlySuite.scala b/tests/unit/src/test/scala/tests/markdown/CompileOnlySuite.scala new file mode 100644 index 000000000..f9cda158d --- /dev/null +++ b/tests/unit/src/test/scala/tests/markdown/CompileOnlySuite.scala @@ -0,0 +1,82 @@ +package tests.markdown + +class CompileOnlySuite extends BaseMarkdownSuite { + check( + "compile-only", + """ + |```scala mdoc:compile-only + |println(System.in.read()) + |``` + """.stripMargin, + """|```scala + |println(System.in.read()) + |``` + """.stripMargin + ) + + check( + "reuse", + """ + |```scala mdoc + |val message = "Enter: " + |``` + |```scala mdoc:compile-only + |println(message) + |println(System.in.read()) + |``` + |```scala mdoc + |println(message) + |``` + """.stripMargin, + // assert it's possible to reference variables from non-compile-only blocks + """|```scala + |val message = "Enter: " + |// message: String = "Enter: " + |``` + | + |```scala + |println(message) + |println(System.in.read()) + |``` + | + |```scala + |println(message) + |// Enter: + |``` + """.stripMargin + ) + + checkError( + "no-reuse", + """ + |```scala mdoc:compile-only + |val message = "Enter: " + |``` + |```scala mdoc + |println(message) + |``` + """.stripMargin, + // assert it's not possible to reference variables from compile-only blocks + """|error: no-reuse.md:6:9: not found: value message + |println(message) + | ^^^^^^^ + """.stripMargin + ) + + checkError( + "error", + """ + |```scala mdoc:compile-only + |val x: String = 42 + |``` + """.stripMargin, + // Validate that compile errors are reported and fail the build. + """|error: error.md:3:17: type mismatch; + | found : Int(42) + | required: String + |val x: String = 42 + | ^^ + """.stripMargin + ) + +} diff --git a/tests/unit/src/test/scala/tests/markdown/JsModsSuite.scala b/tests/unit/src/test/scala/tests/markdown/JsModsSuite.scala index 9cc988487..ad3baf9c9 100644 --- a/tests/unit/src/test/scala/tests/markdown/JsModsSuite.scala +++ b/tests/unit/src/test/scala/tests/markdown/JsModsSuite.scala @@ -41,4 +41,11 @@ class JsModsSuite extends BaseMarkdownSuite { | ^^^ """.stripMargin ) + checkError( + "compile-only:invisible", + """|error: :1:1: compile-only cannot be used in combination with invisible + |compile-only:invisible + |^^^^^^^^^^^^^^^^^^^^^^ + """.stripMargin + ) } diff --git a/tests/unit/src/test/scala/tests/markdown/JsSuite.scala b/tests/unit/src/test/scala/tests/markdown/JsSuite.scala index 6de98e057..fa3656316 100644 --- a/tests/unit/src/test/scala/tests/markdown/JsSuite.scala +++ b/tests/unit/src/test/scala/tests/markdown/JsSuite.scala @@ -160,6 +160,34 @@ class JsSuite extends BaseMarkdownSuite { """.stripMargin ) + check( + "compile-only", + """ + |```scala mdoc:compile-only + |println(42) + |``` + """.stripMargin, + """|```scala + |println(42) + |``` + """.stripMargin + ) + + checkError( + "compile-only-error", + """ + |```scala mdoc:compile-only + |val x: String = 42 + |``` + """.stripMargin, + """|error: compile-only-error.md:3:17: type mismatch; + | found : Int(42) + | required: String + |val x: String = 42 + | ^^ + """.stripMargin + ) + // It's easy to mess up stripMargin multiline strings when generating code with strings. check( "stripMargin", diff --git a/tests/unit/src/test/scala/tests/markdown/MultiModsSuite.scala b/tests/unit/src/test/scala/tests/markdown/MultiModsSuite.scala index 3cfd1b550..81a1c06c6 100644 --- a/tests/unit/src/test/scala/tests/markdown/MultiModsSuite.scala +++ b/tests/unit/src/test/scala/tests/markdown/MultiModsSuite.scala @@ -102,4 +102,29 @@ class MultiModsSuite extends BaseMarkdownSuite { """.stripMargin ) + checkError( + "compile-only:passthrough", + """ + |```scala mdoc:compile-only:passthrough + |val x = 2 + |``` + """.stripMargin, + """|error: compile-only:passthrough.md:2:15: compile-only cannot be used in combination with passthrough + |```scala mdoc:compile-only:passthrough + | ^^^^^^^^^^^^^^^^^^^^^^^^ + """.stripMargin + ) + + checkError( + "compile-only:multiple", + """ + |```scala mdoc:compile-only:to-string:silent + |val x = 2 + |``` + """.stripMargin, + """|error: compile-only:multiple.md:2:15: compile-only cannot be used in combination with to-string, silent + |```scala mdoc:compile-only:to-string:silent + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + """.stripMargin + ) }