summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/_layouts/default.yml2
-rw-r--r--src/compiler/scala/tools/nsc/CompilerCommand.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/MainBench.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Reporting.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ScriptRunner.scala34
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala24
-rw-r--r--src/compiler/scala/tools/nsc/settings/MutableSettings.scala221
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala44
-rw-r--r--src/compiler/scala/tools/nsc/settings/Warnings.scala195
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala20
-rw-r--r--src/compiler/scala/tools/nsc/util/StatisticsInfo.scala4
-rw-r--r--src/library/scala/collection/Iterator.scala40
-rw-r--r--src/library/scala/collection/SeqViewLike.scala23
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala2
-rwxr-xr-xsrc/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala58
-rw-r--r--test/files/jvm/varargs/VaClass.scala4
-rw-r--r--test/files/neg/compile-time-only-a.check5
-rw-r--r--test/files/pos/t8410.flags1
-rw-r--r--test/files/pos/t8410.scala15
-rw-r--r--test/files/pos/t8498.scala6
-rw-r--r--test/files/run/t8803.check16
-rw-r--r--test/files/run/t8803.scala57
-rw-r--r--test/junit/scala/tools/nsc/ScriptRunnerTest.scala23
-rw-r--r--test/junit/scala/tools/nsc/settings/SettingsTest.scala109
-rw-r--r--test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/symtab/FreshNameExtractorTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/symtab/StdNamesTest.scala8
-rw-r--r--test/junit/scala/tools/testing/AssertUtil.scala2
-rw-r--r--test/scaladoc/resources/code-indent.scala6
-rw-r--r--test/scaladoc/run/t8113.check1
-rw-r--r--test/scaladoc/run/t8113.scala36
-rw-r--r--test/scaladoc/scalacheck/HtmlFactoryTest.scala7
36 files changed, 691 insertions, 297 deletions
diff --git a/spec/_layouts/default.yml b/spec/_layouts/default.yml
index 7f17ba30b0..d3296c6f5d 100644
--- a/spec/_layouts/default.yml
+++ b/spec/_layouts/default.yml
@@ -11,7 +11,7 @@
}
});
</script>
- <script type="text/javascript" src="https://c328740.ssl.cf1.rackcdn.com/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+ <script type="text/javascript" src="http://cdn.mathjax.org/mathjax/2.3-latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<!-- need to use include to see value of page.chapter variable -->
diff --git a/src/compiler/scala/tools/nsc/CompilerCommand.scala b/src/compiler/scala/tools/nsc/CompilerCommand.scala
index 3ded456378..9b8e9fa330 100644
--- a/src/compiler/scala/tools/nsc/CompilerCommand.scala
+++ b/src/compiler/scala/tools/nsc/CompilerCommand.scala
@@ -107,7 +107,7 @@ class CompilerCommand(arguments: List[String], val settings: Settings) {
else {
val sb = new StringBuilder
allSettings foreach {
- case s: MultiChoiceSetting if s.isHelping => sb append s.help
+ case s: MultiChoiceSetting[_] if s.isHelping => sb append s.help
case _ =>
}
sb.toString
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 82ffb35c3f..452081cff1 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1372,7 +1372,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
runCheckers()
// output collected statistics
- if (settings.Ystatistics)
+ if (settings.YstatisticsEnabled)
statistics.print(phase)
advancePhase()
diff --git a/src/compiler/scala/tools/nsc/MainBench.scala b/src/compiler/scala/tools/nsc/MainBench.scala
index 03190a63f3..f01de0cbe1 100644
--- a/src/compiler/scala/tools/nsc/MainBench.scala
+++ b/src/compiler/scala/tools/nsc/MainBench.scala
@@ -24,7 +24,7 @@ object MainBench extends Driver with EvalLoop {
var start = System.nanoTime()
for (i <- 0 until NIter) {
if (i == NIter-1) {
- theCompiler.settings.Ystatistics.value = true
+ theCompiler.settings.Ystatistics.default.get foreach theCompiler.settings.Ystatistics.add
Statistics.enabled = true
}
process(args)
diff --git a/src/compiler/scala/tools/nsc/Reporting.scala b/src/compiler/scala/tools/nsc/Reporting.scala
index b164f395fe..c9782de7c8 100644
--- a/src/compiler/scala/tools/nsc/Reporting.scala
+++ b/src/compiler/scala/tools/nsc/Reporting.scala
@@ -33,7 +33,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
if (option) reporter.warning(pos, msg)
else if (!(warnings contains pos)) warnings += ((pos, msg))
def summarize() =
- if (warnings.nonEmpty && (option.isDefault || settings.fatalWarnings)) {
+ if (warnings.nonEmpty && (option.isDefault || option)) {
val numWarnings = warnings.size
val warningVerb = if (numWarnings == 1) "was" else "were"
val warningCount = countElementsAsString(numWarnings, s"$what warning")
@@ -105,4 +105,4 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
reporter.error(NoPosition, "No warnings can be incurred under -Xfatal-warnings.")
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/ScriptRunner.scala b/src/compiler/scala/tools/nsc/ScriptRunner.scala
index c2d62db558..7d5c6f6fff 100644
--- a/src/compiler/scala/tools/nsc/ScriptRunner.scala
+++ b/src/compiler/scala/tools/nsc/ScriptRunner.scala
@@ -6,7 +6,7 @@
package scala
package tools.nsc
-import io.{ Directory, File, Path }
+import io.{ AbstractFile, Directory, File, Path }
import java.io.IOException
import scala.tools.nsc.reporters.{Reporter,ConsoleReporter}
import util.Exceptional.unwrap
@@ -111,6 +111,12 @@ class ScriptRunner extends HasCompileSocket {
else None
}
+ def hasClassToRun(d: Directory): Boolean = {
+ import util.ClassPath.{ DefaultJavaContext => ctx }
+ val cp = ctx.newClassPath(AbstractFile.getDirectory(d))
+ cp.findClass(mainClass).isDefined
+ }
+
/* The script runner calls sys.exit to communicate a return value, but this must
* not take place until there are no non-daemon threads running. Tickets #1955, #2006.
*/
@@ -124,15 +130,21 @@ class ScriptRunner extends HasCompileSocket {
compile match {
case Some(compiledPath) =>
- try io.Jar.create(jarFile, compiledPath, mainClass)
- catch { case _: Exception => jarFile.delete() }
-
- if (jarOK) {
- compiledPath.deleteRecursively()
- handler(jarFile.toAbsolute.path)
+ if (!hasClassToRun(compiledPath)) {
+ // it compiled ok, but there is nothing to run;
+ // running an empty script should succeed
+ true
+ } else {
+ try io.Jar.create(jarFile, compiledPath, mainClass)
+ catch { case _: Exception => jarFile.delete() }
+
+ if (jarOK) {
+ compiledPath.deleteRecursively()
+ handler(jarFile.toAbsolute.path)
+ }
+ // jar failed; run directly from the class files
+ else handler(compiledPath.path)
}
- // jar failed; run directly from the class files
- else handler(compiledPath.path)
case _ => false
}
}
@@ -140,8 +152,8 @@ class ScriptRunner extends HasCompileSocket {
if (jarOK) handler(jarFile.toAbsolute.path) // pre-compiled jar is current
else recompile() // jar old - recompile the script.
}
- // don't use a cache jar at all--just use the class files
- else compile exists (cp => handler(cp.path))
+ // don't use a cache jar at all--just use the class files, if they exist
+ else compile exists (cp => !hasClassToRun(cp) || handler(cp.path))
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index 8df3969c49..351eb23c4c 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -283,7 +283,7 @@ abstract class Inliners extends SubComponent {
}
val tfa = new analysis.MTFAGrowable()
- tfa.stat = global.settings.Ystatistics.value
+ tfa.stat = global.settings.YstatisticsEnabled
val staleOut = new mutable.ListBuffer[BasicBlock]
val splicedBlocks = mutable.Set.empty[BasicBlock]
val staleIn = mutable.Set.empty[BasicBlock]
diff --git a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
index d0b8fd70ed..6b339b2a6d 100644
--- a/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/AbsScalaSettings.scala
@@ -7,20 +7,24 @@ package scala
package tools.nsc
package settings
+import scala.language.higherKinds
+
trait AbsScalaSettings {
self: AbsSettings =>
+ type MultiChoiceEnumeration <: Enumeration
+
type Setting <: AbsSetting
- type BooleanSetting <: Setting { type T = Boolean }
- type ChoiceSetting <: Setting { type T = String }
- type IntSetting <: Setting { type T = Int }
- type MultiStringSetting <: Setting { type T = List[String] }
- type MultiChoiceSetting <: Setting { type T = List[String] }
- type PathSetting <: Setting { type T = String }
- type PhasesSetting <: Setting { type T = List[String] }
- type StringSetting <: Setting { type T = String }
- type PrefixSetting <: Setting { type T = List[String] }
+ type BooleanSetting <: Setting { type T = Boolean }
+ type ChoiceSetting <: Setting { type T = String }
+ type IntSetting <: Setting { type T = Int }
+ type MultiStringSetting <: Setting { type T = List[String] }
+ type MultiChoiceSetting[E <: MultiChoiceEnumeration] <: Setting { type T <: E#ValueSet }
+ type PathSetting <: Setting { type T = String }
+ type PhasesSetting <: Setting { type T = List[String] }
+ type StringSetting <: Setting { type T = String }
+ type PrefixSetting <: Setting { type T = List[String] }
type OutputDirs
type OutputSetting <: Setting
@@ -29,7 +33,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], default: Option[() => Unit])(helper: MultiChoiceSetting => String): MultiChoiceSetting
+ def MultiChoiceSetting[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]]): MultiChoiceSetting[E]
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 f26192f88a..bbe21477cb 100644
--- a/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/MutableSettings.scala
@@ -209,12 +209,11 @@ 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 IntSetting(name: String, descr: String, default: Int, range: Option[(Int, Int)], parser: String => Option[Int]) = add(new IntSetting(name, descr, default, range, parser))
+ 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], default: Option[() => Unit] = None)(
- helper: MultiChoiceSetting => String = _ => choices.mkString(f"$descr:%n", f"%n ", f"%n")
- ) =
- add(new MultiChoiceSetting(name, helpArg, descr, choices, default, helper))
+ def MultiChoiceSetting[E <: MultiChoiceEnumeration](name: String, helpArg: String, descr: String, domain: E, default: Option[List[String]] = None) =
+ add(new MultiChoiceSetting[E](name, helpArg, descr, domain, 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))
@@ -367,7 +366,7 @@ class MutableSettings(val errorFn: String => Unit)
def withDeprecationMessage(msg: String): this.type = { _deprecationMessage = Some(msg) ; this }
}
- /** A setting represented by an integer */
+ /** A setting represented by an integer. */
class IntSetting private[nsc](
name: String,
descr: String,
@@ -553,57 +552,193 @@ class MutableSettings(val errorFn: String => Unit)
}
}
- /** A setting that receives any combination of enumerated 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.
+ /**
+ * Each [[MultiChoiceSetting]] takes a MultiChoiceEnumeration as domain. The enumeration may
+ * use the Choice class to define values, or simply use the default `Value` constructor:
+ *
+ * object SettingDomain extends MultiChoiceEnumeration { val arg1, arg2 = Value }
+ *
+ * Or
+ *
+ * object SettingDomain extends MultiChoiceEnumeration {
+ * val arg1 = Choice("arg1", "help")
+ * val arg2 = Choice("arg2", "help")
+ * }
+ *
+ * Choices with a non-empty `expandsTo` enable other options. Note that expanding choices are
+ * not present in the multiChoiceSetting.value set, only their expansion.
+ */
+ abstract class MultiChoiceEnumeration extends Enumeration {
+ case class Choice(name: String, help: String = "", expandsTo: List[Choice] = Nil) extends Val(name)
+ }
+
+ /**
+ * A Setting that collects string-valued settings from an enumerated domain.
+ * - These choices can be turned on or off: "-option:on,-off"
+ * - If an option is set both on and off, then the option is on
+ * - The choice "_" enables all choices that have not been explicitly disabled
+ *
+ * Arguments can be provided in colonated or non-colonated mode, i.e. "-option a b" or
+ * "-option:a,b". Note that arguments starting with a "-" can only be provided in colonated mode,
+ * otherwise they are interpreted as a new option.
+ *
+ * In non-colonated mode, the setting stops consuming arguments at the first non-choice,
+ * i.e. "-option a b c" only consumes "a" and "b" if "c" is not a valid choice.
+ *
+ * @param name command-line setting name, eg "-Xlint"
+ * @param helpArg help description for the kind of arguments it takes, eg "warning"
+ * @param descr description of the setting
+ * @param domain enumeration of choices implementing MultiChoice, or the string value is
+ * taken for the name
+ * @param default If Some(args), the default options if none are provided. If None, an
+ * error is printed if there are no arguments.
*/
- class MultiChoiceSetting private[nsc](
+ class MultiChoiceSetting[E <: MultiChoiceEnumeration] private[nsc](
name: String,
- arg: String,
+ helpArg: String,
descr: String,
- override val choices: List[String],
- val default: Option[() => Unit],
- helper: MultiChoiceSetting => String
- ) extends MultiStringSetting(name, s"_,$arg,-$arg", s"$descr: `_' for all, `$name:help' to list") {
+ val domain: E,
+ val default: Option[List[String]]
+ ) extends Setting(name, s"$descr: `_' for all, `$name:help' to list") with Clearable {
- 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 "-"))
+ withHelpSyntax(s"$name:<_,$helpArg,-$helpArg>")
- private var sawHelp = false
- private var sawAll = false
- private val adderAll = () => sawAll = true
- private val noargs = () => errorFn(s"'$name' requires an option. See '$name:help'.")
+ object ChoiceOrVal {
+ def unapply(a: domain.Value): Option[(String, String, List[domain.Choice])] = a match {
+ case c: domain.Choice => Some((c.name, c.help, c.expandsTo))
+ case v: domain.Value => Some((v.toString, "", Nil))
+ }
+ }
+
+ type T = domain.ValueSet
+ protected var v: T = domain.ValueSet.empty
+
+ // Explicitly enabled or disabled. Yeas may contain expanding options, nays may not.
+ private var yeas = domain.ValueSet.empty
+ private var nays = domain.ValueSet.empty
+
+ // Asked for help
+ private var sawHelp = false
+ // Wildcard _ encountered
+ private var sawAll = false
+
+ private def badChoice(s: String) = errorFn(s"'$s' is not a valid choice for '$name'")
+ private def isChoice(s: String) = (s == "_") || (choices contains pos(s))
+
+ private def pos(s: String) = s stripPrefix "-"
+ private def isPos(s: String) = !(s startsWith "-")
+
+ override val choices: List[String] = domain.values.toList map {
+ case ChoiceOrVal(name, _, _) => name
+ }
+
+ def descriptions: List[String] = domain.values.toList map {
+ case ChoiceOrVal(_, "", x :: xs) => "Enables the options "+ (x :: xs).map(_.name).mkString(", ")
+ case ChoiceOrVal(_, descr, _) => descr
+ case _ => ""
+ }
- override protected def tts(args: List[String], halting: Boolean) = {
+ /** (Re)compute from current yeas, nays, wildcard status. */
+ def compute() = {
+ def simple(v: domain.Value) = v match {
+ case ChoiceOrVal(_, _, Nil) => true
+ case _ => false
+ }
+
+ /**
+ * Expand an expanding option, if necessary recursively. Expanding options are not included in
+ * the result (consistent with "_", which is not in `value` either).
+ *
+ * Note: by precondition, options in nays are not expanding, they can only be leaves.
+ */
+ def expand(vs: domain.ValueSet): domain.ValueSet = vs flatMap {
+ case c @ ChoiceOrVal(_, _, Nil) => domain.ValueSet(c)
+ case ChoiceOrVal(_, _, others) => expand(domain.ValueSet(others: _*))
+ }
+
+ // yeas from _ or expansions are weak: an explicit nay will disable them
+ val weakYeas = if (sawAll) domain.values filter simple else expand(yeas filterNot simple)
+ value = (yeas filter simple) | (weakYeas &~ nays)
+ }
+
+ /** Add a named choice to the multichoice value. */
+ def add(arg: String) = arg match {
+ case _ if !isChoice(arg) =>
+ badChoice(arg)
+ case "_" =>
+ sawAll = true
+ compute()
+ case _ if isPos(arg) =>
+ yeas += domain withName arg
+ compute()
+ case _ =>
+ val choice = domain withName pos(arg)
+ choice match {
+ case ChoiceOrVal(_, _, _ :: _) => errorFn(s"'${pos(arg)}' cannot be negated, it enables other arguments")
+ case _ =>
+ }
+ nays += choice
+ compute()
+ }
+
+ def tryToSet(args: List[String]) = tryToSetArgs(args, halting = true)
+ override def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false)
+ override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide
+
+ /** Try to set args, handling "help" and default.
+ * The "halting" parameter means args were "-option a b c -else" so halt
+ * on "-else" or other non-choice. Otherwise, args were "-option:a,b,c,d",
+ * so process all and report non-choices as errors.
+ * @param args args to process
+ * @param halting stop on non-arg
+ */
+ private def tryToSetArgs(args: List[String], halting: Boolean) = {
val added = collection.mutable.ListBuffer.empty[String]
+
def tryArg(arg: String) = arg match {
- case "_" if choosing => addAll()
- case "help" if choosing => sawHelp = true
- case s if !choosing || isChoice(s) => added += s
- case s => badChoice(s, name)
+ case "help" => sawHelp = true
+ case s if isChoice(s) => added += s // this case also adds "_"
+ case s => badChoice(s)
}
- 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
+ case arg :: _ if halting && (!isPos(arg) || !isChoice(arg)) => args
+ case arg :: rest => tryArg(arg) ; loop(rest)
+ case Nil => Nil
}
val rest = loop(args)
- if (rest.size == args.size)
- (default getOrElse noargs)() // if no arg consumed, trigger default action or error
- else
- value ++= added.toList // update all new settings at once
+
+ // if no arg consumed, use defaults or error; otherwise, add what they added
+ if (rest.size == args.size) default match {
+ case Some(defaults) => defaults foreach add
+ case None => errorFn(s"'$name' requires an option. See '$name:help'.")
+ } else {
+ added foreach add
+ }
+
Some(rest)
}
+ def contains(choice: domain.Value): Boolean = value contains choice
+
def isHelping: Boolean = sawHelp
- def help: String = helper(this)
- def addAll(): Unit = (default getOrElse adderAll)()
- // the semantics is: s is enabled, i.e., either s or (_ but not -s)
- override def contains(s: String) = isChoice(s) && (value contains s) || (sawAll && !(value contains s"-$s"))
+ def help: String = {
+ val choiceLength = choices.map(_.length).max + 1
+ val formatStr = s" %-${choiceLength}s %s"
+ choices.zipAll(descriptions, "", "").map {
+ case (arg, descr) => formatStr.format(arg, descr)
+ } mkString (f"$descr%n", f"%n", "")
+ }
+
+ def clear(): Unit = {
+ v = domain.ValueSet.empty
+ yeas = domain.ValueSet.empty
+ nays = domain.ValueSet.empty
+ sawAll = false
+ sawHelp = false
+ }
+ def unparse: List[String] = value.toList map (s => s"$name:$s")
+ def contains(s: String) = domain.values.find(_.toString == s).exists(value.contains)
}
/** A setting that accumulates all strings supplied to it,
@@ -619,15 +754,15 @@ class MutableSettings(val errorFn: String => Unit)
def appendToValue(str: String) = value ++= List(str)
// try to set. halting means halt at first non-arg
- protected def tts(args: List[String], halting: Boolean) = {
+ protected def tryToSetArgs(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(loop(args))
}
- def tryToSet(args: List[String]) = tts(args, halting = true)
- override def tryToSetColon(args: List[String]) = tts(args, halting = false)
+ def tryToSet(args: List[String]) = tryToSetArgs(args, halting = true)
+ override def tryToSetColon(args: List[String]) = tryToSetArgs(args, halting = false)
override def tryToSetFromPropertyValue(s: String) = tryToSet(s.trim.split(',').toList) // used from ide
def clear(): Unit = (v = Nil)
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index 8e69598614..91b03869e5 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -45,7 +45,7 @@ trait ScalaSettings extends AbsScalaSettings
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 }
+ private def multihelp = allSettings exists { case s: MultiChoiceSetting[_] => s.isHelping case _ => false }
/** Is an info setting set? */
def isInfo = (infoSettings exists (_.isSetByUser)) || multihelp
@@ -69,28 +69,23 @@ trait ScalaSettings extends AbsScalaSettings
// Would be nice to build this dynamically from scala.languageFeature.
// The two requirements: delay error checking until you have symbols, and let compiler command build option-specific help.
+ object languageFeatures extends MultiChoiceEnumeration {
+ val dynamics = Choice("dynamics", "Allow direct or indirect subclasses of scala.Dynamic")
+ val postfixOps = Choice("postfixOps", "Allow postfix operator notation, such as `1 to 10 toList'")
+ val reflectiveCalls = Choice("reflectiveCalls", "Allow reflective access to members of structural types")
+ val implicitConversions = Choice("implicitConversions", "Allow definition of implicit functions called views")
+ val higherKinds = Choice("higherKinds", "Allow higher-kinded types")
+ val existentials = Choice("existentials", "Existential types (besides wildcard types) can be written and inferred")
+ val macros = Choice("experimental.macros", "Allow macro defintion (besides implementation and application)")
+ }
val language = {
- val features = List(
- "dynamics" -> "Allow direct or indirect subclasses of scala.Dynamic",
- "postfixOps" -> "Allow postfix operator notation, such as `1 to 10 toList'",
- "reflectiveCalls" -> "Allow reflective access to members of structural types",
- "implicitConversions" -> "Allow definition of implicit functions called views",
- "higherKinds" -> "Allow higher-kinded types", // "Ask Adriaan, but if you have to ask..."
- "existentials" -> "Existential types (besides wildcard types) can be written and inferred",
- "experimental.macros" -> "Allow macro defintion (besides implementation and application)"
- )
val description = "Enable or disable language features"
MultiChoiceSetting(
name = "-language",
helpArg = "feature",
descr = description,
- choices = features map (_._1)
- ) { s =>
- val helpline: ((String, String)) => String = {
- case (name, text) => f" $name%-25s $text%n"
- }
- features map helpline mkString (f"$description:%n", "", f"%n")
- }
+ domain = languageFeatures
+ )
}
/*
@@ -193,7 +188,6 @@ trait ScalaSettings extends AbsScalaSettings
val Ygenjavap = StringSetting ("-Ygen-javap", "dir", "Generate a parallel output directory of .javap files.", "")
val Ygenasmp = StringSetting ("-Ygen-asmp", "dir", "Generate a parallel output directory of .asmp files (ie ASM Textifier output).", "")
val Ydumpclasses = StringSetting ("-Ydump-classes", "dir", "Dump the generated bytecode to .class files (useful for reflective compilation that utilizes in-memory classloaders).", "")
- val Ystatistics = BooleanSetting ("-Ystatistics", "Print compiler statistics.") andThen (scala.reflect.internal.util.Statistics.enabled = _)
val stopAfter = PhasesSetting ("-Ystop-after", "Stop after") withAbbreviation ("-stop") // backward compat
val stopBefore = PhasesSetting ("-Ystop-before", "Stop before")
val Yrangepos = BooleanSetting ("-Yrangepos", "Use range positions for syntax trees.")
@@ -217,6 +211,20 @@ trait ScalaSettings extends AbsScalaSettings
private def removalIn212 = "This flag is scheduled for removal in 2.12. If you have a case where you need this flag then please report a bug."
+ object YstatisticsPhases extends MultiChoiceEnumeration { val parser, typer, patmat, erasure, cleanup = Value }
+ val Ystatistics = {
+ val description = "Print compiler statistics for specific phases"
+ MultiChoiceSetting(
+ name = "-Ystatistics",
+ helpArg = "phase",
+ descr = description,
+ domain = YstatisticsPhases,
+ default = Some(List("_"))
+ ) withPostSetHook { _ => scala.reflect.internal.util.Statistics.enabled = true }
+ }
+
+ def YstatisticsEnabled = Ystatistics.value.nonEmpty
+
/** Area-specific debug output.
*/
val Ydocdebug = BooleanSetting("-Ydoc-debug", "Trace all scaladoc activity.")
diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala
index 4c37633301..c400e8c29c 100644
--- a/src/compiler/scala/tools/nsc/settings/Warnings.scala
+++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala
@@ -17,145 +17,94 @@ trait Warnings {
// Warning semantics.
val fatalWarnings = BooleanSetting("-Xfatal-warnings", "Fail the compilation if there are any warnings.")
- // These additional warnings are all so noisy as to be useless in their
- // present form, but have the potential to offer useful info.
- protected def allWarnings = lintWarnings ++ List(
- warnDeadCode,
- warnValueDiscard,
- warnNumericWiden,
- warnUnused, // SI-7712, SI-7707 warnUnused not quite ready for prime-time
- warnUnusedImport, // currently considered too noisy for general use
- warnValueOverrides // currently turned off as experimental
- )
- // These warnings should be pretty quiet unless you're doing
- // something inadvisable.
- protected def lintWarnings = List(
- warnInaccessible,
- warnNullaryOverride,
- warnNullaryUnit,
- warnAdaptedArgs,
- warnInferAny,
- warnMissingInterpolator,
- warnDocDetached,
- warnPrivateShadow,
- warnTypeParameterShadow,
- warnPolyImplicitOverload,
- warnOptionImplicit,
- warnDelayedInit,
- warnByNameRightAssociative,
- warnPackageObjectClasses,
- warnUnsoundMatch
- )
-
- // Individual warnings. They can be set with -Ywarn.
- private def nonlintflag(name: String, text: String): BooleanSetting = BooleanSetting(name, text)
-
- val warnDeadCode = nonlintflag("-Ywarn-dead-code",
- "Warn when dead code is identified.")
- val warnValueDiscard = nonlintflag("-Ywarn-value-discard",
- "Warn when non-Unit expression results are unused.")
- val warnNumericWiden = nonlintflag("-Ywarn-numeric-widen",
- "Warn when numerics are widened.")
- val warnUnused = nonlintflag("-Ywarn-unused",
- "Warn when local and private vals, vars, defs, and types are are unused")
- val warnUnusedImport = nonlintflag("-Ywarn-unused-import",
- "Warn when imports are unused")
-
- // Lint warnings that have no -Y avatar, created with new instead of the autoregistering factory method.
- // They evaluate true if set to true or else are unset but -Xlint is true
- private def lintflag(name: String, text: String): BooleanSetting =
- new BooleanSetting(name, text) {
- override def value = if (isSetByUser) super.value else xlint
- }
-
- 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 warnTypeParameterShadow = lintflag("type-parameter-shadow",
- "A local type parameter shadows a type already in scope.")
- 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")
+ // Non-lint warnings
+
+ 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.")
+ // SI-7712, SI-7707 warnUnused not quite ready for prime-time
+ val warnUnused = BooleanSetting("-Ywarn-unused", "Warn when local and private vals, vars, defs, and types are are unused.")
+ // currently considered too noisy for general use
+ val warnUnusedImport = BooleanSetting("-Ywarn-unused-import", "Warn when imports are unused.")
// Experimental lint warnings that are turned off, but which could be turned on programmatically.
// These warnings are said to blind those who dare enable them.
// They are not activated by -Xlint and can't be enabled on the command line.
- val warnValueOverrides = {
- val flag = lintflag("value-overrides", "Generated value class method overrides an implementation")
+ val warnValueOverrides = { // currently turned off as experimental. creaded using constructor (new BS), so not available on the command line.
+ val flag = new BooleanSetting("value-overrides", "Generated value class method overrides an implementation")
flag.value = false
flag
}
- // 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 = {
- val description = "Enable or disable specific warnings"
- val choices = (lintWarnings map (_.name)).sorted
- MultiChoiceSetting(
- name = "-Xlint",
- helpArg = "warning",
- descr = description,
- choices = choices,
- default = Some(() => xlint.value = true)
- ) { s =>
- def helpline(n: String) = lintWarnings.find(_.name == n).map(w => f" ${w.name}%-25s ${w.helpDescription}%n")
- choices flatMap (helpline(_)) mkString (f"$description:%n", "", f"%n")
- } 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))
- 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 => ()
- }
- propagate(x.value)
- }
+ // Lint warnings
+
+ object LintWarnings extends MultiChoiceEnumeration {
+ class LintWarning(name: String, help: String, val yAliased: Boolean) extends Choice(name, help)
+ def LintWarning(name: String, help: String, yAliased: Boolean = false) = new LintWarning(name, help, yAliased)
+
+ val AdaptedArgs = LintWarning("adapted-args", "Warn if an argument list is modified to match the receiver.", true)
+ val NullaryUnit = LintWarning("nullary-unit", "Warn when nullary methods return Unit.", true)
+ val Inaccessible = LintWarning("inaccessible", "Warn about inaccessible types in method signatures.", true)
+ val NullaryOverride = LintWarning("nullary-override", "Warn when non-nullary `def f()' overrides nullary `def f'.", true)
+ val InferAny = LintWarning("infer-any", "Warn when a type argument is inferred to be `Any`.", true)
+ val MissingInterpolator = LintWarning("missing-interpolator", "A string literal appears to be missing an interpolator id.")
+ val DocDetached = LintWarning("doc-detached", "A ScalaDoc comment appears to be detached from its element.")
+ val PrivateShadow = LintWarning("private-shadow", "A private field (or class parameter) shadows a superclass field.")
+ val TypeParameterShadow = LintWarning("type-parameter-shadow", "A local type parameter shadows a type already in scope.")
+ val PolyImplicitOverload = LintWarning("poly-implicit-overload", "Parameterized overloaded implicit methods are not visible as view bounds.")
+ val OptionImplicit = LintWarning("option-implicit", "Option.apply used implicit view.")
+ val DelayedInitSelect = LintWarning("delayedinit-select", "Selecting member of DelayedInit")
+ val ByNameRightAssociative = LintWarning("by-name-right-associative", "By-name parameter of right associative operator.")
+ val PackageObjectClasses = LintWarning("package-object-classes", "Class or object defined in package object.")
+ val UnsoundMatch = LintWarning("unsound-match", "Pattern match may not be typesafe.")
+
+ def allLintWarnings = values.toSeq.asInstanceOf[Seq[LintWarning]]
}
+ import LintWarnings._
+
+ def warnAdaptedArgs = lint contains AdaptedArgs
+ def warnNullaryUnit = lint contains NullaryUnit
+ def warnInaccessible = lint contains Inaccessible
+ def warnNullaryOverride = lint contains NullaryOverride
+ def warnInferAny = lint contains InferAny
+ def warnMissingInterpolator = lint contains MissingInterpolator
+ def warnDocDetached = lint contains DocDetached
+ def warnPrivateShadow = lint contains PrivateShadow
+ def warnTypeParameterShadow = lint contains TypeParameterShadow
+ def warnPolyImplicitOverload = lint contains PolyImplicitOverload
+ def warnOptionImplicit = lint contains OptionImplicit
+ def warnDelayedInit = lint contains DelayedInitSelect
+ def warnByNameRightAssociative = lint contains ByNameRightAssociative
+ def warnPackageObjectClasses = lint contains PackageObjectClasses
+ def warnUnsoundMatch = lint contains UnsoundMatch
// Lint warnings that are currently -Y, but deprecated in that usage
@deprecated("Use warnAdaptedArgs", since="2.11.2")
- val YwarnAdaptedArgs = BooleanSetting("-Ywarn-adapted-args",
- "Warn if an argument list is modified to match the receiver.") enabling List(warnAdaptedArgs)
- //withDeprecationMessage "Enable -Xlint:adapted-args"
+ def YwarnAdaptedArgs = warnAdaptedArgs
@deprecated("Use warnNullaryUnit", since="2.11.2")
- val YwarnNullaryUnit = BooleanSetting("-Ywarn-nullary-unit",
- "Warn when nullary methods return Unit.") enabling List(warnNullaryUnit)
- //withDeprecationMessage "Enable -Xlint:nullary-unit"
+ def YwarnNullaryUnit = warnNullaryUnit
@deprecated("Use warnInaccessible", since="2.11.2")
- val YwarnInaccessible = BooleanSetting("-Ywarn-inaccessible",
- "Warn about inaccessible types in method signatures.") enabling List(warnInaccessible)
- //withDeprecationMessage "Enable -Xlint:inaccessible"
+ def YwarnInaccessible = warnInaccessible
@deprecated("Use warnNullaryOverride", since="2.11.2")
- val YwarnNullaryOverride = BooleanSetting("-Ywarn-nullary-override",
- "Warn when non-nullary `def f()' overrides nullary `def f'.") enabling List(warnNullaryOverride)
- //withDeprecationMessage "Enable -Xlint:nullary-override"
+ def YwarnNullaryOverride = warnNullaryOverride
@deprecated("Use warnInferAny", since="2.11.2")
- val YwarnInferAny = BooleanSetting("-Ywarn-infer-any",
- "Warn when a type argument is inferred to be `Any`.") enabling List(warnInferAny)
- //withDeprecationMessage "Enable -Xlint:infer-any"
+ def YwarnInferAny = warnInferAny
+
+ // The Xlint warning group.
+ val lint = MultiChoiceSetting(
+ name = "-Xlint",
+ helpArg = "warning",
+ descr = "Enable or disable specific warnings",
+ domain = LintWarnings,
+ default = Some(List("_")))
+
+ allLintWarnings foreach {
+ case w if w.yAliased =>
+ BooleanSetting(s"-Ywarn-${w.name}", {w.help}) withPostSetHook { s =>
+ lint.add(if (s) w.name else s"-${w.name}")
+ } // withDeprecationMessage s"Enable -Xlint:${c._1}"
+ case _ =>
+ }
private lazy val warnSelectNullable = BooleanSetting("-Xcheck-null", "This option is obsolete and does nothing.")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index fb7651ffd6..421021163e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -552,7 +552,7 @@ trait Infer extends Checkable {
}
case _ => context.tree.pos
}
- if (settings.warnInferAny.value && context.reportErrors && canWarnAboutAny) {
+ if (settings.warnInferAny && context.reportErrors && canWarnAboutAny) {
foreachWithIndex(targs) ((targ, idx) =>
targ.typeSymbol match {
case sym @ (AnyClass | AnyValClass) =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 1cb775959d..af4e9e8927 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1287,6 +1287,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
private def checkUndesiredProperties(sym: Symbol, pos: Position) {
// If symbol is deprecated, and the point of reference is not enclosed
// in either a deprecated member or a scala bridge method, issue a warning.
+ // TODO: x.hasBridgeAnnotation doesn't seem to be needed here...
if (sym.isDeprecated && !currentOwner.ownerChain.exists(x => x.isDeprecated || x.hasBridgeAnnotation))
currentRun.reporting.deprecationWarning(pos, sym)
@@ -1305,7 +1306,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
reporter.warning(pos, s"${sym.fullLocationString} has changed semantics in version ${sym.migrationVersion.get}:\n${sym.migrationMessage.get}")
}
// See an explanation of compileTimeOnly in its scaladoc at scala.annotation.compileTimeOnly.
- if (sym.isCompileTimeOnly) {
+ if (sym.isCompileTimeOnly && !currentOwner.ownerChain.exists(x => x.isCompileTimeOnly)) {
def defaultMsg =
sm"""Reference to ${sym.fullLocationString} should not have survived past type checking,
|it should have been processed and eliminated during expansion of an enclosing macro."""
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 38b00a015b..db81eecdf5 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -82,11 +82,11 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
val buf = accDefs.getOrElse(clazz, sys.error("no acc def buf for "+clazz))
buf += typers(clazz) typed tree
}
- private def ensureAccessor(sel: Select) = {
+ private def ensureAccessor(sel: Select, mixName: TermName = nme.EMPTY) = {
val Select(qual, name) = sel
val sym = sel.symbol
val clazz = qual.symbol
- val supername = nme.superName(name)
+ val supername = nme.superName(name, mixName)
val superAcc = clazz.info.decl(supername).suchThat(_.alias == sym) orElse {
debuglog(s"add super acc ${sym.fullLocationString} to $clazz")
val acc = clazz.newMethod(supername, sel.pos, SUPERACCESSOR | PRIVATE | ARTIFACT) setAlias sym
@@ -150,8 +150,20 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
}
}
- if (name.isTermName && mix == tpnme.EMPTY && (clazz.isTrait || clazz != currentClass || !validCurrentOwner))
- ensureAccessor(sel)
+ def mixIsTrait = sup.tpe match {
+ case SuperType(thisTpe, superTpe) => superTpe.typeSymbol.isTrait
+ }
+
+ val needAccessor = name.isTermName && {
+ mix.isEmpty && (clazz.isTrait || clazz != currentClass || !validCurrentOwner) ||
+ // SI-8803. If we access super[A] from an inner class (!= currentClass) or closure (validCurrentOwner),
+ // where A is the superclass we need an accessor. If A is a parent trait we don't: in this case mixin
+ // will re-route the super call directly to the impl class (it's statically known).
+ !mix.isEmpty && (clazz != currentClass || !validCurrentOwner) && !mixIsTrait
+ }
+
+ if (needAccessor)
+ ensureAccessor(sel, mix.toTermName)
else sel
}
diff --git a/src/compiler/scala/tools/nsc/util/StatisticsInfo.scala b/src/compiler/scala/tools/nsc/util/StatisticsInfo.scala
index 225f6ca68e..be245347a8 100644
--- a/src/compiler/scala/tools/nsc/util/StatisticsInfo.scala
+++ b/src/compiler/scala/tools/nsc/util/StatisticsInfo.scala
@@ -14,12 +14,10 @@ abstract class StatisticsInfo {
import global._
import scala.reflect.internal.TreesStats.nodeByType
- val phasesShown = List("parser", "typer", "patmat", "erasure", "cleanup")
-
val retainedCount = Statistics.newCounter("#retained tree nodes")
val retainedByType = Statistics.newByClass("#retained tree nodes by type")(Statistics.newCounter(""))
- def print(phase: Phase) = if (phasesShown contains phase.name) {
+ def print(phase: Phase) = if (settings.Ystatistics contains phase.name) {
inform("*** Cumulative statistics at phase " + phase)
retainedCount.value = 0
for (c <- retainedByType.keys)
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index f6f46e158f..660cc5a42a 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -1088,6 +1088,9 @@ trait Iterator[+A] extends TraversableOnce[A] {
}
/** Returns this iterator with patched values.
+ * Patching at negative indices is the same as patching starting at 0.
+ * Patching at indices at or larger than the length of the original iterator appends the patch to the end.
+ * If more values are replaced than actually exist, the excess is ignored.
*
* @param from The start index from which to patch
* @param patchElems The iterator of patch values
@@ -1096,18 +1099,33 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def patch[B >: A](from: Int, patchElems: Iterator[B], replaced: Int): Iterator[B] = new AbstractIterator[B] {
private var origElems = self
- private var i = 0
- def hasNext: Boolean =
- if (i < from) origElems.hasNext
- else patchElems.hasNext || origElems.hasNext
+ private var i = (if (from > 0) from else 0) // Counts down, switch to patch on 0, -1 means use patch first
+ def hasNext: Boolean = {
+ if (i == 0) {
+ origElems = origElems drop replaced
+ i = -1
+ }
+ origElems.hasNext || patchElems.hasNext
+ }
def next(): B = {
- // We have to do this *first* just in case from = 0.
- if (i == from) origElems = origElems drop replaced
- val result: B =
- if (i < from || !patchElems.hasNext) origElems.next()
- else patchElems.next()
- i += 1
- result
+ if (i == 0) {
+ origElems = origElems drop replaced
+ i = -1
+ }
+ if (i < 0) {
+ if (patchElems.hasNext) patchElems.next()
+ else origElems.next()
+ }
+ else {
+ if (origElems.hasNext) {
+ i -= 1
+ origElems.next()
+ }
+ else {
+ i = -1
+ patchElems.next()
+ }
+ }
}
}
diff --git a/src/library/scala/collection/SeqViewLike.scala b/src/library/scala/collection/SeqViewLike.scala
index 5e31ac4a53..e719f19c78 100644
--- a/src/library/scala/collection/SeqViewLike.scala
+++ b/src/library/scala/collection/SeqViewLike.scala
@@ -154,17 +154,27 @@ trait SeqViewLike[+A,
}
}
+ // Note--for this to work, must ensure 0 <= from and 0 <= replaced
+ // Must also take care to allow patching inside an infinite stream
+ // (patching in an infinite stream is not okay)
trait Patched[B >: A] extends Transformed[B] {
protected[this] val from: Int
protected[this] val patch: GenSeq[B]
protected[this] val replaced: Int
private lazy val plen = patch.length
override def iterator: Iterator[B] = self.iterator patch (from, patch.iterator, replaced)
- def length: Int = self.length + plen - replaced
- def apply(idx: Int): B =
- if (idx < from) self.apply(idx)
- else if (idx < from + plen) patch.apply(idx - from)
+ def length: Int = {
+ val len = self.length
+ val pre = math.min(from, len)
+ val post = math.max(0, len - pre - replaced)
+ pre + plen + post
+ }
+ def apply(idx: Int): B = {
+ val actualFrom = if (self.lengthCompare(from) < 0) self.length else from
+ if (idx < actualFrom) self.apply(idx)
+ else if (idx < actualFrom + plen) patch.apply(idx - actualFrom)
else self.apply(idx - plen + replaced)
+ }
final override protected[this] def viewIdentifier = "P"
}
@@ -210,7 +220,10 @@ trait SeqViewLike[+A,
override def reverse: This = newReversed.asInstanceOf[This]
override def patch[B >: A, That](from: Int, patch: GenSeq[B], replaced: Int)(implicit bf: CanBuildFrom[This, B, That]): That = {
- newPatched(from, patch, replaced).asInstanceOf[That]
+ // Be careful to not evaluate the entire sequence! Patch should work (slowly, perhaps) on infinite streams.
+ val nonNegFrom = math.max(0,from)
+ val nonNegRep = math.max(0,replaced)
+ newPatched(nonNegFrom, patch, nonNegRep).asInstanceOf[That]
// was: val b = bf(repr)
// if (b.isInstanceOf[NoBuilder[_]]) newPatched(from, patch, replaced).asInstanceOf[That]
// else super.patch[B, That](from, patch, replaced)(bf)
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 6848c357c5..d203218c09 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -473,7 +473,7 @@ trait StdNames {
)
def localDummyName(clazz: Symbol): TermName = newTermName(LOCALDUMMY_PREFIX + clazz.name + ">")
- def superName(name: Name): TermName = newTermName(SUPER_PREFIX_STRING + name)
+ def superName(name: Name, mix: Name = EMPTY): TermName = newTermName(SUPER_PREFIX_STRING + name + (if (mix.isEmpty) "" else "$" + mix))
/** The name of an accessor for protected symbols. */
def protName(name: Name): TermName = newTermName(PROTECTED_PREFIX + name)
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
index d5e2f9a2c4..7cd8fa8e51 100755
--- a/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/CommentFactoryBase.scala
@@ -681,10 +681,10 @@ trait CommentFactoryBase { this: MemberLookupBase =>
jump("[[")
val parens = 2 + repeatJump('[')
val stop = "]" * parens
- val target = readUntil { check(stop) || check(" ") }
+ val target = readUntil { check(stop) || isWhitespaceOrNewLine(char) }
val title =
if (!check(stop)) Some({
- jump(" ")
+ jumpWhitespaceOrNewLine()
inline(check(stop))
})
else None
@@ -723,49 +723,15 @@ trait CommentFactoryBase { this: MemberLookupBase =>
*/
def normalizeIndentation(_code: String): String = {
- val code = _code.trim
- var maxSkip = Integer.MAX_VALUE
- var crtSkip = 0
- var wsArea = true
- var index = 0
- var firstLine = true
- var emptyLine = true
-
- while (index < code.length) {
- code(index) match {
- case ' ' =>
- if (wsArea)
- crtSkip += 1
- case c =>
- wsArea = (c == '\n')
- maxSkip = if (firstLine || emptyLine) maxSkip else if (maxSkip <= crtSkip) maxSkip else crtSkip
- crtSkip = if (c == '\n') 0 else crtSkip
- firstLine = if (c == '\n') false else firstLine
- emptyLine = if (c == '\n') true else false
- }
- index += 1
- }
+ val code = _code.replaceAll("\\s+$", "").dropWhile(_ == '\n') // right-trim + remove all leading '\n'
+ val lines = code.split("\n")
- if (maxSkip == 0)
- code
- else {
- index = 0
- val builder = new StringBuilder
- while (index < code.length) {
- builder.append(code(index))
- if (code(index) == '\n') {
- // we want to skip as many spaces are available, if there are less spaces (like on empty lines, do not
- // over-consume them)
- index += 1
- val limit = index + maxSkip
- while ((index < code.length) && (code(index) == ' ') && index < limit)
- index += 1
- }
- else
- index += 1
- }
- builder.toString
- }
+ // maxSkip - size of the longest common whitespace prefix of non-empty lines
+ val nonEmptyLines = lines.filter(_.trim.nonEmpty)
+ val maxSkip = if (nonEmptyLines.isEmpty) 0 else nonEmptyLines.map(line => line.prefixLength(_ == ' ')).min
+
+ // remove common whitespace prefix
+ lines.map(line => if (line.trim.nonEmpty) line.substring(maxSkip) else line).mkString("\n")
}
def checkParaEnded(): Boolean = {
@@ -899,6 +865,8 @@ trait CommentFactoryBase { this: MemberLookupBase =>
def jumpWhitespace() = jumpUntil(!isWhitespace(char))
+ def jumpWhitespaceOrNewLine() = jumpUntil(!isWhitespaceOrNewLine(char))
+
/* READERS */
final def readUntil(c: Char): String = {
@@ -938,5 +906,7 @@ trait CommentFactoryBase { this: MemberLookupBase =>
/* CHARS CLASSES */
def isWhitespace(c: Char) = c == ' ' || c == '\t'
+
+ def isWhitespaceOrNewLine(c: Char) = isWhitespace(c) || c == '\n'
}
}
diff --git a/test/files/jvm/varargs/VaClass.scala b/test/files/jvm/varargs/VaClass.scala
index e94e8a625a..d83e63ace1 100644
--- a/test/files/jvm/varargs/VaClass.scala
+++ b/test/files/jvm/varargs/VaClass.scala
@@ -9,5 +9,7 @@ class VaClass {
@varargs def vs(a: Int, b: String*) = println(a + b.length)
@varargs def vi(a: Int, b: Int*) = println(a + b.sum)
@varargs def vt[T](a: Int, b: T*) = println(a + b.length)
- @varargs def vt1[T](a: Int, b: T*): T = b.head
+
+ // TODO remove type bound after fixing SI-8786, see also https://github.com/scala/scala/pull/3961
+ @varargs def vt1[T <: String](a: Int, b: T*): T = b.head
}
diff --git a/test/files/neg/compile-time-only-a.check b/test/files/neg/compile-time-only-a.check
index 9bc96f6b9b..b1ed1d24c2 100644
--- a/test/files/neg/compile-time-only-a.check
+++ b/test/files/neg/compile-time-only-a.check
@@ -4,9 +4,6 @@ compile-time-only-a.scala:10: error: C3
compile-time-only-a.scala:12: error: C4
@compileTimeOnly("C4") case class C4(x: Int)
^
-compile-time-only-a.scala:17: error: C5
- implicit class C5(val x: Int) {
- ^
compile-time-only-a.scala:32: error: C1
new C1()
^
@@ -76,4 +73,4 @@ compile-time-only-a.scala:75: error: placebo
compile-time-only-a.scala:75: error: placebo
@placebo def x = (2: @placebo)
^
-26 errors found
+25 errors found
diff --git a/test/files/pos/t8410.flags b/test/files/pos/t8410.flags
new file mode 100644
index 0000000000..dcd5943c2f
--- /dev/null
+++ b/test/files/pos/t8410.flags
@@ -0,0 +1 @@
+-optimise -Xfatal-warnings -deprecation:false -Yinline-warnings:false
diff --git a/test/files/pos/t8410.scala b/test/files/pos/t8410.scala
new file mode 100644
index 0000000000..4d862311fa
--- /dev/null
+++ b/test/files/pos/t8410.scala
@@ -0,0 +1,15 @@
+
+object Test extends App {
+ @deprecated("","") def f = 42
+ @deprecated("","") def z = f
+ def g = { @deprecated("","") def _f = f ; _f } // warns in 2.11.0-M8
+ def x = { @deprecated("","") class X { def x = f } ; new X().x } // warns in 2.11.0-M8
+ Console println g
+ Console println f // warns
+
+ @deprecated("","") trait T
+ object T extends T { def t = f }
+ Console println T.t
+
+ def k = List(0).dropWhile(_ < 1) // inlining warns doubly
+}
diff --git a/test/files/pos/t8498.scala b/test/files/pos/t8498.scala
new file mode 100644
index 0000000000..6808c89051
--- /dev/null
+++ b/test/files/pos/t8498.scala
@@ -0,0 +1,6 @@
+import scala.annotation.compileTimeOnly
+
+class C(val s: String) extends AnyVal {
+ @compileTimeOnly("error")
+ def error = ???
+}
diff --git a/test/files/run/t8803.check b/test/files/run/t8803.check
new file mode 100644
index 0000000000..bd26a0fb14
--- /dev/null
+++ b/test/files/run/t8803.check
@@ -0,0 +1,16 @@
+a
+b
+b
+c
+a
+b
+b
+c
+a
+b
+b
+c
+a
+b
+b
+c
diff --git a/test/files/run/t8803.scala b/test/files/run/t8803.scala
new file mode 100644
index 0000000000..2e56180502
--- /dev/null
+++ b/test/files/run/t8803.scala
@@ -0,0 +1,57 @@
+class A {
+ def m = "a"
+ protected def n = "a"
+}
+
+trait B {
+ def m = "b"
+ protected def n = "b"
+}
+
+class C extends A with B {
+ override def m = "c"
+ override protected def n = "c"
+
+ val f1 = () => super[A].m
+ val f2 = () => super[B].m
+ val f3 = () => super.m
+ val f4 = () => this.m
+
+ val g1 = new runtime.AbstractFunction0[String] { def apply() = C.super[A].m }
+ val g2 = new runtime.AbstractFunction0[String] { def apply() = C.super[B].m }
+ val g3 = new runtime.AbstractFunction0[String] { def apply() = C.super.m }
+ val g4 = new runtime.AbstractFunction0[String] { def apply() = C.this.m }
+
+ val h1 = () => super[A].n
+ val h2 = () => super[B].n
+ val h3 = () => super.n
+ val h4 = () => this.n
+
+ val i1 = new runtime.AbstractFunction0[String] { def apply() = C.super[A].n }
+ val i2 = new runtime.AbstractFunction0[String] { def apply() = C.super[B].n }
+ val i3 = new runtime.AbstractFunction0[String] { def apply() = C.super.n }
+ val i4 = new runtime.AbstractFunction0[String] { def apply() = C.this.n }
+}
+
+object Test extends App {
+ val c = new C
+ println(c.f1())
+ println(c.f2())
+ println(c.f3())
+ println(c.f4())
+
+ println(c.g1())
+ println(c.g2())
+ println(c.g3())
+ println(c.g4())
+
+ println(c.h1())
+ println(c.h2())
+ println(c.h3())
+ println(c.h4())
+
+ println(c.i1())
+ println(c.i2())
+ println(c.i3())
+ println(c.i4())
+}
diff --git a/test/junit/scala/tools/nsc/ScriptRunnerTest.scala b/test/junit/scala/tools/nsc/ScriptRunnerTest.scala
new file mode 100644
index 0000000000..9bae7a0487
--- /dev/null
+++ b/test/junit/scala/tools/nsc/ScriptRunnerTest.scala
@@ -0,0 +1,23 @@
+package scala.tools.nsc
+
+import org.junit.Assert._
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@RunWith(classOf[JUnit4])
+class ScriptRunnerTest {
+ @Test
+ def testEmptyScriptSucceeds: Unit = {
+ val s = new GenericRunnerSettings(s => ())
+ s.nc.value = true
+ s.usejavacp.value = true
+
+ // scala -nc -e ''
+ assertTrue(ScriptRunner.runCommand(s, "", Nil))
+
+ // scala -nc -save -e ''
+ s.save.value = true
+ assertTrue(ScriptRunner.runCommand(s, "", Nil))
+ }
+}
diff --git a/test/junit/scala/tools/nsc/settings/SettingsTest.scala b/test/junit/scala/tools/nsc/settings/SettingsTest.scala
index 960d7f8ac1..eda0c27834 100644
--- a/test/junit/scala/tools/nsc/settings/SettingsTest.scala
+++ b/test/junit/scala/tools/nsc/settings/SettingsTest.scala
@@ -39,7 +39,7 @@ class SettingsTest {
}
// for the given args, select the desired setting
- private def check(args: String*)(b: MutableSettings => MutableSettings#BooleanSetting): MutableSettings#BooleanSetting = {
+ private def check(args: String*)(b: MutableSettings => Boolean): Boolean = {
val s = new MutableSettings(msg => throw new IllegalArgumentException(msg))
val (ok, residual) = s.processArguments(args.toList, processAll = true)
assert(residual.isEmpty)
@@ -54,7 +54,114 @@ class SettingsTest {
@Test def anonymousLintersCanBeNamed() {
assertTrue(check("-Xlint")(_.warnMissingInterpolator)) // among Xlint
assertFalse(check("-Xlint:-missing-interpolator")(_.warnMissingInterpolator))
+
+ // positive overrides negative, but not the other way around
+ assertTrue(check("-Xlint:-missing-interpolator,missing-interpolator")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:-missing-interpolator", "-Xlint:missing-interpolator")(_.warnMissingInterpolator))
+
+ assertTrue(check("-Xlint:missing-interpolator,-missing-interpolator")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:missing-interpolator", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator))
+
+ // -Xlint:_ adds all possible choices, but explicit negative settings will override
+ assertFalse(check("-Xlint:-missing-interpolator,_")(_.warnMissingInterpolator))
+ assertFalse(check("-Xlint:-missing-interpolator", "-Xlint:_")(_.warnMissingInterpolator))
+ assertFalse(check("-Xlint:_", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator))
+ assertFalse(check("-Xlint:_,-missing-interpolator")(_.warnMissingInterpolator))
+
+ // -Xlint is the same as -Xlint:_
assertFalse(check("-Xlint:-missing-interpolator", "-Xlint")(_.warnMissingInterpolator))
assertFalse(check("-Xlint", "-Xlint:-missing-interpolator")(_.warnMissingInterpolator))
+
+ // combination of positive, negative and _
+ assertTrue(check("-Xlint:_,-missing-interpolator,missing-interpolator")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:-missing-interpolator,_,missing-interpolator")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:-missing-interpolator,missing-interpolator,_")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:missing-interpolator,-missing-interpolator,_")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint:missing-interpolator,_,-missing-interpolator")(_.warnMissingInterpolator))
+ }
+
+ @Test def xLintInvalidChoices(): Unit = {
+ assertThrows[IllegalArgumentException](check("-Xlint:-_")(_.warnAdaptedArgs))
+ assertThrows[IllegalArgumentException](check("-Xlint:-warn-adapted-args")(_.warnAdaptedArgs)) // "warn-" should not be there
+ }
+
+ @Test def xLintNonColonated(): Unit = {
+ assertTrue(check("-Xlint", "adapted-args", "-deprecation")(_.warnAdaptedArgs))
+ assertFalse(check("-Xlint", "adapted-args", "-deprecation")(_.warnMissingInterpolator))
+ assertTrue(check("-Xlint", "adapted-args", "missing-interpolator", "-deprecation")(s => s.warnMissingInterpolator && s.warnAdaptedArgs))
+ assertThrows[IllegalArgumentException](check("-Xlint", "adapted-args", "-missing-interpolator")(_.warnAdaptedArgs)) // non-colonated: cannot provide negative args
+ }
+
+ @Test def xLintContainsValues(): Unit = {
+ // make sure that lint.contains and lint.value.contains are consistent
+ def t(s: MutableSettings, v: String) = {
+ val r = s.lint.contains(v)
+ assertSame(r, s.lint.value.contains((s.LintWarnings withName v).asInstanceOf[s.lint.domain.Value]))
+ r
+ }
+
+ assertTrue(check("-Xlint")(t(_, "adapted-args")))
+ assertTrue(check("-Xlint:_")(t(_, "adapted-args")))
+ assertFalse(check("-Xlint:_,-adapted-args")(t(_, "adapted-args")))
+ assertFalse(check("-Xlint:-adapted-args,_")(t(_, "adapted-args")))
+ assertTrue(check("-Xlint:-adapted-args,_,adapted-args")(t(_, "adapted-args")))
+ }
+
+ @Test def xLintDeprecatedAlias(): Unit = {
+ assertTrue(check("-Ywarn-adapted-args")(_.warnAdaptedArgs))
+ assertTrue(check("-Xlint:_,-adapted-args", "-Ywarn-adapted-args")(_.warnAdaptedArgs))
+ assertTrue(check("-Xlint:-adapted-args", "-Ywarn-adapted-args")(_.warnAdaptedArgs))
+ assertTrue(check("-Ywarn-adapted-args", "-Xlint:-adapted-args,_")(_.warnAdaptedArgs))
+
+ assertFalse(check("-Ywarn-adapted-args:false")(_.warnAdaptedArgs))
+ assertFalse(check("-Ywarn-adapted-args:false", "-Xlint:_")(_.warnAdaptedArgs))
+ assertFalse(check("-Ywarn-adapted-args:false", "-Xlint:_,-adapted-args")(_.warnAdaptedArgs))
+ assertTrue(check("-Ywarn-adapted-args:false", "-Xlint:_,adapted-args")(_.warnAdaptedArgs))
+ }
+
+ @Test def expandingMultichoice(): Unit = {
+ val s = new MutableSettings(msg => throw new IllegalArgumentException(msg))
+ object mChoices extends s.MultiChoiceEnumeration {
+ val a = Choice("a")
+ val b = Choice("b")
+ val c = Choice("c")
+ val d = Choice("d")
+
+ val ab = Choice("ab", expandsTo = List(a, b))
+ val ac = Choice("ac", expandsTo = List(a, c))
+ val uber = Choice("uber", expandsTo = List(ab, d))
+ }
+ val m = s.MultiChoiceSetting("-m", "args", "magic sauce", mChoices, Some(List("ac")))
+
+ def check(args: String*)(t: s.MultiChoiceSetting[mChoices.type] => Boolean): Boolean = {
+ m.clear()
+ val (ok, rest) = s.processArguments(args.toList, processAll = true)
+ assert(rest.isEmpty)
+ t(m)
+ }
+
+ import mChoices._
+
+ assertTrue(check("-m")(_.value == Set(a,c)))
+ assertTrue(check("-m:a,-b,c")(_.value == Set(a,c)))
+
+ // expanding options don't end up in the value set, only the terminal ones
+ assertTrue(check("-m:ab,ac")(_.value == Set(a,b,c)))
+ assertTrue(check("-m:_")(_.value == Set(a,b,c,d)))
+ assertTrue(check("-m:uber,ac")(_.value == Set(a,b,c,d))) // recursive expansion of uber
+
+ // explicit nays
+ assertTrue(check("-m:_,-b")(_.value == Set(a,c,d)))
+ assertTrue(check("-m:b,_,-b")(_.value == Set(a,b,c,d)))
+ assertTrue(check("-m:ac,-c")(_.value == Set(a)))
+ assertTrue(check("-m:ac,-a,-c")(_.value == Set()))
+ assertTrue(check("-m:-d,ac")(_.value == Set(a,c)))
+ assertTrue(check("-m:-b,ac,uber")(_.value == Set(a,c,d)))
+
+ assertFalse(check("-m:uber")(_.contains("i-m-not-an-option")))
+
+ assertThrows[IllegalArgumentException](check("-m:-_")(_ => true), _ contains "'-_' is not a valid choice")
+ assertThrows[IllegalArgumentException](check("-m:a,b,-ab")(_ => true), _ contains "'ab' cannot be negated")
+ assertThrows[IllegalArgumentException](check("-m:a,ac,-uber,uber")(_ => true), _ contains "'uber' cannot be negated")
}
}
diff --git a/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala b/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala
index 355771bf04..d424f12710 100644
--- a/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala
+++ b/test/junit/scala/tools/nsc/symtab/CannotHaveAttrsTest.scala
@@ -47,7 +47,7 @@ class CannotHaveAttrsTest {
assertEquals(t.tpe, NoType)
}
- @Test
+ @Test @org.junit.Ignore // SI-8816
def nonDefaultPosAssignmentFails = {
val pos = new OffsetPosition(null, 0)
attrlessTrees.foreach { t =>
@@ -56,7 +56,7 @@ class CannotHaveAttrsTest {
}
}
- @Test
+ @Test @org.junit.Ignore // SI-8816
def nonDefaultTpeAssignmentFails = {
val tpe = typeOf[Int]
attrlessTrees.foreach { t =>
diff --git a/test/junit/scala/tools/nsc/symtab/FreshNameExtractorTest.scala b/test/junit/scala/tools/nsc/symtab/FreshNameExtractorTest.scala
index cf09abdfff..effbfb2f7c 100644
--- a/test/junit/scala/tools/nsc/symtab/FreshNameExtractorTest.scala
+++ b/test/junit/scala/tools/nsc/symtab/FreshNameExtractorTest.scala
@@ -36,7 +36,7 @@ class FreshNameExtractorTest {
}
}
- @Test
+ @Test @org.junit.Ignore // SI-8818
def extractionsFailsIfNameDoesntEndWithNumber = {
val Creator = new FreshNameCreator(prefixes.head)
val Extractor = new FreshNameExtractor(prefixes.head)
@@ -44,4 +44,4 @@ class FreshNameExtractorTest {
val Extractor(_) = TermName(Creator.newName("foo") + "bar")
}
}
-} \ No newline at end of file
+}
diff --git a/test/junit/scala/tools/nsc/symtab/StdNamesTest.scala b/test/junit/scala/tools/nsc/symtab/StdNamesTest.scala
index 4a39cf9d48..524d2e45e0 100644
--- a/test/junit/scala/tools/nsc/symtab/StdNamesTest.scala
+++ b/test/junit/scala/tools/nsc/symtab/StdNamesTest.scala
@@ -15,12 +15,16 @@ class StdNamesTest {
@Test
def testNewTermNameInvalid(): Unit = {
- assertThrows[IllegalArgumentException](newTermName("foo".toCharArray, 0, -1))
- assertThrows[IllegalArgumentException](newTermName("foo".toCharArray, 0, 0))
assertThrows[IllegalArgumentException](newTermName("foo".toCharArray, -1, 1))
}
@Test
+ def testNewTermNameNegativeLenght(): Unit = {
+ assertEquals(nme.EMPTY, newTermName("foo".toCharArray, 0, -1))
+ assertEquals(nme.EMPTY, newTermName("foo".toCharArray, 0, 0))
+ }
+
+ @Test
def testUnspecializedName(): Unit = {
def test(expected: Name, nme: Name) {
assertEquals(expected, unspecializedName(nme))
diff --git a/test/junit/scala/tools/testing/AssertUtil.scala b/test/junit/scala/tools/testing/AssertUtil.scala
index 9a97c5114f..9b4833d46b 100644
--- a/test/junit/scala/tools/testing/AssertUtil.scala
+++ b/test/junit/scala/tools/testing/AssertUtil.scala
@@ -19,6 +19,8 @@ object AssertUtil {
val clazz = manifest.runtimeClass
if (!clazz.isAssignableFrom(e.getClass))
throw e
+ else return
}
+ throw new AssertionError("Expression did not throw!")
}
}
diff --git a/test/scaladoc/resources/code-indent.scala b/test/scaladoc/resources/code-indent.scala
index 88946ffc7f..2eee3352b4 100644
--- a/test/scaladoc/resources/code-indent.scala
+++ b/test/scaladoc/resources/code-indent.scala
@@ -20,6 +20,12 @@
* an alternative
* the e l s e branch
* }}}
+ * {{{
+ * Trait example {
+ * Val x = a
+ * Val y = b
+ * }
+ * }}}
* NB: Trailing spaces are necessary for this test!
* {{{
* l1
diff --git a/test/scaladoc/run/t8113.check b/test/scaladoc/run/t8113.check
new file mode 100644
index 0000000000..619c56180b
--- /dev/null
+++ b/test/scaladoc/run/t8113.check
@@ -0,0 +1 @@
+Done.
diff --git a/test/scaladoc/run/t8113.scala b/test/scaladoc/run/t8113.scala
new file mode 100644
index 0000000000..f006213ef2
--- /dev/null
+++ b/test/scaladoc/run/t8113.scala
@@ -0,0 +1,36 @@
+import scala.tools.nsc.doc.base._
+import scala.tools.nsc.doc.base.comment._
+import scala.tools.nsc.doc.model._
+import scala.tools.partest.ScaladocModelTest
+
+object Test extends ScaladocModelTest {
+
+ override def code = """
+ /**
+ * Check out [[http://www.scala-lang.org
+ * this great website]]!
+ */
+ class Test
+ """
+
+ def scaladocSettings = ""
+
+ def testModel(rootPackage: Package) = {
+ import access._
+
+ val test = rootPackage._class("Test")
+
+ // find Link
+ def find(body: Any): Option[Link] = body match {
+ case l: Link => Some(l)
+ case s: Seq[_] => s.toList.map(find(_)).flatten.headOption
+ case p: Product => p.productIterator.toList.map(find(_)).flatten.headOption
+ case _ => None
+ }
+
+ val link = find(test.comment.get.body).collect { case Link(ta, Text(ti)) => (ta, ti) }
+ assert(link.isDefined)
+ val expected = ("http://www.scala-lang.org", "this great website")
+ link.foreach {l => assert(l == expected, s"$l != $expected")}
+ }
+}
diff --git a/test/scaladoc/scalacheck/HtmlFactoryTest.scala b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
index fdc4f9527f..fc190b188c 100644
--- a/test/scaladoc/scalacheck/HtmlFactoryTest.scala
+++ b/test/scaladoc/scalacheck/HtmlFactoryTest.scala
@@ -659,6 +659,7 @@ object Test extends Properties("HtmlFactory") {
s.contains("<pre>two lines, one useful</pre>") &&
s.contains("<pre>line1\nline2\nline3\nline4</pre>") &&
s.contains("<pre>a ragged example\na (condition)\n the t h e n branch\nan alternative\n the e l s e branch</pre>") &&
+ s.contains("<pre>Trait example {\n Val x = a\n Val y = b\n}</pre>") &&
s.contains("<pre>l1\n\nl2\n\nl3\n\nl4\n\nl5</pre>")
}
case _ => false
@@ -683,7 +684,7 @@ object Test extends Properties("HtmlFactory") {
oneAuthor match {
case node: scala.xml.Node => {
val s = node.toString
- s.contains("<h6>Author:</h6>")
+ s.contains("<h6>Author:</h6>") &&
s.contains("<p>The Only Author\n</p>")
}
case _ => false
@@ -696,8 +697,8 @@ object Test extends Properties("HtmlFactory") {
twoAuthors match {
case node: scala.xml.Node => {
val s = node.toString
- s.contains("<h6>Authors:</h6>")
- s.contains("<p>The First Author\n</p>")
+ s.contains("<h6>Authors:</h6>") &&
+ s.contains("<p>The First Author</p>") &&
s.contains("<p>The Second Author\n</p>")
}
case _ => false