diff options
Diffstat (limited to 'src/compiler/scala/tools/nsc/settings')
5 files changed, 62 insertions, 47 deletions
diff --git a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala index 6b339b2a6d..8386722b63 100644 --- a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala @@ -31,6 +31,7 @@ trait AbsScalaSettings { def BooleanSetting(name: String, descr: String): BooleanSetting def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String): ChoiceSetting + def ChoiceSettingForcedDefault(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[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]]): MultiChoiceSetting[E] diff --git a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala index b4987e1240..9cc8faf8c2 100644 --- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala @@ -221,6 +221,13 @@ class MutableSettings(val errorFn: String => Unit) def BooleanSetting(name: String, descr: String) = add(new BooleanSetting(name, descr)) def ChoiceSetting(name: String, helpArg: String, descr: String, choices: List[String], default: String) = add(new ChoiceSetting(name, helpArg, descr, choices, default)) + def ChoiceSettingForcedDefault(name: String, helpArg: String, descr: String, choices: List[String], default: String) = + ChoiceSetting(name, helpArg, descr, choices, default).withPostSetHook(sett => + if (sett.value != default) { + sett.withDeprecationMessage(s"${name}:${sett.value} is deprecated, forcing use of $default") + sett.value = 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)) diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 1817cfa25a..70170d9e97 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -22,13 +22,9 @@ trait ScalaSettings extends AbsScalaSettings /** Set of settings */ protected[scala] lazy val allSettings = mutable.HashSet[Setting]() - /** Against my better judgment, giving in to martin here and allowing - * CLASSPATH to be used automatically. So for the user-specified part - * of the classpath: - * - * - If -classpath or -cp is given, it is that - * - Otherwise, if CLASSPATH is set, it is that - * - If neither of those, then "." is used. + /** The user class path, specified by `-classpath` or `-cp`, + * defaults to the value of CLASSPATH env var if it is set, as in Java, + * or else to `"."` for the current user directory. */ protected def defaultClasspath = sys.env.getOrElse("CLASSPATH", ".") @@ -134,8 +130,9 @@ trait ScalaSettings extends AbsScalaSettings val Xshowobj = StringSetting ("-Xshow-object", "object", "Show internal representation of object.", "") val showPhases = BooleanSetting ("-Xshow-phases", "Print a synopsis of compiler phases.") val sourceReader = StringSetting ("-Xsource-reader", "classname", "Specify a custom method for reading source files.", "") + val reporter = StringSetting ("-Xreporter", "classname", "Specify a custom reporter for compiler messages.", "scala.tools.nsc.reporters.ConsoleReporter") val strictInference = BooleanSetting ("-Xstrict-inference", "Don't infer known-unsound types") - val source = ScalaVersionSetting ("-Xsource", "version", "Treat compiler input as Scala source for the specified version, see SI-8126.", initial = ScalaVersion("2.11")) + val source = ScalaVersionSetting ("-Xsource", "version", "Treat compiler input as Scala source for the specified version, see SI-8126.", initial = ScalaVersion("2.12")) val XnoPatmatAnalysis = BooleanSetting ("-Xno-patmat-analysis", "Don't perform exhaustivity/unreachability analysis. Also, ignore @switch annotation.") val XfullLubs = BooleanSetting ("-Xfull-lubs", "Retains pre 2.10 behavior of less aggressive truncation of least upper bounds.") @@ -143,7 +140,7 @@ trait ScalaSettings extends AbsScalaSettings // XML parsing options object XxmlSettings extends MultiChoiceEnumeration { val coalescing = Choice("coalescing", "Convert PCData to Text and coalesce sibling nodes") - def isCoalescing = (Xxml contains coalescing) || (!isScala212 && !Xxml.isSetByUser) + def isCoalescing = Xxml contains coalescing } val Xxml = MultiChoiceSetting( name = "-Xxml", @@ -223,9 +220,8 @@ trait ScalaSettings extends AbsScalaSettings val YdisableUnreachablePrevention = BooleanSetting("-Ydisable-unreachable-prevention", "Disable the prevention of unreachable blocks in code generation.") val YnoLoadImplClass = BooleanSetting ("-Yno-load-impl-class", "Do not load $class.class files.") - val exposeEmptyPackage = BooleanSetting("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() - // the current standard is "inline" but we are moving towards "method" - val Ydelambdafy = ChoiceSetting ("-Ydelambdafy", "strategy", "Strategy used for translating lambdas into JVM code.", List("inline", "method"), "inline") + val exposeEmptyPackage = BooleanSetting ("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly() + val Ydelambdafy = ChoiceSetting ("-Ydelambdafy", "strategy", "Strategy used for translating lambdas into JVM code.", List("inline", "method"), "method") val YskipInlineInfoAttribute = BooleanSetting("-Yskip-inline-info-attribute", "Do not add the ScalaInlineInfo attribute to classfiles generated by -Ybackend:GenASM") @@ -275,19 +271,20 @@ trait ScalaSettings extends AbsScalaSettings def YoptInlinerEnabled = YoptInlineProject || YoptInlineGlobal def YoptBuildCallGraph = YoptInlinerEnabled || YoptClosureElimination - def YoptAddToBytecodeRepository = YoptInlinerEnabled || YoptClosureElimination + def YoptAddToBytecodeRepository = YoptBuildCallGraph || YoptInlinerEnabled || YoptClosureElimination val YoptInlineHeuristics = ChoiceSetting( name = "-Yopt-inline-heuristics", helpArg = "strategy", descr = "Set the heuristics for inlining decisions.", - choices = List("at-inline-annotated", "everything"), - default = "at-inline-annotated") + choices = List("at-inline-annotated", "everything", "default"), + default = "default") object YoptWarningsChoices extends MultiChoiceEnumeration { val none = Choice("none" , "No optimizer warnings.") val atInlineFailedSummary = Choice("at-inline-failed-summary" , "One-line summary if there were @inline method calls that could not be inlined.") val atInlineFailed = Choice("at-inline-failed" , "A detailed warning for each @inline method call that could not be inlined.") + val anyInlineFailed = Choice("any-inline-failed" , "A detailed warning for every callsite that was chosen for inlining by the heuristics, but could not be inlined.") val noInlineMixed = Choice("no-inline-mixed" , "In mixed compilation, warn at callsites methods defined in java sources (the inlining decision cannot be made without bytecode).") val noInlineMissingBytecode = Choice("no-inline-missing-bytecode" , "Warn if an inlining decision cannot be made because a the bytecode of a class or member cannot be found on the compilation classpath.") val noInlineMissingScalaInlineInfoAttr = Choice("no-inline-missing-attribute", "Warn if an inlining decision cannot be made because a Scala classfile does not have a ScalaInlineInfo attribute.") @@ -306,7 +303,8 @@ trait ScalaSettings extends AbsScalaSettings def YoptWarningEmitAtInlineFailed = !YoptWarnings.isSetByUser || YoptWarnings.contains(YoptWarningsChoices.atInlineFailedSummary) || - YoptWarnings.contains(YoptWarningsChoices.atInlineFailed) + YoptWarnings.contains(YoptWarningsChoices.atInlineFailed) || + YoptWarnings.contains(YoptWarningsChoices.anyInlineFailed) def YoptWarningNoInlineMixed = YoptWarnings.contains(YoptWarningsChoices.noInlineMixed) def YoptWarningNoInlineMissingBytecode = YoptWarnings.contains(YoptWarningsChoices.noInlineMissingBytecode) @@ -358,7 +356,7 @@ trait ScalaSettings extends AbsScalaSettings */ val Ybackend = ChoiceSetting ("-Ybackend", "choice of bytecode emitter", "Choice of bytecode emitter.", List("GenASM", "GenBCode"), - "GenASM") + "GenBCode") // Feature extensions val XmacroSettings = MultiStringSetting("-Xmacro-settings", "option", "Custom settings for macros.") @@ -389,6 +387,23 @@ trait ScalaSettings extends AbsScalaSettings val Normal = "normal" val Discard = "discard" } + + def conflictWarning: Option[String] = { + def oldOptimiseFlagsInGenBCode: Option[String] = { + val optFlags: List[Setting] = if (optimise.value) List(optimise) else optimiseSettings.filter(_.value) + if (isBCodeActive && optFlags.nonEmpty) { + val msg = s"""Compiler settings for the 2.11 optimizer (${optFlags.map(_.name).mkString(", ")}) are incompatible with -Ybackend:GenBCode (which is the default in 2.12). + |The optimizer settings are ignored. See -Yopt:help for enabling the new optimizer in 2.12.""".stripMargin + Some(msg) + } else + None + } + + List(oldOptimiseFlagsInGenBCode /*, moreToCome */).flatten match { + case Nil => None + case warnings => Some("Conflicting compiler settings were detected. Some settings will be ignored.\n" + warnings.mkString("\n")) + } + } } object ClassPathRepresentationType { diff --git a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala index 43bdad5882..0b051ef89d 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaVersion.scala @@ -68,45 +68,37 @@ case object AnyScalaVersion extends ScalaVersion { * Factory methods for producing ScalaVersions */ object ScalaVersion { - private val dot = "\\." - private val dash = "\\-" - private def not(s:String) = s"[^${s}]" - private val R = s"((${not(dot)}*)(${dot}(${not(dot)}*)(${dot}(${not(dash)}*)(${dash}(.*))?)?)?)".r - - def apply(versionString : String, errorHandler: String => Unit): ScalaVersion = { - def errorAndValue() = { - errorHandler( - s"There was a problem parsing ${versionString}. " + - "Versions should be in the form major[.minor[.revision]] " + - "where each part is a positive number, as in 2.10.1. " + - "The minor and revision parts are optional." - ) - AnyScalaVersion - } + private val dot = """\.""" + private val dash = "-" + private val vchar = """\d""" //"[^-+.]" + private val vpat = s"(?s)($vchar+)(?:$dot($vchar+)(?:$dot($vchar+)(?:$dash(.*))?)?)?".r + private val rcpat = """(?i)rc(\d*)""".r + private val mspat = """(?i)m(\d*)""".r + + def apply(versionString: String, errorHandler: String => Unit): ScalaVersion = { + def error() = errorHandler( + s"Bad version (${versionString}) not major[.minor[.revision[-suffix]]]" + ) def toInt(s: String) = s match { case null | "" => 0 - case _ => s.toInt + case _ => s.toInt } - def isInt(s: String) = util.Try(toInt(s)).isSuccess - def toBuild(s: String) = s match { case null | "FINAL" => Final - case s if (s.toUpperCase.startsWith("RC") && isInt(s.substring(2))) => RC(toInt(s.substring(2))) - case s if (s.toUpperCase.startsWith("M") && isInt(s.substring(1))) => Milestone(toInt(s.substring(1))) - case _ => Development(s) + case rcpat(i) => RC(toInt(i)) + case mspat(i) => Milestone(toInt(i)) + case _ /* | "" */ => Development(s) } - try versionString match { + versionString match { case "none" => NoScalaVersion - case "any" => AnyScalaVersion - case R(_, majorS, _, minorS, _, revS, _, buildS) => + case "" => NoScalaVersion + case "any" => AnyScalaVersion + case vpat(majorS, minorS, revS, buildS) => SpecificScalaVersion(toInt(majorS), toInt(minorS), toInt(revS), toBuild(buildS)) - case _ => - errorAndValue() - } catch { - case e: NumberFormatException => errorAndValue() + case _ => error() ; AnyScalaVersion } } diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala index d42c0dd730..f197a4930d 100644 --- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala @@ -38,8 +38,8 @@ trait StandardScalaSettings { val nowarn = BooleanSetting ("-nowarn", "Generate no warnings.") val optimise: BooleanSetting // depends on post hook which mutates other settings val print = BooleanSetting ("-print", "Print program with Scala-specific features removed.") - val target = ChoiceSetting ("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.", - List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8"), "jvm-1.6") + val target = ChoiceSettingForcedDefault ("-target", "target", "Target platform for object files. All JVM 1.5 - 1.7 targets are deprecated.", + List("jvm-1.5", "jvm-1.6", "jvm-1.7", "jvm-1.8"), "jvm-1.8") val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions.") val uniqid = BooleanSetting ("-uniqid", "Uniquely tag all identifiers in debugging output.") val usejavacp = BooleanSetting ("-usejavacp", "Utilize the java.class.path in classpath resolution.") |