Skip to content

Commit

Permalink
Unify settings parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
szymon-rd committed Mar 5, 2024
1 parent 7a3aac7 commit c0bd89a
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 36 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ private sealed trait YSettings:
val YstopBefore: Setting[List[String]] = PhasesSetting(ForkSetting, "Ystop-before", "Stop before") // stop before erasure as long as we have not debugged it fully
val YshowSuppressedErrors: Setting[Boolean] = BooleanSetting(ForkSetting, "Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally suppressed.")
val YdetailedStats: Setting[Boolean] = BooleanSetting(ForkSetting, "Ydetailed-stats", "Show detailed internal compiler stats (needs Stats.enabled to be set to true).")
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")
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")
val YprintPos: Setting[Boolean] = BooleanSetting(ForkSetting, "Yprint-pos", "Show tree positions.")
val YprintPosSyms: Setting[Boolean] = BooleanSetting(ForkSetting, "Yprint-pos-syms", "Show symbol definitions positions.")
val YnoDeepSubtypes: Setting[Boolean] = BooleanSetting(ForkSetting, "Yno-deep-subtypes", "Throw an exception on deep subtyping call stacks.")
Expand Down
64 changes: 32 additions & 32 deletions compiler/src/dotty/tools/dotc/config/Settings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ object Settings:
ignoreInvalidArgs: Boolean = false,
propertyClass: Option[Class[?]] = None,
deprecationMsg: Option[String] = None)(private[Settings] val idx: Int) {



assert(name.startsWith(s"-$category"), s"Setting $name does not start with category -$category")

assert(!choices.contains(""), s"Empty string is not supported as a choice for setting $name")
// Without the following assertion, it would be easy to mistakenly try to pass a file to a setting that ignores invalid args.
// Example: -opt Main.scala would be interpreted as -opt:Main.scala, and the source file would be ignored.
assert(!(summon[ClassTag[T]] == ListTag && ignoreInvalidArgs), s"Ignoring invalid args is not supported for multivalue settings: $name")
Expand Down Expand Up @@ -165,6 +166,12 @@ object Settings:
val output = if (isJar) JarArchive.create(path) else new PlainDirectory(path)
update(output, args)
}

def setVersion(argValue: String, args: List[String]) =
ScalaVersion.parse(argValue) match {
case Success(v) => update(v, args)
case Failure(ex) => fail(ex.getMessage, args)
}

def appendList(strings: List[String], args: List[String]) =
choices match
Expand All @@ -180,38 +187,31 @@ object Settings:
setBoolean(argRest, args)
case (OptionTag, _) =>
update(Some(propertyClass.get.getConstructor().newInstance()), args)
case (ListTag, args) if argRest.nonEmpty =>
val strings = argRest.split(",").toList
appendList(strings, args)
case (ListTag, arg2 :: args2) if !(arg2 startsWith "-")=>
appendList(arg2 :: Nil, args2)
case (StringTag, _) if argRest.nonEmpty || choices.exists(_.contains("")) =>
setString(argRest, args)
case (StringTag, arg2 :: args2) =>
if (arg2 startsWith "-") missingArg
else setString(arg2, args2)
case (OutputTag, args) if argRest.nonEmpty =>
setOutput(argRest, args)
case (OutputTag, arg2 :: args2) =>
setOutput(arg2, args2)
case (IntTag, args) if argRest.nonEmpty =>
setInt(argRest, args)
case (IntTag, arg2 :: args2) =>
setInt(arg2, args2)
case (VersionTag, _) if argRest.nonEmpty =>
ScalaVersion.parse(argRest) match {
case Success(v) => update(v, args)
case Failure(ex) => fail(ex.getMessage, args)
}
case (VersionTag, arg2 :: args2) =>
ScalaVersion.parse(arg2) match {
case Success(v) => update(v, args2)
case Failure(ex) => fail(ex.getMessage, args2)
}
case (_, Nil) =>
missingArg
case (_, args) =>
val argInArgRest = !argRest.isEmpty
val argAfterParam = !argInArgRest && args.nonEmpty && !args.head.startsWith("-")
if argInArgRest then
doSetArg(argRest, args)
else if argAfterParam then
doSetArg(args.head, args.tail)
else missingArg
}

def doSetArg(arg: String, argsLeft: List[String]) = summon[ClassTag[T]] match
case ListTag =>
val strings = arg.split(",").toList
appendList(strings, argsLeft)
case StringTag =>
setString(arg, argsLeft)
case OutputTag =>
setOutput(arg, argsLeft)
case IntTag =>
setInt(arg, argsLeft)
case VersionTag =>
setVersion(arg, argsLeft)
case _ =>
missingArg

def matches(argName: String): Boolean =
(allFullNames).exists(_ == argName.takeWhile(_ != ':')) || prefix.exists(arg.startsWith)

Expand Down
2 changes: 1 addition & 1 deletion tests/neg/kind-projector.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -Ykind-projector
//> using options -Ykind-projector:enable

package kind_projector_neg

Expand Down
2 changes: 1 addition & 1 deletion tests/pos-with-compiler-cc/dotc/config/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ private sealed trait YSettings:
val YstopBefore: Setting[List[String]] = PhasesSetting("-Ystop-before", "Stop before") // stop before erasure as long as we have not debugged it fully
val YshowSuppressedErrors: Setting[Boolean] = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally suppressed.")
val YdetailedStats: Setting[Boolean] = BooleanSetting("-Ydetailed-stats", "Show detailed internal compiler stats (needs Stats.enabled to be set to true).")
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")
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")
val YprintPos: Setting[Boolean] = BooleanSetting("-Yprint-pos", "Show tree positions.")
val YprintPosSyms: Setting[Boolean] = BooleanSetting("-Yprint-pos-syms", "Show symbol definitions positions.")
val YnoDeepSubtypes: Setting[Boolean] = BooleanSetting("-Yno-deep-subtypes", "Throw an exception on deep subtyping call stacks.")
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/kind-projector.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//> using options -Ykind-projector
//> using options -Ykind-projector:enable

package kind_projector

Expand Down

0 comments on commit c0bd89a

Please sign in to comment.