Skip to content

Commit

Permalink
Allow BooleanSettings to be set with a colon (#16425)
Browse files Browse the repository at this point in the history
e.g. "-explain:true" and "-explain:false" should be allowed
  • Loading branch information
KacperFKorban authored Dec 1, 2022
2 parents e842810 + 54b1f61 commit e16ff26
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
15 changes: 10 additions & 5 deletions compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ object Settings:

def updateIn(state: SettingsState, x: Any): SettingsState = x match
case _: T => state.update(idx, x)
case _ => throw IllegalArgumentException(s"found: $x of type ${x.getClass.getName}, required: ${implicitly[ClassTag[T]]}")
case _ => throw IllegalArgumentException(s"found: $x of type ${x.getClass.getName}, required: ${summon[ClassTag[T]]}")

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

def isMultivalue: Boolean = implicitly[ClassTag[T]] == ListTag
def isMultivalue: Boolean = summon[ClassTag[T]] == ListTag

def legalChoices: String =
choices match {
Expand Down Expand Up @@ -106,6 +106,11 @@ object Settings:
def missingArg =
fail(s"missing argument for option $name", args)

def setBoolean(argValue: String, args: List[String]) =
if argValue.equalsIgnoreCase("true") || argValue.isEmpty then update(true, args)
else if argValue.equalsIgnoreCase("false") then update(false, args)
else fail(s"$argValue is not a valid choice for boolean setting $name", args)

def setString(argValue: String, args: List[String]) =
choices match
case Some(xs) if !xs.contains(argValue) =>
Expand All @@ -126,9 +131,9 @@ object Settings:
catch case _: NumberFormatException =>
fail(s"$argValue is not an integer argument for $name", args)

def doSet(argRest: String) = ((implicitly[ClassTag[T]], args): @unchecked) match {
def doSet(argRest: String) = ((summon[ClassTag[T]], args): @unchecked) match {
case (BooleanTag, _) =>
update(true, args)
setBoolean(argRest, args)
case (OptionTag, _) =>
update(Some(propertyClass.get.getConstructor().newInstance()), args)
case (ListTag, _) =>
Expand Down Expand Up @@ -290,6 +295,6 @@ object Settings:
publish(Setting(name, descr, default))

def OptionSetting[T: ClassTag](name: String, descr: String, aliases: List[String] = Nil): Setting[Option[T]] =
publish(Setting(name, descr, None, propertyClass = Some(implicitly[ClassTag[T]].runtimeClass), aliases = aliases))
publish(Setting(name, descr, None, propertyClass = Some(summon[ClassTag[T]].runtimeClass), aliases = aliases))
}
end Settings
19 changes: 19 additions & 0 deletions compiler/test/dotty/tools/dotc/SettingsTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,25 @@ class SettingsTests {
assertEquals(100, foo.value)
}

@Test def `Set BooleanSettings correctly`: Unit =
object Settings extends SettingGroup:
val foo = BooleanSetting("-foo", "foo", false)
val bar = BooleanSetting("-bar", "bar", true)
val baz = BooleanSetting("-baz", "baz", false)
val qux = BooleanSetting("-qux", "qux", false)
import Settings._

val args = List("-foo:true", "-bar:false", "-baz", "-qux:true", "-qux:false")
val summary = processArguments(args, processAll = true)
assertTrue(s"Setting args errors:\n ${summary.errors.take(5).mkString("\n ")}", summary.errors.isEmpty)
withProcessedArgs(summary) {
assertEquals(true, foo.value)
assertEquals(false, bar.value)
assertEquals(true, baz.value)
assertEquals(false, qux.value)
assertEquals(List("Flag -qux set repeatedly"), summary.warnings)
}

private def withProcessedArgs(summary: ArgsSummary)(f: SettingsState ?=> Unit) = f(using summary.sstate)

extension [T](setting: Setting[T])
Expand Down

0 comments on commit e16ff26

Please sign in to comment.