Skip to content

Commit 67a6300

Browse files
committed
A setting alias is a SettingAlias
1 parent 120ed58 commit 67a6300

File tree

4 files changed

+163
-78
lines changed

4 files changed

+163
-78
lines changed

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package dotty.tools.dotc
22
package config
33

44
import dotty.tools.dotc.config.PathResolver.Defaults
5-
import dotty.tools.dotc.config.Settings.{Setting, SettingGroup, SettingCategory, Deprecation}
5+
import dotty.tools.dotc.config.Settings.{Setting, SettingAlias, SettingGroup, SettingCategory, Deprecation}
66
import dotty.tools.dotc.config.SourceVersion
77
import dotty.tools.dotc.core.Contexts.*
88
import dotty.tools.dotc.rewrites.Rewrites
@@ -40,7 +40,7 @@ abstract class ScalaSettings extends SettingGroup, AllScalaSettings:
4040
val forkSettings: List[Setting[?]] = settingsByCategory(ForkSetting).sortBy(_.name)
4141
val advancedSettings: List[Setting[?]] = settingsByCategory(AdvancedSetting).sortBy(_.name)
4242
val verboseSettings: List[Setting[?]] = settingsByCategory(VerboseSetting).sortBy(_.name)
43-
val settingsByAliases: Map[String, Setting[?]] = allSettings.flatMap(s => s.aliases.map(_ -> s)).toMap
43+
val settingsByAliases: Map[String, Setting[?]] = allSettings.flatMap(s => s.aliases.map(_.name -> s)).toMap
4444

4545

4646
trait AllScalaSettings extends CommonScalaSettings, PluginSettings, VerboseSettings, WarningSettings, XSettings, YSettings:
@@ -146,8 +146,8 @@ private sealed trait PluginSettings:
146146
private sealed trait VerboseSettings:
147147
self: SettingGroup =>
148148
val Vhelp: Setting[Boolean] = BooleanSetting(VerboseSetting, "V", "Print a synopsis of verbose options.")
149-
val Vprint: Setting[List[String]] = PhasesSetting(VerboseSetting, "Vprint", "Print out program after", deprecatedAliases = List("-Xprint" -> Deprecation()))
150-
val XshowPhases: Setting[Boolean] = BooleanSetting(VerboseSetting, "Vphases", "List compiler phases.", deprecatedAliases = List("-Xshow-phases" -> Deprecation()))
149+
val Vprint: Setting[List[String]] = PhasesSetting(VerboseSetting, "Vprint", "Print out program after", aliases = SettingAlias("-Xprint", Deprecation()) :: Nil)
150+
val XshowPhases: Setting[Boolean] = BooleanSetting(VerboseSetting, "Vphases", "List compiler phases.", aliases = SettingAlias("-Xshow-phases", Deprecation()) :: Nil)
151151

152152
val Vprofile: Setting[Boolean] = BooleanSetting(VerboseSetting, "Vprofile", "Show metrics about sources and internal representations to estimate compile-time complexity.")
153153
val VprofileSortedBy = ChoiceSetting(VerboseSetting, "Vprofile-sorted-by", "key", "Show metrics about sources and internal representations sorted by given column name", List("name", "path", "lines", "tokens", "tasty", "complexity"), "")
@@ -161,7 +161,7 @@ private sealed trait WarningSettings:
161161
self: SettingGroup =>
162162

163163
val Whelp: Setting[Boolean] = BooleanSetting(WarningSetting, "W", "Print a synopsis of warning options.")
164-
val Werror: Setting[Boolean] = BooleanSetting(WarningSetting, "Werror", "Fail the compilation if there are any warnings.", deprecatedAliases = List("-Xfatal-warnings" -> Deprecation()))
164+
val Werror: Setting[Boolean] = BooleanSetting(WarningSetting, "Werror", "Fail the compilation if there are any warnings.", aliases = SettingAlias("-Xfatal-warnings", Deprecation()) :: Nil)
165165
val Wall: Setting[Boolean] = BooleanSetting(WarningSetting, "Wall", "Enable all warning settings.")
166166
private val WvalueDiscard: Setting[Boolean] = BooleanSetting(WarningSetting, "Wvalue-discard", "Warn when non-Unit expression results are unused.")
167167
private val WNonUnitStatement = BooleanSetting(WarningSetting, "Wnonunit-statement", "Warn when block statements are non-Unit expressions.")

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

Lines changed: 66 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ object Settings:
9292
*/
9393
type SettingDependencies = List[(Setting[?], Any)]
9494

95+
case class SettingAlias(name: String, deprecation: Option[Deprecation])
96+
object SettingAlias:
97+
given Conversion[String, SettingAlias] = SettingAlias(_, None)
98+
def apply(name: String): SettingAlias = SettingAlias(name, None)
99+
def apply(name: String, deprecation: Deprecation): SettingAlias = SettingAlias(name, Some(deprecation))
100+
95101
case class Setting[T] private[Settings] (
96102
category: SettingCategory,
97103
name: String,
@@ -100,21 +106,23 @@ object Settings:
100106
helpArg: String = "",
101107
choices: Option[Seq[?]] = None,
102108
prefix: Option[String] = None,
103-
aliases: List[String] = Nil,
109+
aliases: List[SettingAlias] = Nil,
104110
depends: SettingDependencies = Nil,
105111
ignoreInvalidArgs: Boolean = false,
106112
preferPrevious: Boolean = false,
107113
propertyClass: Option[Class[?]] = None,
108114
deprecation: Option[Deprecation] = None,
109-
deprecatedAliases: List[(String, Deprecation)] = Nil,
110115
// kept only for -Xkind-projector option compatibility
111116
legacyArgs: Boolean = false,
112117
// accept legacy choices (for example, valid in Scala 2 but no longer supported)
113118
legacyChoices: Option[Seq[?]] = None)(private[Settings] val idx: Int)(using ct: ClassTag[T]):
114119

115120
validateSettingString(prefix.getOrElse(name))
116-
aliases.foreach(validateSettingString)
117-
deprecatedAliases.foreach((alias, _) => validateSettingString(alias))
121+
for alias <- aliases do
122+
validateSettingString(alias.name)
123+
val msg = "An alias is only \"replaced by\" its primary setting; its deprecation can have only a custom message."
124+
for dep <- alias.deprecation do
125+
assert(!dep.replacedBy.isDefined, msg)
118126
assert(name.startsWith(s"-${category.prefixLetter}"), s"Setting $name does not start with category -$category")
119127
assert(legacyArgs || !choices.exists(_.contains("")), s"Empty string is not supported as a choice for setting $name")
120128
validateSettingTag(ct)
@@ -123,7 +131,7 @@ object Settings:
123131
// Example: -opt Main.scala would be interpreted as -opt:Main.scala, and the source file would be ignored.
124132
assert(!(ct == ListTag && ignoreInvalidArgs), s"Ignoring invalid args is not supported for multivalue settings: $name")
125133

126-
val allFullNames: List[String] = s"$name" :: s"-$name" :: aliases ::: deprecatedAliases.map(_._1)
134+
val allFullNames: List[String] = s"$name" :: s"-$name" :: aliases.map(_.name)
127135

128136
def valueIn(state: SettingsState): T = state.value(idx).asInstanceOf[T]
129137

@@ -163,18 +171,31 @@ object Settings:
163171
* @return updated argument state
164172
*/
165173
def update(value: => Any, altArg: String, args: List[String])(using ArgsSummary): ArgsSummary =
166-
deprecation match
167-
case Some(Deprecation(msg, Some(replacedBy))) =>
168-
val deprecatedMsg = s"Option $name is deprecated: $msg"
169-
val altArg1 =
170-
if altArg.isEmpty then List(replacedBy)
171-
else List(s"$replacedBy:$altArg")
172-
state.deprecated(deprecatedMsg, altArg1, args) // retry with reconstructed arg
173-
case Some(Deprecation(msg, _)) =>
174-
state.updated(updateIn(sstate, value), args) // allow but warn
175-
.warn(s"Option $name is deprecated: $msg")
176-
case None =>
177-
state.updated(updateIn(sstate, value), args)
174+
def checkDeprecatedAlias()(using ArgsSummary) =
175+
val name = arg.takeWhile(_ != ':')
176+
aliases.find(alt => alt.name == name && alt.deprecation.isDefined)
177+
.map:
178+
case SettingAlias(alt, dep) =>
179+
val msg =
180+
dep.collect:
181+
case dep if dep.msg.nonEmpty => dep.msg
182+
.getOrElse(s"use ${this.name} instead")
183+
state.warn(s"Option $alt is a deprecated alias: $msg", args)
184+
.getOrElse(state)
185+
def doUpdate(using ArgsSummary) =
186+
deprecation match
187+
case Some(Deprecation(msg, Some(replacedBy))) =>
188+
val deprecatedMsg = s"Option $name is deprecated: $msg"
189+
val altArg1 =
190+
if altArg.isEmpty then List(replacedBy)
191+
else List(s"$replacedBy:$altArg")
192+
state.deprecated(deprecatedMsg, altArg1, args) // retry with reconstructed arg
193+
case Some(Deprecation(msg, _)) =>
194+
state.updated(updateIn(sstate, value), args) // allow but warn
195+
.warn(s"Option $name is deprecated: $msg")
196+
case None =>
197+
state.updated(updateIn(sstate, value), args)
198+
doUpdate(using checkDeprecatedAlias())
178199
end update
179200

180201
def setBoolean(argValue: String, args: List[String])(using ArgsSummary) =
@@ -293,25 +314,19 @@ object Settings:
293314
val name = arg.takeWhile(_ != ':')
294315
allFullNames.exists(_ == name) || prefix.exists(arg.startsWith)
295316

296-
def checkDeprecatedAlias()(using ArgsSummary) =
297-
val name = arg.takeWhile(_ != ':')
298-
val found = deprecatedAliases.find((alt, _) => alt == name)
299-
found.map: (alt, dep) =>
300-
val msg = if dep.msg.nonEmpty then dep.msg else s"use ${this.name} instead"
301-
state.warn(s"Option $alt is a deprecated alias: $msg", args)
302-
.getOrElse(state)
303-
304317
if matches then
305-
val checked = checkDeprecatedAlias()(using state0)
306-
given ArgsSummary = checked
318+
given ArgsSummary = state0
307319
deprecation match
308320
case Some(Deprecation(msg, _)) if ignoreInvalidArgs => // a special case for Xlint
309321
state.warn(s"Option $name is deprecated: $msg", args)
310322
case _ =>
311323
prefix match
312324
case Some(prefix) =>
313-
// todo an error if empty suffix
314-
doSet(arg.drop(prefix.length), useArg = true)
325+
val value = arg.drop(prefix.length)
326+
if value.isEmpty then
327+
state.warn(s"Option $name requires a suffix: $arg", args)
328+
else
329+
doSet(value, useArg = true)
315330
case none =>
316331
val split = arg.split(":", 2)
317332
if split.length == 1 then
@@ -437,38 +452,38 @@ object Settings:
437452
assert(!name.startsWith("-"), s"Setting $name cannot start with -")
438453
"-" + name
439454

440-
def BooleanSetting(category: SettingCategory, name: String, descr: String, initialValue: Boolean = false, aliases: List[String] = Nil, preferPrevious: Boolean = false, deprecation: Option[Deprecation] = None, ignoreInvalidArgs: Boolean = false, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[Boolean] =
441-
publish(Setting(category, prependName(name), descr, initialValue, aliases = aliases, preferPrevious = preferPrevious, deprecation = deprecation, ignoreInvalidArgs = ignoreInvalidArgs, deprecatedAliases = deprecatedAliases))
455+
def BooleanSetting(category: SettingCategory, name: String, descr: String, initialValue: Boolean = false, aliases: List[SettingAlias] = Nil, preferPrevious: Boolean = false, deprecation: Option[Deprecation] = None, ignoreInvalidArgs: Boolean = false): Setting[Boolean] =
456+
publish(Setting(category, prependName(name), descr, initialValue, aliases = aliases, preferPrevious = preferPrevious, deprecation = deprecation, ignoreInvalidArgs = ignoreInvalidArgs))
442457

443-
def StringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: String, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, depends: SettingDependencies = Nil, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[String] =
444-
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, deprecation = deprecation, depends = depends, deprecatedAliases = deprecatedAliases))
458+
def StringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: String, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None, depends: SettingDependencies = Nil): Setting[String] =
459+
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, deprecation = deprecation, depends = depends))
445460

446-
def ChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: String, aliases: List[String] = Nil, legacyArgs: Boolean = false, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[String] =
447-
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), aliases = aliases, legacyArgs = legacyArgs, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
461+
def ChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: String, aliases: List[SettingAlias] = Nil, legacyArgs: Boolean = false, deprecation: Option[Deprecation] = None): Setting[String] =
462+
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), aliases = aliases, legacyArgs = legacyArgs, deprecation = deprecation))
448463

449-
def MultiChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: List[String] = Nil, legacyChoices: List[String] = Nil, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[List[String]] =
450-
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), legacyChoices = Some(legacyChoices), aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
464+
def MultiChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: List[String] = Nil, legacyChoices: List[String] = Nil, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[List[String]] =
465+
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), legacyChoices = Some(legacyChoices), aliases = aliases, deprecation = deprecation))
451466

452-
def MultiChoiceHelpSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[ChoiceWithHelp[String]], default: List[ChoiceWithHelp[String]], legacyChoices: List[String] = Nil, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[List[ChoiceWithHelp[String]]] =
453-
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), legacyChoices = Some(legacyChoices), aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
467+
def MultiChoiceHelpSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[ChoiceWithHelp[String]], default: List[ChoiceWithHelp[String]], legacyChoices: List[String] = Nil, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[List[ChoiceWithHelp[String]]] =
468+
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), legacyChoices = Some(legacyChoices), aliases = aliases, deprecation = deprecation))
454469

455-
def IntSetting(category: SettingCategory, name: String, descr: String, default: Int, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[Int] =
456-
publish(Setting(category, prependName(name), descr, default, aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
470+
def IntSetting(category: SettingCategory, name: String, descr: String, default: Int, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[Int] =
471+
publish(Setting(category, prependName(name), descr, default, aliases = aliases, deprecation = deprecation))
457472

458473
def IntChoiceSetting(category: SettingCategory, name: String, descr: String, choices: Seq[Int], default: Int, deprecation: Option[Deprecation] = None): Setting[Int] =
459474
publish(Setting(category, prependName(name), descr, default, choices = Some(choices), deprecation = deprecation))
460475

461-
def MultiStringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: List[String] = Nil, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[List[String]] =
462-
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
476+
def MultiStringSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: List[String] = Nil, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[List[String]] =
477+
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, deprecation = deprecation))
463478

464-
def OutputSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: AbstractFile, aliases: List[String] = Nil, preferPrevious: Boolean = false, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[AbstractFile] =
465-
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, preferPrevious = preferPrevious, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
479+
def OutputSetting(category: SettingCategory, name: String, helpArg: String, descr: String, default: AbstractFile, aliases: List[SettingAlias] = Nil, preferPrevious: Boolean = false, deprecation: Option[Deprecation] = None): Setting[AbstractFile] =
480+
publish(Setting(category, prependName(name), descr, default, helpArg, aliases = aliases, preferPrevious = preferPrevious, deprecation = deprecation))
466481

467-
def PathSetting(category: SettingCategory, name: String, descr: String, default: String, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[String] =
468-
publish(Setting(category, prependName(name), descr, default, aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
482+
def PathSetting(category: SettingCategory, name: String, descr: String, default: String, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[String] =
483+
publish(Setting(category, prependName(name), descr, default, aliases = aliases, deprecation = deprecation))
469484

470-
def PhasesSetting(category: SettingCategory, name: String, descr: String, default: String = "", aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, depends: SettingDependencies = Nil, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[List[String]] =
471-
publish(Setting(category, prependName(name), descr, if (default.isEmpty) Nil else List(default), aliases = aliases, deprecation = deprecation, depends = depends, deprecatedAliases = deprecatedAliases))
485+
def PhasesSetting(category: SettingCategory, name: String, descr: String, default: String = "", aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None, depends: SettingDependencies = Nil): Setting[List[String]] =
486+
publish(Setting(category, prependName(name), descr, if (default.isEmpty) Nil else List(default), aliases = aliases, deprecation = deprecation, depends = depends))
472487

473488
def PrefixSetting(category: SettingCategory, name0: String, descr: String, deprecation: Option[Deprecation] = None): Setting[List[String]] =
474489
val name = prependName(name0)
@@ -478,8 +493,8 @@ object Settings:
478493
def VersionSetting(category: SettingCategory, name: String, descr: String, default: ScalaVersion = NoScalaVersion, legacyArgs: Boolean = false, deprecation: Option[Deprecation] = None): Setting[ScalaVersion] =
479494
publish(Setting(category, prependName(name), descr, default, legacyArgs = legacyArgs, deprecation = deprecation))
480495

481-
def OptionSetting[T: ClassTag](category: SettingCategory, name: String, descr: String, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None, deprecatedAliases: List[(String, Deprecation)] = Nil): Setting[Option[T]] =
482-
publish(Setting(category, prependName(name), descr, None, propertyClass = Some(summon[ClassTag[T]].runtimeClass), aliases = aliases, deprecation = deprecation, deprecatedAliases = deprecatedAliases))
496+
def OptionSetting[T: ClassTag](category: SettingCategory, name: String, descr: String, aliases: List[SettingAlias] = Nil, deprecation: Option[Deprecation] = None): Setting[Option[T]] =
497+
publish(Setting(category, prependName(name), descr, None, propertyClass = Some(summon[ClassTag[T]].runtimeClass), aliases = aliases, deprecation = deprecation))
483498

484499
end SettingGroup
485500
end Settings

0 commit comments

Comments
 (0)