diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala index b895d4438c63..dc606d5a15a0 100644 --- a/src/compiler/scala/tools/nsc/CompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala @@ -126,11 +126,11 @@ class CompilerCommand(arguments: List[String], val settings: Settings) { def expandArg(arg: String): List[String] = { import java.nio.file.{Files, Paths} import scala.jdk.CollectionConverters._ - def stripComment(s: String) = s.takeWhile(_ != '#') - val file = Paths.get(arg stripPrefix "@") + def stripComment(s: String) = s.takeWhile(_ != '#').trim() // arg can be "" but not " " + val file = Paths.get(arg.stripPrefix("@")) if (!Files.exists(file)) throw new java.io.FileNotFoundException(s"argument file $file could not be found") - settings.splitParams(Files.readAllLines(file).asScala.map(stripComment).mkString(" ")) + Files.readAllLines(file).asScala.filter(!_.startsWith("#")).map(stripComment).toList } // override this if you don't want arguments processed here diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 0d864d9ba90b..926496d913fb 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1491,23 +1491,19 @@ class Global(var currentSettings: Settings, reporter0: Reporter) } } - /** Compile list of source files, - * unless there is a problem already, - * such as a plugin was passed a bad option. + /** Compile a list of source files, unless there is a problem already, e.g., a plugin was passed a bad option. */ def compileSources(sources: List[SourceFile]): Unit = if (!reporter.hasErrors) { printArgs(sources) - def checkDeprecations() = { warnDeprecatedAndConflictingSettings() reporting.summarizeErrors() } - - val units = sources map scripted map (file => new CompilationUnit(file, warningFreshNameCreator)) - - units match { + sources match { case Nil => checkDeprecations() // nothing to compile, report deprecated options - case _ => compileUnits(units) + case _ => + val units = sources.map(src => new CompilationUnit(scripted(src), warningFreshNameCreator)) + compileUnits(units) } } diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 49e4a8f405b5..314b5393138f 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -973,5 +973,5 @@ class MutableSettings(val errorFn: String => Unit, val pathFactory: PathFactory) } private object Optionlike { - def unapply(s: String): Boolean = s.startsWith("-") + def unapply(s: String): Boolean = s.startsWith("-") && s != "-" } diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index cb81e259aeea..6a3a812f21d8 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -39,7 +39,7 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett protected def defaultClasspath = Option(System.getenv("CLASSPATH")).getOrElse(".") /** If any of these settings is enabled, the compiler should print a message and exit. */ - def infoSettings = List[Setting](version, help, Vhelp, Whelp, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph, printArgs) + def infoSettings = List[Setting](version, help, Vhelp, Whelp, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph) /** Is an info setting set? Any -option:help? */ def isInfo = infoSettings.exists(_.isSetByUser) || allSettings.valuesIterator.exists(_.isHelping) diff --git a/test/files/run/argfile.check b/test/files/run/argfile.check new file mode 100644 index 000000000000..bb8621865db7 --- /dev/null +++ b/test/files/run/argfile.check @@ -0,0 +1 @@ +Compiler arguments written to: argfile-run.obj/print-args.txt diff --git a/test/files/run/argfile.scala b/test/files/run/argfile.scala new file mode 100644 index 000000000000..6fffbac7e9bc --- /dev/null +++ b/test/files/run/argfile.scala @@ -0,0 +1,39 @@ + +import java.nio.file.Files + +import scala.jdk.CollectionConverters._ +import scala.reflect.internal.util._ +import scala.tools.nsc.{CompilerCommand, Settings} +import scala.tools.partest.DirectTest +import scala.util.chaining._ + +object Test extends DirectTest { + var count = 0 + lazy val argfile = testOutput.jfile.toPath().resolve("print-args.txt") + lazy val goodarg = testOutput.jfile.toPath().resolve("print-args2.txt") + override def extraSettings = + if (count == 0) s"""${super.extraSettings} -Xsource:3 -Vprint-args $argfile "-Wconf:cat=unused-nowarn&msg=does not suppress&site=C:s"""" + else s"@$goodarg" + + // Use CompilerCommand for expanding the args file. + override def newSettings(args: List[String]) = (new Settings).tap { s => + val cc = new CompilerCommand(args, s) + assert(cc.ok) + assert(cc.files.isEmpty) + } + def code = + sm""" + |@annotation.nowarn + |final class C { + | def f: Int = "42".toInt + |} + """ + def show() = { + assert(compile()) + // drop "-Vprint-args .../print-args.txt newSource1.scala" + val args = Files.readAllLines(argfile).asScala.toList.dropRight(3) + Files.write(goodarg, args.asJava) + count += 1 + assert(compile()) + } +} diff --git a/test/files/run/print-args.check b/test/files/run/print-args.check new file mode 100644 index 000000000000..60f43da7cdd3 --- /dev/null +++ b/test/files/run/print-args.check @@ -0,0 +1,6 @@ +Compiler arguments written to: print-args-run.obj/print-args.txt +newSource1.scala:3: error: type mismatch; + found : String("42") + required: Int + def f: Int = "42" + ^ diff --git a/test/files/run/print-args.scala b/test/files/run/print-args.scala new file mode 100644 index 000000000000..57c78b2d0d0f --- /dev/null +++ b/test/files/run/print-args.scala @@ -0,0 +1,31 @@ + +import java.nio.file.Files + +import scala.jdk.CollectionConverters._ +import scala.reflect.internal.util._ +import scala.tools.partest.DirectTest + +object Test extends DirectTest { + lazy val argfile = testOutput.jfile.toPath().resolve("print-args.txt") + override def extraSettings = s"${super.extraSettings} -Xsource:3 -Vprint-args ${argfile}" + def expected = + sm""" + |-usejavacp + |-d + |${testOutput.jfile.toPath()} + |-Xsource:3.0.0 + |-Vprint-args + |${testOutput.jfile.toPath().resolve(argfile)} + |newSource1.scala + """ + def code = + sm""" + |class C { + | def f: Int = "42" + |} + """ + def show() = { + assert(!compile()) + assert(expected.linesIterator.toList.tail.init.sameElements(Files.readAllLines(argfile).asScala)) + } +} diff --git a/test/junit/scala/tools/nsc/settings/SettingsTest.scala b/test/junit/scala/tools/nsc/settings/SettingsTest.scala index b83b536725fe..3d63d7fe75c6 100644 --- a/test/junit/scala/tools/nsc/settings/SettingsTest.scala +++ b/test/junit/scala/tools/nsc/settings/SettingsTest.scala @@ -345,6 +345,15 @@ class SettingsTest { assertFalse(s.optInlinerEnabled) assertTrue(s.optBoxUnbox) } + @Test def `print args to reporter`: Unit = { + val s = settings + val args = "-Vprint-args" :: "-" :: Nil + val (ok, rest) = s.processArguments(args, processAll = true) + assertTrue(ok) + assertTrue(rest.isEmpty) + assertFalse(s.isInfo) + assertTrue(s.printArgs.isSetByUser) + } } object SettingsTest { import language.implicitConversions