Skip to content

Commit ae55323

Browse files
committedSep 5, 2020
Multivalued setting can be set multiply
Permit `-language:foo -language:bar` to mean `-language:foo,bar`, and similarly for other settings which are multivalued (i.e., have a value which is a list). Such settings include `-Xplugin` and `-Xprint`. There is no mechanism to distinguish phase names from other string settings.
1 parent 196b3fa commit ae55323

File tree

2 files changed

+68
-7
lines changed

2 files changed

+68
-7
lines changed
 

‎compiler/src/dotty/tools/dotc/config/Settings.scala

+14-7
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ object Settings {
8888

8989
def isDefaultIn(state: SettingsState): Boolean = valueIn(state) == default
9090

91+
def isMultivalue: Boolean = implicitly[ClassTag[T]] == ListTag
92+
9193
def legalChoices: String =
9294
choices match {
9395
case xs if xs.isEmpty => ""
@@ -114,12 +116,17 @@ object Settings {
114116
def tryToSet(state: ArgsSummary): ArgsSummary = {
115117
val ArgsSummary(sstate, arg :: args, errors, warnings) = state
116118
def update(value: Any, args: List[String]) =
117-
if (changed)
118-
ArgsSummary(updateIn(sstate, value), args, errors, warnings :+ s"Flag $name set repeatedly")
119-
else {
120-
changed = true
121-
ArgsSummary(updateIn(sstate, value), args, errors, warnings)
122-
}
119+
val (value1, twicely) =
120+
if changed && isMultivalue then
121+
val value0 = value.asInstanceOf[List[String]]
122+
val current = valueIn(sstate).asInstanceOf[List[String]]
123+
val newly = current ++ value0.filterNot(current.contains)
124+
(newly, value0.exists(current.contains))
125+
else
126+
(value, changed)
127+
val dangers = if twicely then warnings :+ s"Flag $name set repeatedly" else warnings
128+
changed = true
129+
ArgsSummary(updateIn(sstate, value1), args, errors, dangers)
123130
def fail(msg: String, args: List[String]) =
124131
ArgsSummary(sstate, args, errors :+ msg, warnings)
125132
def missingArg =
@@ -226,7 +233,7 @@ object Settings {
226233
*
227234
* to get their arguments.
228235
*/
229-
protected def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
236+
protected[config] def processArguments(state: ArgsSummary, processAll: Boolean, skipped: List[String]): ArgsSummary = {
230237
def stateWithArgs(args: List[String]) = ArgsSummary(state.sstate, args, state.errors, state.warnings)
231238
state.arguments match {
232239
case Nil =>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package dotty.tools.dotc
2+
package config
3+
4+
import CommandLineParser.tokenize
5+
import Settings._
6+
7+
import org.junit.Test
8+
import org.junit.Assert._
9+
10+
class ScalaSettingsTests:
11+
12+
@Test def `A multistring setting is multivalued`: Unit =
13+
class SUT extends SettingGroup:
14+
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.")
15+
val sut = SUT()
16+
val args = tokenize("-language:implicitConversions,dynamics")
17+
val sumy = ArgsSummary(sut.defaultState, args, errors = Nil, warnings = Nil)
18+
val res = sut.processArguments(sumy, processAll = true, skipped = Nil)
19+
val set = sut.language.valueIn(res.sstate)
20+
assertEquals(1, args.length)
21+
assertTrue("No warnings!", res.warnings.isEmpty)
22+
assertTrue("No errors!", res.errors.isEmpty)
23+
assertTrue("Has the feature", set.contains("implicitConversions"))
24+
assertTrue("Has the feature", set.contains("dynamics"))
25+
26+
@Test def `t9719 Apply -language more than once`: Unit =
27+
class SUT extends SettingGroup:
28+
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.")
29+
val sut = SUT()
30+
val args = tokenize("-language:implicitConversions -language:dynamics")
31+
val sumy = ArgsSummary(sut.defaultState, args, errors = Nil, warnings = Nil)
32+
val res = sut.processArguments(sumy, processAll = true, skipped = Nil)
33+
val set = sut.language.valueIn(res.sstate)
34+
assertEquals(2, args.length)
35+
assertTrue("No warnings!", res.warnings.isEmpty)
36+
assertTrue("No errors!", res.errors.isEmpty)
37+
assertTrue("Has the feature", set.contains("implicitConversions"))
38+
assertTrue("Has the feature", set.contains("dynamics"))
39+
40+
@Test def `Warn if multistring element is supplied multiply`: Unit =
41+
class SUT extends SettingGroup:
42+
val language: Setting[List[String]] = MultiStringSetting("-language", "feature", "Enable one or more language features.")
43+
val sut = SUT()
44+
val args = tokenize("-language:dynamics -language:implicitConversions -language:dynamics")
45+
val sumy = ArgsSummary(sut.defaultState, args, errors = Nil, warnings = Nil)
46+
val res = sut.processArguments(sumy, processAll = true, skipped = Nil)
47+
val set = sut.language.valueIn(res.sstate)
48+
assertEquals(3, args.length)
49+
assertEquals("Must warn", 1, res.warnings.length)
50+
assertTrue("No errors!", res.errors.isEmpty)
51+
assertTrue("Has the feature", set.contains("implicitConversions"))
52+
assertTrue("Has the feature", set.contains("dynamics"))
53+
54+
end ScalaSettingsTests

0 commit comments

Comments
 (0)
Please sign in to comment.