From c18ac07b40659c2c63abe4b814a1f003966afb8a Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 21 Feb 2025 13:46:57 +0100 Subject: [PATCH 1/3] Add REPL setting to quit after evaluating init script --- compiler/src/dotty/tools/dotc/config/ScalaSettings.scala | 1 + compiler/src/dotty/tools/repl/ReplDriver.scala | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala index 7058a9c4ab6d..7771a8e29ad8 100644 --- a/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala +++ b/compiler/src/dotty/tools/dotc/config/ScalaSettings.scala @@ -127,6 +127,7 @@ trait CommonScalaSettings: val usejavacp: Setting[Boolean] = BooleanSetting(RootSetting, "usejavacp", "Utilize the java.class.path in classpath resolution.", aliases = List("--use-java-class-path")) val scalajs: Setting[Boolean] = BooleanSetting(RootSetting, "scalajs", "Compile in Scala.js mode (requires scalajs-library.jar on the classpath).", aliases = List("--scalajs")) val replInitScript: Setting[String] = StringSetting(RootSetting, "repl-init-script", "code", "The code will be run on REPL startup.", "", aliases = List("--repl-init-script")) + val replEvalOnly: Setting[Boolean] = BooleanSetting(RootSetting, "repl-eval", "Quit REPL after evaluating the init script.", aliases = List("--repl-eval")) end CommonScalaSettings /** -P "plugin" settings. Various tools might support plugins. */ diff --git a/compiler/src/dotty/tools/repl/ReplDriver.scala b/compiler/src/dotty/tools/repl/ReplDriver.scala index 0f2921fd736c..c284a9c00560 100644 --- a/compiler/src/dotty/tools/repl/ReplDriver.scala +++ b/compiler/src/dotty/tools/repl/ReplDriver.scala @@ -153,7 +153,9 @@ class ReplDriver(settings: Array[String], * * Possible reason for unsuccessful run are raised flags in CLI like --help or --version */ - final def tryRunning = if shouldStart then runUntilQuit() + final def tryRunning = if shouldStart then + if rootCtx.settings.replEvalOnly.value(using rootCtx) then initialState + else runUntilQuit() /** Run REPL with `state` until `:quit` command found * From 4661104375a555395d39738a26e0b1415a774f77 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 21 Feb 2025 14:19:46 +0100 Subject: [PATCH 2/3] Add a script for launching the REPL --- bin/repl | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100755 bin/repl diff --git a/bin/repl b/bin/repl new file mode 100755 index 000000000000..5d0b84c4a229 --- /dev/null +++ b/bin/repl @@ -0,0 +1,6 @@ +#!/usr/bin/env bash + +ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >& /dev/null && pwd)/.." +. $ROOT/bin/commonQ + +java -Dscala.usejavacp=true -cp $cp dotty.tools.repl.Main -usejavacp "$@" From 0c5a25c691417a6fe9b340928b8b04518db401d3 Mon Sep 17 00:00:00 2001 From: noti0na1 Date: Fri, 21 Feb 2025 15:56:57 +0100 Subject: [PATCH 3/3] Add REPL exit test to BashExitCodeTests --- compiler/test/dotty/tools/scripting/BashExitCodeTests.scala | 5 ++++- compiler/test/dotty/tools/scripting/ScriptTestEnv.scala | 5 +++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala b/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala index 857f5ef378e7..c359e7a1b2bd 100644 --- a/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala +++ b/compiler/test/dotty/tools/scripting/BashExitCodeTests.scala @@ -32,10 +32,11 @@ class BashExitCodeTests: s"expected $expectedExitCode but got $exitCode${pp("out", stdout)}${pp("err", stderr)}" }, expectedExitCode, exitCode) - // Helpers for running scala, scalac, and scalac without the output directory ("raw") + // Helpers for running scala, scalac, scalac, and repl without the output directory ("raw") def scala(args: String*) = verifyExit(scalaPath, ("--power" +: args :+ "--offline" :+ "--server=false")*) def scalacRaw(args: String*) = verifyExit(scalacPath, args*) def scalac(args: String*) = scalacRaw(("-d" +: tmpDir +: args)*) + def repl(args: String*) = verifyExit(replPath, args*) /** The path to the test file for this class. */ def f(body: String, suffix: String = ".scala"): String = @@ -72,6 +73,8 @@ class BashExitCodeTests: @Test def xPluginList = scala("-Xplugin-list")(0) @Test def vPhases = scala("-Vphases")(0) + @Test def replEval = repl("--repl-eval", "--repl-init-script", "println(\"Hello from init script!\"); val i = 2 * 2")(0) + /** A utility for running two commands in a row, like you do in bash. */ extension (inline u1: Unit) inline def & (inline u2: Unit): Unit = { u1; u2 } end BashExitCodeTests diff --git a/compiler/test/dotty/tools/scripting/ScriptTestEnv.scala b/compiler/test/dotty/tools/scripting/ScriptTestEnv.scala index 771c3ba14af0..c565354cdc1f 100644 --- a/compiler/test/dotty/tools/scripting/ScriptTestEnv.scala +++ b/compiler/test/dotty/tools/scripting/ScriptTestEnv.scala @@ -292,10 +292,11 @@ object ScriptTestEnv { lazy val cwd: Path = Paths.get(".").toAbsolutePath.normalize - lazy val (scalacPath: String, scalaPath: String) = { + lazy val (scalacPath: String, scalaPath: String, replPath: String) = { val scalac = s"$workingDirectory/$packBinDir/scalac".toPath.normalize val scala = s"$workingDirectory/$packBinDir/scala".toPath.normalize - (scalac.norm, scala.norm) + val repl = s"$workingDirectory/$packBinDir/repl".toPath.normalize + (scalac.norm, scala.norm, repl.norm) }