diff options
author | Som Snytt <som.snytt@gmail.com> | 2014-07-17 10:04:20 -0700 |
---|---|---|
committer | Som Snytt <som.snytt@gmail.com> | 2014-07-17 10:04:20 -0700 |
commit | bde623925d011841f222891050c5fdb08f3bb251 (patch) | |
tree | d69aa258a538d59d6fddbbd6e87a9b00db8d3121 | |
parent | f81ec8d1f6481ddacfb27e743c6c58961e765f0e (diff) | |
download | scala-bde623925d011841f222891050c5fdb08f3bb251.tar.gz scala-bde623925d011841f222891050c5fdb08f3bb251.tar.bz2 scala-bde623925d011841f222891050c5fdb08f3bb251.zip |
SI-8525 Multichoice help
Enables -Xlint:help and -language:help.
The Settings API makes it difficult to innovate.
4 files changed, 38 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala index a1d0d52dcf..95f7a70980 100644 --- a/src/compiler/scala/tools/nsc/CompilerCommand.scala +++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala @@ -103,7 +103,15 @@ class CompilerCommand(arguments: List[String], val settings: Settings) { val components = global.phaseNames // global.phaseDescriptors // one initializes s"Phase graph of ${components.size} components output to ${genPhaseGraph.value}*.dot." } - else "" + // would be nicer if we could ask all the options for their helpful messages + else { + val sb = new StringBuilder + allSettings foreach { + case s: MultiChoiceSetting if s.isHelping => sb append s.help append "\n" + case _ => + } + sb.toString + } } /** diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index 0dd4ae0b3b..8c69b49b98 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -201,7 +201,7 @@ class MutableSettings(val errorFn: String => Unit) } // a wrapper for all Setting creators to keep our list up to date - private def add[T <: Setting](s: T): T = { + private[nsc] def add[T <: Setting](s: T): T = { allSettings += s s } @@ -552,7 +552,7 @@ class MutableSettings(val errorFn: String => Unit) } /** A setting that receives any combination of enumerated values, - * including "_" to mean all values. + * including "_" to mean all values and "help" for verbose info. * In non-colonated mode, stops consuming args at the first * non-value, instead of at the next option, as for a multi-string. */ @@ -562,16 +562,18 @@ class MutableSettings(val errorFn: String => Unit) descr: String, override val choices: List[String], val default: () => Unit - ) extends MultiStringSetting(name, arg, s"$descr${ choices.mkString(": ", ",", ".") }") { + ) extends MultiStringSetting(name, s"_,$arg,-$arg", s"$descr: `_' for all, `$name:help' to list") { - 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 "-")) + private def badChoice(s: String, n: String) = errorFn(s"'$s' is not a valid choice for '$name'") + private def choosing = choices.nonEmpty + private def isChoice(s: String) = (s == "_") || (choices contains (s stripPrefix "-")) + private var sawHelp = false override protected def tts(args: List[String], halting: Boolean) = { val added = collection.mutable.ListBuffer.empty[String] def tryArg(arg: String) = arg match { case "_" if choosing => default() + case "help" if choosing => sawHelp = true case s if !choosing || isChoice(s) => added += s case s => badChoice(s, name) } @@ -586,6 +588,9 @@ class MutableSettings(val errorFn: String => Unit) else value = added.toList // update all new settings at once Some(rest) } + + def isHelping: Boolean = sawHelp + def help: String = s"$descr${ choices.mkString(":\n", " \n", "\n") }" } /** A setting that accumulates all strings supplied to it, diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index d22dcacad6..6675ad96e6 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -44,8 +44,11 @@ trait ScalaSettings extends AbsScalaSettings /** If any of these settings is enabled, the compiler should print a message and exit. */ def infoSettings = List[Setting](version, help, Xhelp, Yhelp, showPlugins, showPhases, genPhaseGraph) + /** Any -multichoice:help? Nicer if any option could report that it had help to offer. */ + private def multihelp = allSettings exists { case s: MultiChoiceSetting => s.isHelping case _ => false } + /** Is an info setting set? */ - def isInfo = infoSettings exists (_.isSetByUser) + def isInfo = (infoSettings exists (_.isSetByUser)) || multihelp /** Disable a setting */ def disable(s: Setting) = allSettings -= s @@ -68,7 +71,7 @@ trait ScalaSettings extends AbsScalaSettings // The two requirements: delay error checking until you have symbols, and let compiler command build option-specific help. val language = { val features = List("dynamics", "postfixOps", "reflectiveCalls", "implicitConversions", "higherKinds", "existentials", "experimental.macros") - MultiChoiceSetting("-language", "feature", "Enable one or more language features", features) + MultiChoiceSetting("-language", "feature", "Enable or disable language features", features) } /* diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala index 0b9ad80041..3accd9fdaa 100644 --- a/src/compiler/scala/tools/nsc/settings/Warnings.scala +++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala @@ -108,14 +108,19 @@ trait Warnings { // The Xlint warning group. private val xlint = new BooleanSetting("-Zunused", "True if -Xlint or -Xlint:_") // On -Xlint or -Xlint:_, set xlint, otherwise set the lint warning unless already set true - val lint = - MultiChoiceSetting( + val lint = { + val d = "Enable or disable specific warnings" + val s = new MultiChoiceSetting( name = "-Xlint", - helpArg = "warning", - descr = "Enable recommended additional warnings", + arg = "warning", + descr = d, choices = (lintWarnings map (_.name)).sorted, default = () => xlint.value = true - ) withPostSetHook { x => + ) { + def helpline(n: String) = lintWarnings.find(_.name == n).map(w => f" ${w.name}%-25s ${w.helpDescription}%n") + override def help = s"$d${ choices flatMap (helpline(_)) mkString (":\n", "", "\n") }" + } + val t = s withPostSetHook { x => val Neg = "-" def setPolitely(b: BooleanSetting, v: Boolean) = if (!b.isSetByUser || !b) b.value = v def set(w: String, v: Boolean) = lintWarnings find (_.name == w) foreach (setPolitely(_, v)) @@ -125,6 +130,9 @@ trait Warnings { } propagate(x.value) } + add(t) + t + } // Lint warnings that are currently -Y, but deprecated in that usage @deprecated("Use warnAdaptedArgs", since="2.11.2") |