summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/settings
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@typesafe.com>2014-07-16 12:25:34 +0200
committerLukas Rytz <lukas.rytz@typesafe.com>2014-07-16 12:25:34 +0200
commit04cb634ec4564c6ee3bd34c3cef899537c3787ba (patch)
tree2acaa0c06544acd35aa286f56dba368996748fad /src/compiler/scala/tools/nsc/settings
parent0f8b07a8d7deda602a41859a175b0b46bb113d51 (diff)
parent3b89c168b4926139f7295183fdc1903f6f553798 (diff)
downloadscala-04cb634ec4564c6ee3bd34c3cef899537c3787ba.tar.gz
scala-04cb634ec4564c6ee3bd34c3cef899537c3787ba.tar.bz2
scala-04cb634ec4564c6ee3bd34c3cef899537c3787ba.zip
Merge pull request #3792 from som-snytt/issue/8525
SI-8525 -Xlint:nowarn-missing-interpolator
Diffstat (limited to 'src/compiler/scala/tools/nsc/settings')
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala78
-rw-r--r--src/compiler/scala/tools/nsc/settings/Warnings.scala121
3 files changed, 160 insertions, 41 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
index 38a7525862..ef9695a594 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
@@ -29,7 +29,7 @@ trait AbsScalaSettings {
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]): IntSetting
def MultiStringSetting(name: String, helpArg: String, descr: String): MultiStringSetting
- def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String]): MultiChoiceSetting
+ def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: () => Unit): MultiChoiceSetting
def OutputSetting(outputDirs: OutputDirs, default: String): OutputSetting
def PathSetting(name: String, descr: String, default: String): PathSetting
def PhasesSetting(name: String, descr: String, default: String): PhasesSetting
diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
index 54e444decf..dc49e8b822 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -211,11 +211,8 @@ class MutableSettings(val errorFn: String => Unit)
add(new ChoiceSetting(name, helpArg, descr, choices, default))
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]) = add(new IntSetting(name, descr, default, range, parser))
def MultiStringSetting(name: String, arg: String, descr: String) = add(new MultiStringSetting(name, arg, descr))
- def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String]): MultiChoiceSetting = {
- val fullChoix = choices.mkString(": ", ",", ".")
- val fullDescr = s"$descr$fullChoix"
- add(new MultiChoiceSetting(name, helpArg, fullDescr, choices))
- }
+ def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: () => Unit = () => ()) =
+ add(new MultiChoiceSetting(name, helpArg, descr, choices, default))
def OutputSetting(outputDirs: OutputDirs, default: String) = add(new OutputSetting(outputDirs, default))
def PhasesSetting(name: String, descr: String, default: String = "") = add(new PhasesSetting(name, descr, default))
def StringSetting(name: String, arg: String, descr: String, default: String) = add(new StringSetting(name, arg, descr, default))
@@ -444,7 +441,7 @@ class MutableSettings(val errorFn: String => Unit)
value = s.equalsIgnoreCase("true")
}
override def tryToSetColon(args: List[String]) = args match {
- case Nil => tryToSet(Nil)
+ case Nil => tryToSet(Nil)
case List(x) =>
if (x.equalsIgnoreCase("true")) {
value = true
@@ -452,7 +449,8 @@ class MutableSettings(val errorFn: String => Unit)
} else if (x.equalsIgnoreCase("false")) {
value = false
Some(Nil)
- } else errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None)
+ } else errorAndValue(s"'$x' is not a valid choice for '$name'", None)
+ case _ => errorAndValue(s"'$name' accepts only one boolean value", None)
}
}
@@ -553,12 +551,43 @@ class MutableSettings(val errorFn: String => Unit)
}
}
+ /** A setting that receives any combination of enumerated values,
+ * including "_" to mean all values.
+ * In non-colonated mode, stops consuming args at the first
+ * non-value, instead of at the next option, as for a multi-string.
+ */
class MultiChoiceSetting private[nsc](
name: String,
arg: String,
descr: String,
- override val choices: List[String])
- extends MultiStringSetting(name, arg, descr)
+ override val choices: List[String],
+ val default: () => Unit
+ ) extends MultiStringSetting(name, arg, s"$descr${ choices.mkString(": ", ",", ".") }") {
+
+ def badChoice(s: String, n: String) = errorFn(s"'$s' is not a valid choice for '$name'")
+ def choosing = choices.nonEmpty
+ def isChoice(s: String) = (s == "_") || (choices contains (s stripPrefix "-"))
+ def wildcards = choices // filter (!_.isSetByUser)
+
+ override protected def tts(args: List[String], halting: Boolean) = {
+ val total = collection.mutable.ListBuffer.empty[String] ++ value
+ def tryArg(arg: String) = arg match {
+ case "_" if choosing => wildcards foreach (total += _)
+ case s if !choosing || isChoice(s) => total += s
+ case s => badChoice(s, name)
+ }
+ def stoppingAt(arg: String) = (arg startsWith "-") || (choosing && !isChoice(arg))
+ def loop(args: List[String]): List[String] = args match {
+ case arg :: _ if halting && stoppingAt(arg) => args
+ case arg :: rest => tryArg(arg) ; loop(rest)
+ case Nil => Nil
+ }
+ val rest = loop(args)
+ if (rest.size == args.size) default() // if no arg consumed, trigger default action
+ else value = total.toList // update once
+ Some(rest)
+ }
+ }
/** A setting that accumulates all strings supplied to it,
* until it encounters one starting with a '-'.
@@ -570,24 +599,23 @@ class MutableSettings(val errorFn: String => Unit)
extends Setting(name, descr) with Clearable {
type T = List[String]
protected var v: T = Nil
- def appendToValue(str: String) { value ++= List(str) }
- def badChoice(s: String, n: String) = errorFn(s"'$s' is not a valid choice for '$name'")
+ def appendToValue(str: String) = value ++= List(str)
- def tryToSet(args: List[String]) = {
- val (strings, rest) = args span (x => !x.startsWith("-"))
- strings foreach {
- case "_" if choices.nonEmpty => choices foreach appendToValue
- case s if choices.isEmpty || (choices contains s) => appendToValue(s)
- case s => badChoice(s, name)
+ // try to set. halting means halt at first non-arg
+ protected def tts(args: List[String], halting: Boolean) = {
+ def loop(args: List[String]): List[String] = args match {
+ case arg :: rest => if (halting && (arg startsWith "-")) args else { appendToValue(arg) ; loop(rest) }
+ case Nil => Nil
}
- Some(rest)
+ Some(loop(args))
}
- override def tryToSetColon(args: List[String]) = tryToSet(args)
+ def tryToSet(args: List[String]) = tts(args, halting = true)
+ override def tryToSetColon(args: List[String]) = tts(args, halting = false)
override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide
- def clear(): Unit = (v = Nil)
- def unparse: List[String] = value map (name + ":" + _)
- def contains(s: String) = value contains s
+ def clear(): Unit = (v = Nil)
+ def unparse: List[String] = value map (name + ":" + _)
+ def contains(s: String) = value contains s
withHelpSyntax(name + ":<" + arg + ">")
}
@@ -606,10 +634,8 @@ class MutableSettings(val errorFn: String => Unit)
protected var v: T = default
def indexOfChoice: Int = choices indexOf value
- private def usageErrorMessage = {
- "Usage: %s:<%s>\n where <%s> choices are %s (default: %s)\n".format(
- name, helpArg, helpArg, choices mkString ", ", default)
- }
+ private def usageErrorMessage = f"Usage: $name:<$helpArg>%n where <$helpArg> choices are ${choices mkString ", "} (default: $default)%n"
+
def tryToSet(args: List[String]) = errorAndValue(usageErrorMessage, None)
override def tryToSetColon(args: List[String]) = args match {
diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala
index 1509ad13b8..3ff2369f86 100644
--- a/src/compiler/scala/tools/nsc/settings/Warnings.scala
+++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala
@@ -31,27 +31,120 @@ trait Warnings {
warnNullaryOverride,
warnNullaryUnit,
warnAdaptedArgs,
- warnInferAny
+ warnInferAny,
// warnUnused SI-7712, SI-7707 warnUnused not quite ready for prime-time
// warnUnusedImport currently considered too noisy for general use
+ // warnValueOverrides
+ warnMissingInterpolator,
+ warnDocDetached,
+ warnPrivateShadow,
+ warnPolyImplicitOverload,
+ warnOptionImplicit,
+ warnDelayedInit,
+ warnByNameRightAssociative,
+ warnPackageObjectClasses,
+ warnUnsoundMatch
)
private lazy val warnSelectNullable = BooleanSetting("-Xcheck-null", "This option is obsolete and does nothing.")
// Individual warnings.
- val warnAdaptedArgs = BooleanSetting ("-Ywarn-adapted-args", "Warn if an argument list is modified to match the receiver.")
- val warnDeadCode = BooleanSetting ("-Ywarn-dead-code", "Warn when dead code is identified.")
- val warnValueDiscard = BooleanSetting ("-Ywarn-value-discard", "Warn when non-Unit expression results are unused.")
- val warnNumericWiden = BooleanSetting ("-Ywarn-numeric-widen", "Warn when numerics are widened.")
- val warnNullaryUnit = BooleanSetting ("-Ywarn-nullary-unit", "Warn when nullary methods return Unit.")
- val warnInaccessible = BooleanSetting ("-Ywarn-inaccessible", "Warn about inaccessible types in method signatures.")
- val warnNullaryOverride = BooleanSetting ("-Ywarn-nullary-override", "Warn when non-nullary overrides nullary, e.g. `def foo()` over `def foo`.")
- val warnInferAny = BooleanSetting ("-Ywarn-infer-any", "Warn when a type argument is inferred to be `Any`.")
- val warnUnused = BooleanSetting ("-Ywarn-unused", "Warn when local and private vals, vars, defs, and types are are unused")
- val warnUnusedImport = BooleanSetting ("-Ywarn-unused-import", "Warn when imports are unused")
-
- // Warning groups.
- val lint = BooleanSetting("-Xlint", "Enable recommended additional warnings.") enablingIfNotSetByUser lintWarnings
+ val warnDeadCode = BooleanSetting("-Ywarn-dead-code",
+ "Warn when dead code is identified.")
+ val warnValueDiscard = BooleanSetting("-Ywarn-value-discard",
+ "Warn when non-Unit expression results are unused.")
+ val warnNumericWiden = BooleanSetting("-Ywarn-numeric-widen",
+ "Warn when numerics are widened.")
+ val warnUnused = BooleanSetting("-Ywarn-unused",
+ "Warn when local and private vals, vars, defs, and types are are unused")
+ val warnUnusedImport = BooleanSetting("-Ywarn-unused-import",
+ "Warn when imports are unused")
+
+ // Lint warnings that are not -Y, created with new instead of autoregistering factory method
+ private def lintflag(name: String, text: String) = new BooleanSetting(name, text)
+
+ val warnAdaptedArgs = lintflag("adapted-args",
+ "Warn if an argument list is modified to match the receiver.")
+ val warnNullaryUnit = lintflag("nullary-unit",
+ "Warn when nullary methods return Unit.")
+ val warnInaccessible = lintflag("inaccessible",
+ "Warn about inaccessible types in method signatures.")
+ val warnNullaryOverride = lintflag("nullary-override",
+ "Warn when non-nullary `def f()' overrides nullary `def f'.")
+ val warnInferAny = lintflag("infer-any",
+ "Warn when a type argument is inferred to be `Any`.")
+ val warnMissingInterpolator = lintflag("missing-interpolator",
+ "A string literal appears to be missing an interpolator id.")
+ val warnDocDetached = lintflag("doc-detached",
+ "A ScalaDoc comment appears to be detached from its element.")
+ val warnPrivateShadow = lintflag("private-shadow",
+ "A private field (or class parameter) shadows a superclass field.")
+ val warnPolyImplicitOverload = lintflag("poly-implicit-overload",
+ "Parameterized overloaded implicit methods are not visible as view bounds")
+ val warnOptionImplicit = lintflag("option-implicit",
+ "Option.apply used implicit view.")
+ val warnDelayedInit = lintflag("delayedinit-select",
+ "Selecting member of DelayedInit")
+ val warnByNameRightAssociative = lintflag("by-name-right-associative",
+ "By-name parameter of right associative operator")
+ val warnPackageObjectClasses = lintflag("package-object-classes",
+ "Class or object defined in package object")
+ val warnUnsoundMatch = lintflag("unsound-match",
+ "Pattern match may not be typesafe")
+
+ // Lint warnings that are not enabled yet
+ val warnValueOverrides = lintflag("value-overrides", "Generated value class method overrides an implementation")
+
+ // Warning groups.
+ val lint = {
+ // Boolean setting for testing if lint is on; not "added" to option processing
+ val xlint = lintflag("-Xlint", "Enable recommended additional warnings.")
+ val yprefix = "-Ywarn-"
+ def lintables = (lintWarnings map (_.name stripPrefix yprefix)).sorted
+ def isAnon(b: BooleanSetting) = !(b.name startsWith "-")
+ def setPolitely(b: BooleanSetting, v: Boolean) = if (!b.isSetByUser) b.value = v
+ def set(w: String, v: Boolean) = lintWarnings find (s => (s.name stripPrefix yprefix) == w) foreach (b => setPolitely(b, v))
+ val Neg = "-"
+ def propagate(ss: List[String]): Unit = ss match {
+ case w :: rest => if (w startsWith Neg) set(w stripPrefix Neg, false) else set(w, true) ; propagate(rest)
+ case Nil => ()
+ }
+ // enable lint and the group, honoring previous -Y settings
+ def enableAll(): Unit = {
+ xlint.value = true
+ for (s <- lintWarnings) setPolitely(s, true)
+ }
+ // The command option
+ MultiChoiceSetting("-Xlint", "warning", "Enable recommended additional warnings", choices = lintables, default = enableAll) withPostSetHook { x =>
+ propagate(x.value) // enabling the selections (on each append to value)
+ xlint.value = true // only enables lint, not the group
+ for (b <- lintWarnings if isAnon(b) && !b.isSetByUser) b.value = true // init anonymous settings (but not if disabled)
+ }
+ xlint
+ }
+
+ // Lint warnings that are currently -Y, but deprecated in that usage
+ // Alas, the -Yarg must have a doppelgaenger that is not deprecated
+ @deprecated("Use the Xlint flag", since="2.11.2")
+ val YwarnAdaptedArgs = BooleanSetting("-Ywarn-adapted-args",
+ "Warn if an argument list is modified to match the receiver.") withDeprecationMessage
+ "Enable -Xlint:adapted-args" enabling List(warnAdaptedArgs)
+ @deprecated("Use the Xlint flag", since="2.11.2")
+ val YwarnNullaryUnit = BooleanSetting("-Ywarn-nullary-unit",
+ "Warn when nullary methods return Unit.") withDeprecationMessage
+ "Enable -Xlint:nullary-unit" enabling List(warnNullaryUnit)
+ @deprecated("Use the Xlint flag", since="2.11.2")
+ val YwarnInaccessible = BooleanSetting("-Ywarn-inaccessible",
+ "Warn about inaccessible types in method signatures.") withDeprecationMessage
+ "Enable -Xlint:inaccessible" enabling List(warnInaccessible)
+ @deprecated("Use the Xlint flag", since="2.11.2")
+ val YwarnNullaryOverride = BooleanSetting("-Ywarn-nullary-override",
+ "Warn when non-nullary `def f()' overrides nullary `def f'.") withDeprecationMessage
+ "Enable -Xlint:nullary-override" enabling List(warnNullaryOverride)
+ @deprecated("Use the Xlint flag", since="2.11.2")
+ val YwarnInferAny = BooleanSetting("-Ywarn-infer-any",
+ "Warn when a type argument is inferred to be `Any`.") withDeprecationMessage
+ "Enable -Xlint:infer-any" enabling List(warnInferAny)
// Backward compatibility.
@deprecated("Use fatalWarnings", "2.11.0") def Xwarnfatal = fatalWarnings // used by sbt