Skip to content

Commit 7289a26

Browse files
committed
Merge pull request #3734 from retronym/topic/master-to-2.11.x-2
Merge master to 2.11.x
2 parents 7523ed3 + 068d2c0 commit 7289a26

File tree

8 files changed

+79
-6
lines changed

8 files changed

+79
-6
lines changed

src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ trait AbsScalaSettings {
1616
type ChoiceSetting <: Setting { type T = String }
1717
type IntSetting <: Setting { type T = Int }
1818
type MultiStringSetting <: Setting { type T = List[String] }
19+
type MultiChoiceSetting <: Setting { type T = List[String] }
1920
type PathSetting <: Setting { type T = String }
2021
type PhasesSetting <: Setting { type T = List[String] }
2122
type StringSetting <: Setting { type T = String }
@@ -28,6 +29,7 @@ trait AbsScalaSettings {
2829
def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting
2930
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]): IntSetting
3031
def MultiStringSetting(name: String, helpArg: String, descr: String): MultiStringSetting
32+
def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String]): MultiChoiceSetting
3133
def OutputSetting(outputDirs: OutputDirs, default: String): OutputSetting
3234
def PathSetting(name: String, descr: String, default: String): PathSetting
3335
def PhasesSetting(name: String, descr: String, default: String): PhasesSetting

src/compiler/scala/tools/nsc/settings/MutableSettings.scala

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,11 @@ class MutableSettings(val errorFn: String => Unit)
211211
add(new ChoiceSetting(name, helpArg, descr, choices, default))
212212
def IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]) = add(new IntSetting(name, descr, default, range, parser))
213213
def MultiStringSetting(name: String, arg: String, descr: String) = add(new MultiStringSetting(name, arg, descr))
214+
def MultiChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String]): MultiChoiceSetting = {
215+
val fullChoix = choices.mkString(": ", ",", ".")
216+
val fullDescr = s"$descr$fullChoix"
217+
add(new MultiChoiceSetting(name, helpArg, fullDescr, choices))
218+
}
214219
def OutputSetting(outputDirs: OutputDirs, default: String) = add(new OutputSetting(outputDirs, default))
215220
def PhasesSetting(name: String, descr: String, default: String = "") = add(new PhasesSetting(name, descr, default))
216221
def StringSetting(name: String, arg: String, descr: String, default: String) = add(new StringSetting(name, arg, descr, default))
@@ -548,8 +553,16 @@ class MutableSettings(val errorFn: String => Unit)
548553
}
549554
}
550555

556+
class MultiChoiceSetting private[nsc](
557+
name: String,
558+
arg: String,
559+
descr: String,
560+
override val choices: List[String])
561+
extends MultiStringSetting(name, arg, descr)
562+
551563
/** A setting that accumulates all strings supplied to it,
552-
* until it encounters one starting with a '-'. */
564+
* until it encounters one starting with a '-'.
565+
*/
553566
class MultiStringSetting private[nsc](
554567
name: String,
555568
val arg: String,
@@ -558,18 +571,24 @@ class MutableSettings(val errorFn: String => Unit)
558571
type T = List[String]
559572
protected var v: T = Nil
560573
def appendToValue(str: String) { value ++= List(str) }
574+
def badChoice(s: String, n: String) = errorFn(s"'$s' is not a valid choice for '$name'")
561575

562576
def tryToSet(args: List[String]) = {
563577
val (strings, rest) = args span (x => !x.startsWith("-"))
564-
strings foreach appendToValue
565-
578+
strings foreach {
579+
case "_" if choices.nonEmpty => choices foreach appendToValue
580+
case s if choices.isEmpty || (choices contains s) => appendToValue(s)
581+
case s => badChoice(s, name)
582+
}
566583
Some(rest)
567584
}
568585
override def tryToSetColon(args: List[String]) = tryToSet(args)
569586
override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide
570587
def clear(): Unit = (v = Nil)
571588
def unparse: List[String] = value map (name + ":" + _)
572589

590+
def contains(s: String) = value contains s
591+
573592
withHelpSyntax(name + ":<" + arg + ">")
574593
}
575594

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,14 @@ trait ScalaSettings extends AbsScalaSettings
6262
/*val argfiles = */ BooleanSetting ("@<file>", "A text file containing compiler arguments (options and source files)")
6363
val classpath = PathSetting ("-classpath", "Specify where to find user class files.", defaultClasspath) withAbbreviation "-cp"
6464
val d = OutputSetting (outputDirs, ".")
65-
val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.")
66-
val language = MultiStringSetting("-language", "feature", "Enable one or more language features.")
65+
val nospecialization = BooleanSetting ("-no-specialization", "Ignore @specialize annotations.")
66+
67+
// Would be nice to build this dynamically from scala.languageFeature.
68+
// The two requirements: delay error checking until you have symbols, and let compiler command build option-specific help.
69+
val language = {
70+
val features = List("dynamics", "postfixOps", "reflectiveCalls", "implicitConversions", "higherKinds", "existentials", "experimental.macros")
71+
MultiChoiceSetting("-language", "feature", "Enable one or more language features", features)
72+
}
6773

6874
/*
6975
* The previous "-source" option is intended to be used mainly

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -741,7 +741,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
741741
val featureName = (nestedOwners map (_.name + ".")).mkString + featureTrait.name
742742
def action(): Boolean = {
743743
def hasImport = inferImplicit(EmptyTree: Tree, featureTrait.tpe, reportAmbiguous = true, isView = false, context).isSuccess
744-
def hasOption = settings.language.value exists (s => s == featureName || s == "_")
744+
def hasOption = settings.language contains featureName
745745
val OK = hasImport || hasOption
746746
if (!OK) {
747747
val Some(AnnotationInfo(_, List(Literal(Constant(featureDesc: String)), Literal(Constant(required: Boolean))), _)) =
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-nowarn
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
2+
import tools.partest.DirectTest
3+
4+
// verify that all languageFeature names are accepted by -language
5+
object Test extends DirectTest {
6+
override def code = "class Code { def f = (1 to 10) size }" // exercise a feature
7+
8+
override def extraSettings = s"-usejavacp -d ${testOutput.path}"
9+
10+
override def show() = {
11+
val global = newCompiler("-language:postfixOps", "-Ystop-after:typer")
12+
compileString(global)(code)
13+
import global._
14+
exitingTyper {
15+
//def isFeature(s: Symbol) = s.annotations.exists((a: AnnotationInfo) => a.tpe <:< typeOf[scala.annotation.meta.languageFeature])
16+
def isFeature(s: Symbol) = s hasAnnotation definitions.LanguageFeatureAnnot
17+
val langf = definitions.languageFeatureModule.typeSignature
18+
val feats = langf.declarations filter (s => isFeature(s)) map (_.name.decoded)
19+
val xmen = langf.member(TermName("experimental")).typeSignature.declarations filter (s => isFeature(s)) map (s => s"experimental.${s.name.decoded}")
20+
val all = (feats ++ xmen) mkString ","
21+
22+
assert(feats.nonEmpty, "Test must find feature flags.")
23+
24+
//dynamics,postfixOps,reflectiveCalls,implicitConversions,higherKinds,existentials,experimental.macros
25+
compile(s"-language:$all")
26+
}
27+
}
28+
}
29+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
'noob' is not a valid choice for '-language'
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
2+
import tools.partest.DirectTest
3+
4+
// verify that only languageFeature names are accepted by -language
5+
object Test extends DirectTest {
6+
override def code = "class Code"
7+
8+
override def extraSettings = s"-usejavacp -d ${testOutput.path}"
9+
10+
override def show() = {
11+
//compile("-language", "--") // no error
12+
compile(s"-language:noob")
13+
}
14+
}
15+

0 commit comments

Comments
 (0)