Skip to content

Commit c0bd89a

Browse files
committed
Unify settings parsing
1 parent 7a3aac7 commit c0bd89a

File tree

5 files changed

+36
-36
lines changed

5 files changed

+36
-36
lines changed

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ private sealed trait YSettings:
400400
val YstopBefore: Setting[List[String]] = PhasesSetting(ForkSetting, "Ystop-before", "Stop before") // stop before erasure as long as we have not debugged it fully
401401
val YshowSuppressedErrors: Setting[Boolean] = BooleanSetting(ForkSetting, "Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally suppressed.")
402402
val YdetailedStats: Setting[Boolean] = BooleanSetting(ForkSetting, "Ydetailed-stats", "Show detailed internal compiler stats (needs Stats.enabled to be set to true).")
403-
val YkindProjector: Setting[String] = ChoiceSetting(ForkSetting, "Ykind-projector", "[underscores, disable]", "Allow `*` as type lambda placeholder to be compatible with kind projector. When invoked as -Ykind-projector:underscores will repurpose `_` to be a type parameter placeholder, this will disable usage of underscore as a wildcard.", List("disable", "", "underscores"), "disable")
403+
val YkindProjector: Setting[String] = ChoiceSetting(ForkSetting, "Ykind-projector", "[underscores, enable, disable]", "Allow `*` as type lambda placeholder to be compatible with kind projector. When invoked as -Ykind-projector:underscores will repurpose `_` to be a type parameter placeholder, this will disable usage of underscore as a wildcard.", List("disable", "enable", "underscores"), "disable")
404404
val YprintPos: Setting[Boolean] = BooleanSetting(ForkSetting, "Yprint-pos", "Show tree positions.")
405405
val YprintPosSyms: Setting[Boolean] = BooleanSetting(ForkSetting, "Yprint-pos-syms", "Show symbol definitions positions.")
406406
val YnoDeepSubtypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-deep-subtypes", "Throw an exception on deep subtyping call stacks.")

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

+32-32
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ object Settings:
7272
ignoreInvalidArgs: Boolean = false,
7373
propertyClass: Option[Class[?]] = None,
7474
deprecationMsg: Option[String] = None)(private[Settings] val idx: Int) {
75-
75+
76+
7677
assert(name.startsWith(s"-$category"), s"Setting $name does not start with category -$category")
77-
78+
assert(!choices.contains(""), s"Empty string is not supported as a choice for setting $name")
7879
// Without the following assertion, it would be easy to mistakenly try to pass a file to a setting that ignores invalid args.
7980
// Example: -opt Main.scala would be interpreted as -opt:Main.scala, and the source file would be ignored.
8081
assert(!(summon[ClassTag[T]] == ListTag && ignoreInvalidArgs), s"Ignoring invalid args is not supported for multivalue settings: $name")
@@ -165,6 +166,12 @@ object Settings:
165166
val output = if (isJar) JarArchive.create(path) else new PlainDirectory(path)
166167
update(output, args)
167168
}
169+
170+
def setVersion(argValue: String, args: List[String]) =
171+
ScalaVersion.parse(argValue) match {
172+
case Success(v) => update(v, args)
173+
case Failure(ex) => fail(ex.getMessage, args)
174+
}
168175

169176
def appendList(strings: List[String], args: List[String]) =
170177
choices match
@@ -180,38 +187,31 @@ object Settings:
180187
setBoolean(argRest, args)
181188
case (OptionTag, _) =>
182189
update(Some(propertyClass.get.getConstructor().newInstance()), args)
183-
case (ListTag, args) if argRest.nonEmpty =>
184-
val strings = argRest.split(",").toList
185-
appendList(strings, args)
186-
case (ListTag, arg2 :: args2) if !(arg2 startsWith "-")=>
187-
appendList(arg2 :: Nil, args2)
188-
case (StringTag, _) if argRest.nonEmpty || choices.exists(_.contains("")) =>
189-
setString(argRest, args)
190-
case (StringTag, arg2 :: args2) =>
191-
if (arg2 startsWith "-") missingArg
192-
else setString(arg2, args2)
193-
case (OutputTag, args) if argRest.nonEmpty =>
194-
setOutput(argRest, args)
195-
case (OutputTag, arg2 :: args2) =>
196-
setOutput(arg2, args2)
197-
case (IntTag, args) if argRest.nonEmpty =>
198-
setInt(argRest, args)
199-
case (IntTag, arg2 :: args2) =>
200-
setInt(arg2, args2)
201-
case (VersionTag, _) if argRest.nonEmpty =>
202-
ScalaVersion.parse(argRest) match {
203-
case Success(v) => update(v, args)
204-
case Failure(ex) => fail(ex.getMessage, args)
205-
}
206-
case (VersionTag, arg2 :: args2) =>
207-
ScalaVersion.parse(arg2) match {
208-
case Success(v) => update(v, args2)
209-
case Failure(ex) => fail(ex.getMessage, args2)
210-
}
211-
case (_, Nil) =>
212-
missingArg
190+
case (_, args) =>
191+
val argInArgRest = !argRest.isEmpty
192+
val argAfterParam = !argInArgRest && args.nonEmpty && !args.head.startsWith("-")
193+
if argInArgRest then
194+
doSetArg(argRest, args)
195+
else if argAfterParam then
196+
doSetArg(args.head, args.tail)
197+
else missingArg
213198
}
214199

200+
def doSetArg(arg: String, argsLeft: List[String]) = summon[ClassTag[T]] match
201+
case ListTag =>
202+
val strings = arg.split(",").toList
203+
appendList(strings, argsLeft)
204+
case StringTag =>
205+
setString(arg, argsLeft)
206+
case OutputTag =>
207+
setOutput(arg, argsLeft)
208+
case IntTag =>
209+
setInt(arg, argsLeft)
210+
case VersionTag =>
211+
setVersion(arg, argsLeft)
212+
case _ =>
213+
missingArg
214+
215215
def matches(argName: String): Boolean =
216216
(allFullNames).exists(_ == argName.takeWhile(_ != ':')) || prefix.exists(arg.startsWith)
217217

tests/neg/kind-projector.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -Ykind-projector
1+
//> using options -Ykind-projector:enable
22

33
package kind_projector_neg
44

tests/pos-with-compiler-cc/dotc/config/ScalaSettings.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ private sealed trait YSettings:
289289
val YstopBefore: Setting[List[String]] = PhasesSetting("-Ystop-before", "Stop before") // stop before erasure as long as we have not debugged it fully
290290
val YshowSuppressedErrors: Setting[Boolean] = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally suppressed.")
291291
val YdetailedStats: Setting[Boolean] = BooleanSetting("-Ydetailed-stats", "Show detailed internal compiler stats (needs Stats.enabled to be set to true).")
292-
val YkindProjector: Setting[String] = ChoiceSetting("-Ykind-projector", "[underscores, disable]", "Allow `*` as type lambda placeholder to be compatible with kind projector. When invoked as -Ykind-projector:underscores will repurpose `_` to be a type parameter placeholder, this will disable usage of underscore as a wildcard.", List("disable", "", "underscores"), "disable")
292+
val YkindProjector: Setting[String] = ChoiceSetting("-Ykind-projector", "[underscores, enable, disable]", "Allow `*` as type lambda placeholder to be compatible with kind projector. When invoked as -Ykind-projector:underscores will repurpose `_` to be a type parameter placeholder, this will disable usage of underscore as a wildcard.", List("disable", "enable", "underscores"), "disable")
293293
val YprintPos: Setting[Boolean] = BooleanSetting("-Yprint-pos", "Show tree positions.")
294294
val YprintPosSyms: Setting[Boolean] = BooleanSetting("-Yprint-pos-syms", "Show symbol definitions positions.")
295295
val YnoDeepSubtypes: Setting[Boolean] = BooleanSetting("-Yno-deep-subtypes", "Throw an exception on deep subtyping call stacks.")

tests/pos/kind-projector.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//> using options -Ykind-projector
1+
//> using options -Ykind-projector:enable
22

33
package kind_projector
44

0 commit comments

Comments
 (0)