Skip to content

Commit 7c9aae3

Browse files
authored
Enhance help message for language flag (#20247)
Fix #20083: Enhance help message for language features by displaying all available choises and notes
2 parents 4dffcc9 + 6a07b0a commit 7c9aae3

17 files changed

+55
-16
lines changed

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ trait CliCommand:
5353
end distill
5454

5555
/** Creates a help message for a subset of options based on cond */
56-
protected def availableOptionsMsg(p: Setting[?] => Boolean)(using settings: ConcreteSettings)(using SettingsState): String =
56+
protected def availableOptionsMsg(p: Setting[?] => Boolean, showArgFileMsg: Boolean = true)(using settings: ConcreteSettings)(using SettingsState): String =
5757
// result is (Option Name, descrption\ndefault: value\nchoices: x, y, z
5858
def help(s: Setting[?]): (String, String) =
5959
// For now, skip the default values that do not make sense for the end user, such as 'false' for the version command.
@@ -68,7 +68,10 @@ trait CliCommand:
6868
val ss = settings.allSettings.filter(p).toList.sortBy(_.name)
6969
val formatter = Columnator("", "", maxField = 30)
7070
val fresh = ContextBase().initialCtx.fresh.setSettings(summon[SettingsState])
71-
formatter(List(ss.map(help) :+ ("@<file>", "A text file containing compiler arguments (options and source files).")))(using fresh)
71+
var msg = ss.map(help)
72+
if showArgFileMsg then
73+
msg = msg :+ ("@<file>", "A text file containing compiler arguments (options and source files).")
74+
formatter(List(msg))(using fresh)
7275
end availableOptionsMsg
7376

7477
protected def shortUsage: String = s"Usage: $cmdName <options> <source files>"

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ abstract class CompilerCommand extends CliCommand:
99

1010
final def helpMsg(using settings: ConcreteSettings)(using SettingsState, Context): String =
1111
settings.allSettings.find(isHelping) match
12-
case Some(s) => s.description
12+
case Some(s) => availableOptionsMsg(_ == s, showArgFileMsg = false)
1313
case _ =>
1414
if (settings.help.value) usageMessage
1515
else if (settings.Vhelp.value) vusageMessage

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

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import SourceVersion.*
1111
import reporting.Message
1212
import NameKinds.QualifiedName
1313
import Annotations.ExperimentalAnnotation
14+
import Settings.Setting.ChoiceWithHelp
1415

1516
object Feature:
1617

@@ -42,6 +43,35 @@ object Feature:
4243
.map(sym => experimental(sym.name))
4344
.filterNot(_ == captureChecking) // TODO is this correct?
4445

46+
val values = List(
47+
(nme.help, "Display all available features"),
48+
(nme.noAutoTupling, "Disable automatic tupling"),
49+
(nme.dynamics, "Allow direct or indirect subclasses of scala.Dynamic"),
50+
(nme.unsafeNulls, "Enable unsafe nulls for explicit nulls"),
51+
(nme.postfixOps, "Allow postfix operators (not recommended)"),
52+
(nme.strictEquality, "Enable strict equality (disable canEqualAny)"),
53+
(nme.implicitConversions, "Allow implicit conversions without warnings"),
54+
(nme.adhocExtensions, "Allow ad-hoc extension methods"),
55+
(namedTypeArguments, "Allow named type arguments"),
56+
(genericNumberLiterals, "Allow generic number literals"),
57+
(scala2macros, "Allow Scala 2 macros"),
58+
(dependent, "Allow dependent method types"),
59+
(erasedDefinitions, "Allow erased definitions"),
60+
(symbolLiterals, "Allow symbol literals"),
61+
(fewerBraces, "Enable support for using indentation for arguments"),
62+
(saferExceptions, "Enable safer exceptions"),
63+
(clauseInterleaving, "Enable clause interleaving"),
64+
(pureFunctions, "Enable pure functions for capture checking"),
65+
(captureChecking, "Enable experimental capture checking"),
66+
(into, "Allow into modifier on parameter types"),
67+
(namedTuples, "Allow named tuples"),
68+
(modularity, "Enable experimental modularity features"),
69+
(betterMatchTypeExtractors, "Enable better match type extractors")
70+
)
71+
72+
private def enabledLanguageFeaturesBySetting(using Context): List[String] =
73+
ctx.settings.language.value.asInstanceOf
74+
4575
/** Is `feature` enabled by by a command-line setting? The enabling setting is
4676
*
4777
* -language:<prefix>feature
@@ -50,7 +80,7 @@ object Feature:
5080
* but subtracting the prefix `scala.language.` at the front.
5181
*/
5282
def enabledBySetting(feature: TermName)(using Context): Boolean =
53-
ctx.base.settings.language.value.contains(feature.toString)
83+
enabledLanguageFeaturesBySetting.contains(feature.toString)
5484

5585
/** Is `feature` enabled by by an import? This is the case if the feature
5686
* is imported by a named import

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ trait CommonScalaSettings:
114114
val explainTypes: Setting[Boolean] = BooleanSetting(RootSetting, "explain-types", "Explain type errors in more detail (deprecated, use -explain instead).", aliases = List("--explain-types", "-explaintypes"))
115115
val explainCyclic: Setting[Boolean] = BooleanSetting(RootSetting, "explain-cyclic", "Explain cyclic reference errors in more detail.", aliases = List("--explain-cyclic"))
116116
val unchecked: Setting[Boolean] = BooleanSetting(RootSetting, "unchecked", "Enable additional warnings where generated code depends on assumptions.", initialValue = true, aliases = List("--unchecked"))
117-
val language: Setting[List[String]] = MultiStringSetting(RootSetting, "language", "feature", "Enable one or more language features.", aliases = List("--language"))
117+
val language: Setting[List[ChoiceWithHelp[String]]] = MultiChoiceHelpSetting(RootSetting, "language", "feature", "Enable one or more language features.", choices = ScalaSettingsProperties.supportedLanguageFeatures, default = Nil, aliases = List("--language"))
118118
val experimental: Setting[Boolean] = BooleanSetting(RootSetting, "experimental", "Annotate all top-level definitions with @experimental. This enables the use of experimental features anywhere in the project.")
119119

120120
/* Coverage settings */
@@ -492,3 +492,4 @@ private sealed trait YSettings:
492492
@deprecated(message = "Scheduled for removal.", since = "3.5.0")
493493
val YoutputOnlyTasty: Setting[Boolean] = BooleanSetting(ForkSetting, "Youtput-only-tasty", "Used to only generate the TASTy file without the classfiles", deprecation = Deprecation.removed())
494494
end YSettings
495+

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package dotty.tools.dotc
22
package config
33

4+
import Settings.Setting.ChoiceWithHelp
45
import dotty.tools.backend.jvm.BackendUtils.classfileVersionMap
56
import dotty.tools.io.{AbstractFile, Directory, JDK9Reflectors, PlainDirectory, NoAbstractFile}
67
import scala.language.unsafeNulls
@@ -26,6 +27,9 @@ object ScalaSettingsProperties:
2627
def supportedSourceVersions: List[String] =
2728
SourceVersion.values.toList.map(_.toString)
2829

30+
def supportedLanguageFeatures: List[ChoiceWithHelp[String]] =
31+
Feature.values.map((n, d) => ChoiceWithHelp(n.toString, d))
32+
2933
def defaultClasspath: String = sys.env.getOrElse("CLASSPATH", ".")
3034

3135
def defaultPageWidth: Int = {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -380,7 +380,7 @@ object Settings:
380380
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): Setting[String] =
381381
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), aliases = aliases, legacyArgs = legacyArgs, deprecation = deprecation))
382382

383-
def MultiChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: List[String], aliases: List[String] = Nil, deprecation: Option[Deprecation] = None): Setting[List[String]] =
383+
def MultiChoiceSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[String], default: List[String] = Nil, aliases: List[String] = Nil, deprecation: Option[Deprecation] = None): Setting[List[String]] =
384384
publish(Setting(category, prependName(name), descr, default, helpArg, Some(choices), aliases = aliases, deprecation = deprecation))
385385

386386
def MultiChoiceHelpSetting(category: SettingCategory, name: String, helpArg: String, descr: String, choices: List[ChoiceWithHelp[String]], default: List[ChoiceWithHelp[String]], aliases: List[String] = Nil, deprecation: Option[Deprecation] = None): Setting[List[ChoiceWithHelp[String]]] =

compiler/src/dotty/tools/dotc/core/StdNames.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ object StdNames {
509509
val _hashCode_ : N = "_hashCode"
510510
val hash_ : N = "hash"
511511
val head: N = "head"
512+
val help: N = "help"
512513
val higherKinds: N = "higherKinds"
513514
val idx: N = "idx"
514515
val identity: N = "identity"

compiler/test/dotty/tools/DottyTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ trait DottyTest extends ContextEscapeDetection {
4040
protected def initializeCtx(fc: FreshContext): Unit = {
4141
fc.setSetting(fc.settings.encoding, "UTF8")
4242
fc.setSetting(fc.settings.classpath, TestConfiguration.basicClasspath)
43-
fc.setSetting(fc.settings.language, List("experimental.erasedDefinitions"))
43+
fc.setSetting(fc.settings.language, List("experimental.erasedDefinitions").asInstanceOf)
4444
fc.setProperty(ContextDoc, new ContextDocstrings)
4545
}
4646

compiler/test/dotty/tools/dotc/CompilationTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class CompilationTests {
143143
"tests/neg-custom-args/toplevel-samesource/S.scala",
144144
"tests/neg-custom-args/toplevel-samesource/nested/S.scala"),
145145
defaultOptions),
146-
compileFile("tests/neg/i7575.scala", defaultOptions.withoutLanguageFeatures.and("-language:_")),
146+
compileFile("tests/neg/i7575.scala", defaultOptions.withoutLanguageFeatures),
147147
).checkExpectedErrors()
148148
}
149149

0 commit comments

Comments
 (0)