Skip to content

Commit 76deb1c

Browse files
committed
support test scope by ignoring repeated pipelining flags
1 parent 9d8dda9 commit 76deb1c

File tree

7 files changed

+67
-9
lines changed

7 files changed

+67
-9
lines changed

Diff for: compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ private sealed trait YSettings:
440440
val YdebugMacros: Setting[Boolean] = BooleanSetting(ForkSetting, "Ydebug-macros", "Show debug info when quote pattern match fails")
441441

442442
// Pipeline compilation options
443-
val YjavaTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Yjava-tasty", "Pickler phase should compute TASTy for .java defined symbols for use by build tools", aliases = List("-Ypickle-java"))
444-
val YearlyTastyOutput: Setting[AbstractFile] = OutputSetting(ForkSetting, "Yearly-tasty-output", "directory|jar", "Destination to write generated .tasty files to for use in pipelined compilation.", NoAbstractFile, aliases = List("-Ypickle-write"))
443+
val YjavaTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Yjava-tasty", "Pickler phase should compute TASTy for .java defined symbols for use by build tools", aliases = List("-Ypickle-java"), preferPrevious = true)
444+
val YearlyTastyOutput: Setting[AbstractFile] = OutputSetting(ForkSetting, "Yearly-tasty-output", "directory|jar", "Destination to write generated .tasty files to for use in pipelined compilation.", NoAbstractFile, aliases = List("-Ypickle-write"), preferPrevious = true)
445445
val YallowOutlineFromTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Yallow-outline-from-tasty", "Allow outline TASTy to be loaded with the -from-tasty option.")
446446
end YSettings

Diff for: compiler/src/dotty/tools/dotc/config/Settings.scala

+17-7
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ object Settings:
7979
aliases: List[String] = Nil,
8080
depends: List[(Setting[?], Any)] = Nil,
8181
ignoreInvalidArgs: Boolean = false,
82+
preferPrevious: Boolean = false,
8283
propertyClass: Option[Class[?]] = None,
8384
deprecationMsg: Option[String] = None,
8485
// kept only for -Ykind-projector option compatibility
@@ -125,11 +126,16 @@ object Settings:
125126
valueList.filter(current.contains).foreach(s => dangers :+= s"Setting $name set to $s redundantly")
126127
current ++ valueList
127128
else
128-
if sstate.wasChanged(idx) then dangers :+= s"Flag $name set repeatedly"
129+
if sstate.wasChanged(idx) then
130+
assert(!preferPrevious, "should have shortcutted with ignoreValue, side-effect may be present!")
131+
dangers :+= s"Flag $name set repeatedly"
129132
value
130133
ArgsSummary(updateIn(sstate, valueNew), args, errors, dangers)
131134
end update
132135

136+
def ignoreValue(args: List[String]): ArgsSummary =
137+
ArgsSummary(sstate, args, errors, warnings)
138+
133139
def fail(msg: String, args: List[String]) =
134140
ArgsSummary(sstate, args, errors :+ msg, warnings)
135141

@@ -196,7 +202,8 @@ object Settings:
196202
def doSet(argRest: String) =
197203
((summon[ClassTag[T]], args): @unchecked) match {
198204
case (BooleanTag, _) =>
199-
setBoolean(argRest, args)
205+
if sstate.wasChanged(idx) && preferPrevious then ignoreValue(args)
206+
else setBoolean(argRest, args)
200207
case (OptionTag, _) =>
201208
update(Some(propertyClass.get.getConstructor().newInstance()), args)
202209
case (ct, args) =>
@@ -216,7 +223,10 @@ object Settings:
216223
case StringTag =>
217224
setString(arg, argsLeft)
218225
case OutputTag =>
219-
setOutput(arg, argsLeft)
226+
if sstate.wasChanged(idx) && preferPrevious then
227+
ignoreValue(argsLeft) // do not risk side effects e.g. overwriting a jar
228+
else
229+
setOutput(arg, argsLeft)
220230
case IntTag =>
221231
setInt(arg, argsLeft)
222232
case VersionTag =>
@@ -333,8 +343,8 @@ object Settings:
333343
assert(!name.startsWith("-"), s"Setting $name cannot start with -")
334344
"-" + name
335345

336-
def BooleanSetting(category: SettingCategory, name: String, descr: String, initialValue: Boolean = false, aliases: List[String] = Nil): Setting[Boolean] =
337-
publish(Setting(category, prependName(name), descr, initialValue, aliases = aliases))
346+
def BooleanSetting(category: SettingCategory, name: String, descr: String, initialValue: Boolean = false, aliases: List[String] = Nil, preferPrevious: Boolean = false): Setting[Boolean] =
347+
publish(Setting(category, prependName(name), descr, initialValue, aliases = aliases, preferPrevious = preferPrevious))
338348

339349
def StringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: String, aliases: List[String] = Nil): Setting[String] =
340350
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases))
@@ -357,8 +367,8 @@ object Settings:
357367
def MultiStringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: List[String] = Nil, aliases: List[String] = Nil): Setting[List[String]] =
358368
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases))
359369

360-
def OutputSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: AbstractFile, aliases: List[String] = Nil): Setting[AbstractFile] =
361-
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases))
370+
def OutputSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: AbstractFile, aliases: List[String] = Nil, preferPrevious: Boolean = false): Setting[AbstractFile] =
371+
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, preferPrevious = preferPrevious))
362372

363373
def PathSetting(category: SettingCategory, name: String, descr: String, default: String, aliases: List[String] = Nil): Setting[String] =
364374
publish(Setting(category, prependName(name), descr, default, aliases = aliases))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package a
2+
3+
object A {
4+
val foo: (1,2,3) = (1,2,3)
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package a
2+
3+
import a.A
4+
5+
import org.junit.Test
6+
7+
class Hello {
8+
9+
@Test def test(): Unit = {
10+
assert(A.foo == (1,2,3))
11+
}
12+
}

Diff for: sbt-test/pipelining/pipelining-test/build.sbt

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
ThisBuild / usePipelining := true
2+
3+
lazy val a = project.in(file("a"))
4+
.settings(
5+
scalacOptions += "-Ycheck:all",
6+
libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % "test",
7+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import sbt._
2+
import Keys._
3+
4+
object DottyInjectedPlugin extends AutoPlugin {
5+
override def requires = plugins.JvmPlugin
6+
override def trigger = allRequirements
7+
8+
override val projectSettings = Seq(
9+
scalaVersion := sys.props("plugin.scalaVersion"),
10+
scalacOptions += "-source:3.0-migration"
11+
)
12+
}

Diff for: sbt-test/pipelining/pipelining-test/test

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# run the tests on a project with pipelining
2+
# exercises the fact that -Ypickle-java and -Ypickle-write
3+
# flags are set twice.
4+
# steps:
5+
# - Compile scope is compiled with flags `-Ypickle-java -Ypickle-write early/a-early-7423784.jar`
6+
# - sbt copies `early/a-early-7423784.jar` to `early/a-early.jar`
7+
# - Test scope is compiled with flags `-Ypickle-java -Ypickle-write early-test/a-early-963232.jar -Ypickle-java -Ypickle-write early/a-early.jar -classpath early/a-early.jar`
8+
# e.g. for some reason the classpath has the same `a-early.jar` that
9+
# is passed with `Ypickle-write`.
10+
# Therefore we MUST avoid even reading the second `-Ypickle-write` setting,
11+
# otherwise we will zero-out `a-early.jar`, causing type errors because its contents are blank.
12+
> a/test

0 commit comments

Comments
 (0)