This commit is contained in:
soc 2017-05-01 15:16:07 +00:00 committed by GitHub
commit b54e6f40d7
44 changed files with 227 additions and 159 deletions

View File

@ -494,8 +494,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// string. So this needs attention. For now the fact that migration is
// private[scala] ought to provide enough protection.
def hasMigrationAnnotation = hasAnnotation(MigrationAnnotationClass)
def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(2) }
def migrationVersion = getAnnotation(MigrationAnnotationClass) map { version => version.intArg(0).get + "." + version.intArg(1).get }
def migrationMessage = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(0) }
def migrationVersion = getAnnotation(MigrationAnnotationClass) flatMap { _.stringArg(1) }
def elisionLevel = getAnnotation(ElidableMethodClass) flatMap { _.intArg(0) }
def implicitNotFoundMsg = getAnnotation(ImplicitNotFoundClass) flatMap { _.stringArg(0) }

View File

@ -820,7 +820,7 @@ trait ParallelMatching extends ast.TreeDSL
// match that's unimportant; so we add an instance check only if there
// is a binding.
def bindingWarning() = {
if (isBound && settings.Xmigration28.value) {
if (isBound && settings.Xmigration.isSetAndAtLeast("2.8")) {
cunit.warning(scrutTree.pos,
"A bound pattern such as 'x @ Pattern' now matches fewer cases than the same pattern with no binding.")
}

View File

@ -19,6 +19,7 @@ trait AbsScalaSettings {
type PhasesSetting <: Setting { type T = List[String] }
type StringSetting <: Setting { type T = String }
type PrefixSetting <: Setting { type T = List[String] }
type VersionSetting <: Setting { type T = Version }
type OutputDirs
type OutputSetting <: Setting
@ -32,7 +33,8 @@ trait AbsScalaSettings {
def PhasesSetting(name: String, descr: String, default: String): PhasesSetting
def StringSetting(name: String, helpArg: String, descr: String, default: String): StringSetting
def PrefixSetting(name: String, prefix: String, descr: String): PrefixSetting
def VersionSetting(name: String, helpArg: String, descr: String, default: Version): VersionSetting
/** **/
abstract class SettingGroup(val prefix: String) extends AbsSetting {
def name = prefix

View File

@ -21,7 +21,7 @@ trait AdvancedScalaSettings {
val generatephasegraph: StringSetting
val logimplicits: BooleanSetting
val mainClass: StringSetting
val migration: BooleanSetting
val migration: VersionSetting
val noforwarders: BooleanSetting
val nojline: BooleanSetting
val nouescape: BooleanSetting
@ -44,7 +44,6 @@ trait AdvancedScalaSettings {
val sourcereader: StringSetting
}
// def Xexperimental = X.experimental
// def Xmigration28 = X.migration
// def Xnojline = X.nojline
// def Xprint = X.print
// def Xprintpos = X.printpos

View File

@ -16,7 +16,7 @@ import scala.io.Source
/** A mutable Settings object.
*/
class MutableSettings(val errorFn: String => Unit)
extends scala.reflect.internal.settings.MutableSettings
extends scala.reflect.internal.settings.MutableSettings
with AbsSettings
with ScalaSettings
with Mutable {
@ -41,7 +41,7 @@ class MutableSettings(val errorFn: String => Unit)
/** Iterates over the arguments applying them to settings where applicable.
* Then verifies setting dependencies are met.
*
*
* This temporarily takes a boolean indicating whether to keep
* processing if an argument is seen which is not a command line option.
* This is an expedience for the moment so that you can say
@ -49,7 +49,7 @@ class MutableSettings(val errorFn: String => Unit)
* scalac -d /tmp foo.scala -optimise
*
* while also allowing
*
*
* scala Program opt opt
*
* to get their arguments.
@ -107,7 +107,7 @@ class MutableSettings(val errorFn: String => Unit)
* '*' in this list.
*/
lazy val outputDirs = new OutputDirs
/** A list of settings which act based on prefix rather than an exact
* match. This is basically -D and -J.
*/
@ -179,14 +179,14 @@ class MutableSettings(val errorFn: String => Unit)
}
}
}
/** Initializes these settings for embedded use by type `T`.
* The class loader defining `T` should provide resources `app.class.path`
* and `boot.class.path`. These resources should contain the application
* and boot classpaths in the same form as would be passed on the command line.*/
def embeddedDefaults[T: Manifest]: Unit =
embeddedDefaults(implicitly[Manifest[T]].erasure.getClassLoader)
/** Initializes these settings for embedded use by a class from the given class loader.
* The class loader for `T` should provide resources `app.class.path`
* and `boot.class.path`. These resources should contain the application
@ -196,10 +196,10 @@ class MutableSettings(val errorFn: String => Unit)
getClasspath("app", loader) foreach { classpath.value = _ }
getClasspath("boot", loader) foreach { bootclasspath append _ }
}
/** The parent loader to use for the interpreter.*/
private[nsc] var explicitParentLoader: Option[ClassLoader] = None
/** Retrieves the contents of resource "${id}.class.path" from `loader`
* (wrapped in Some) or None if the resource does not exist.*/
private def getClasspath(id: String, loader: ClassLoader): Option[String] =
@ -216,7 +216,10 @@ 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 VersionSetting(name: String, helpArg: String, descr: String, default: Version) =
add(new VersionSetting(name, helpArg, descr, 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))
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))
@ -303,20 +306,20 @@ class MutableSettings(val errorFn: String => Unit)
}
}
}
/** Return the source file path(s) which correspond to the given
* classfile path and SourceFile attribute value, subject to the
* condition that source files are arranged in the filesystem
* according to Java package layout conventions.
*
*
* The given classfile path must be contained in at least one of
* the specified output directories. If it does not then this
* method returns Nil.
*
*
* Note that the source file is not required to exist, so assuming
* a valid classfile path this method will always return a list
* containing at least one element.
*
*
* Also that if two or more source path elements target the same
* output directory there will be two or more candidate source file
* paths.
@ -353,7 +356,7 @@ class MutableSettings(val errorFn: String => Unit)
private var _helpSyntax = name
override def helpSyntax: String = _helpSyntax
def withHelpSyntax(s: String): this.type = { _helpSyntax = s ; this }
/** Abbreviations for this setting */
private var _abbreviations: List[String] = Nil
override def abbreviations = _abbreviations
@ -363,7 +366,7 @@ class MutableSettings(val errorFn: String => Unit)
private var dependency: Option[(Setting, String)] = None
override def dependencies = dependency.toList
def dependsOn(s: Setting, value: String): this.type = { dependency = Some((s, value)); this }
private var _deprecationMessage: Option[String] = None
override def deprecationMessage = _deprecationMessage
def withDeprecationMessage(msg: String): this.type = { _deprecationMessage = Some(msg) ; this }
@ -445,7 +448,7 @@ class MutableSettings(val errorFn: String => Unit)
value = s.equalsIgnoreCase("true")
}
}
/** A special setting for accumulating arguments like -Dfoo=bar. */
class PrefixSetting private[nsc](
name: String,
@ -454,7 +457,7 @@ class MutableSettings(val errorFn: String => Unit)
extends Setting(name, descr) {
type T = List[String]
protected var v: T = Nil
def tryToSet(args: List[String]) = args match {
case x :: xs if x startsWith prefix =>
v = v :+ x
@ -484,7 +487,7 @@ class MutableSettings(val errorFn: String => Unit)
withHelpSyntax(name + " <" + arg + ">")
}
class PathSetting private[nsc](
name: String,
descr: String,
@ -495,7 +498,7 @@ class MutableSettings(val errorFn: String => Unit)
import util.ClassPath.join
def prepend(s: String) = prependPath.value = join(s, prependPath.value)
def append(s: String) = appendPath.value = join(appendPath.value, s)
override def value = join(
prependPath.value,
super.value,
@ -573,6 +576,68 @@ class MutableSettings(val errorFn: String => Unit)
withHelpSyntax(name + ":<" + helpArg + ">")
}
class VersionSetting private[nsc] (
name: String,
helpArg: String,
descr: String,
val default: Version)
extends Setting(name, descr) {
type T = Version
protected var v: T = default
private def usageErrorMessage = {
"Usage: %s:<%s>\n where <%s> is a version string (default: %s)\n".format(
name, helpArg, helpArg, default)
}
def tryToSet(args: List[String]) = args match {
case Nil => value = default; Some(Nil)
case List(x) => try {
value = Version(x); Some(Nil)
} catch {
case ex: NumberFormatException =>
errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None)
}
case x :: xs => try {
value = Version(x); Some(xs)
} catch {
case ex: NumberFormatException =>
errorAndValue("'" + x + "' is not a valid choice for '" + name + "'", None)
}
}
override def tryToSetColon(args: List[String]) = tryToSet(args)
// args match {
// case Nil => tryToSet(Nil)
// case List(x) => tryToSet(List(x))
// case xs => errorAndValue("'" + name + "' does not accept multiple versions.", None)
// }
def unparse: List[String] =
if (value == default) Nil else List(name + ":" + value)
override def tryToSetFromPropertyValue(s: String) = tryToSetColon(s::Nil)
def isSetAndAtLeast(version: String) = isSetByUser && atLeast(version)
def isSetAndAtMost(version: String) = isSetByUser && atMost(version)
private def atLeast(version: String) =
try {
value >= Version(version)
} catch {
case _ => /* Print a warning ... I have no idea how I would do that. */ false
}
private def atMost(version: String) =
try {
value <= Version(version)
} catch {
case _ => /* Print a warning ... I have no idea how I would do that. */ false
}
withHelpSyntax(name + ":<" + helpArg + ">")
}
private def mkPhasesHelp(descr: String, default: String) = {
descr + " <phases>" + (
if (default == "") "" else " (default: " + default + ")"
@ -596,7 +661,7 @@ class MutableSettings(val errorFn: String => Unit)
override def value = if (v contains "all") List("all") else super.value
private lazy val (numericValues, stringValues) =
value filterNot (_ == "" ) partition (_ forall (ch => ch.isDigit || ch == '-'))
/** A little ad-hoc parsing. If a string is not the name of a phase, it can also be:
* a phase id: 5
* a phase id range: 5-10 (inclusive of both ends)
@ -617,7 +682,7 @@ class MutableSettings(val errorFn: String => Unit)
case Nil => _ => false
case fns => fns.reduceLeft((f1, f2) => id => f1(id) || f2(id))
}
def tryToSet(args: List[String]) =
if (default == "") errorAndValue("missing phase", None)
else { tryToSetColon(List(default)) ; Some(args) }

View File

@ -68,7 +68,7 @@ trait ScalaSettings extends AbsScalaSettings
val genPhaseGraph = StringSetting ("-Xgenerate-phase-graph", "file", "Generate the phase graphs (outputs .dot files) to fileX.dot.", "")
val XlogImplicits = BooleanSetting ("-Xlog-implicits", "Show more detail on why some implicits are not applicable.")
val maxClassfileName = IntSetting ("-Xmax-classfile-name", "Maximum filename length for generated classes", 255, Some((72, 255)), _ => None)
val Xmigration28 = BooleanSetting ("-Xmigration", "Warn about constructs whose behavior may have changed between 2.7 and 2.8.")
val Xmigration = VersionSetting ("-Xmigration", "version", "Warn about constructs whose behavior has changed since <version>.", Version(2,9))
val nouescape = BooleanSetting ("-Xno-uescape", "Disable handling of \\u unicode escapes.")
val Xnojline = BooleanSetting ("-Xnojline", "Do not use JLine for editing.")
val Xverify = BooleanSetting ("-Xverify", "Verify generic signatures in generated bytecode.")

View File

@ -0,0 +1,25 @@
/* NSC -- new Scala compiler
* Copyright 2011 LAMP/EPFL
* @author Simon Ochsenreither
*/
package scala.tools.nsc.settings
object Version {
def apply(version: String) = new Version(version.split('.').map(_.toInt): _*)
def apply(version: String, separators: Char*) =
new Version(version.split(separators.toArray).map(_.toInt): _*)
}
case class Version(version: Int*) extends Ordered[Version] {
def compare(that: Version): Int = {
this.version.zipAll(that.version, 0, 0)
.foreach {
v => if (v._1 < v._2) return -1 else if (v._1 > v._2) return 1
}
return 0
}
override def toString = version.mkString(".")
}

View File

@ -536,7 +536,7 @@ abstract class ExplicitOuter extends InfoTransform
}
}
if (settings.Xmigration28.value) tree match {
if (settings.Xmigration.isSetAndAtLeast("2.8")) tree match {
case TypeApply(fn @ Select(qual, _), args) if fn.symbol == Object_isInstanceOf || fn.symbol == Any_isInstanceOf =>
if (isArraySeqTest(qual.tpe, args.head.tpe))
unit.warning(tree.pos, "An Array will no longer match as Seq[_].")

View File

@ -1272,10 +1272,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
/** Similar to deprecation: check if the symbol is marked with @migration
* indicating it has changed semantics between versions.
*/
private def checkMigration(sym: Symbol, pos: Position) = {
for (msg <- sym.migrationMessage)
unit.warning(pos, sym.fullLocationString + " has changed semantics:\n" + msg)
}
private def checkMigration(sym: Symbol, pos: Position) =
if (sym.hasMigrationAnnotation && settings.Xmigration.isSetAndAtMost(sym.migrationVersion.get))
unit.warning(pos, "%s has changed semantics in version %s:\n%s".format(
sym.fullLocationString, sym.migrationVersion.get, sym.migrationMessage.get)
)
private def lessAccessible(otherSym: Symbol, memberSym: Symbol): Boolean = (
(otherSym != NoSymbol)
@ -1463,8 +1464,7 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
* arbitrarily choose one as more important than the other.
*/
checkDeprecated(sym, tree.pos)
if (settings.Xmigration28.value)
checkMigration(sym, tree.pos)
checkMigration(sym, tree.pos)
if (currentClass != sym.owner && sym.hasLocalFlag) {
var o = currentClass

View File

@ -14,15 +14,17 @@ package scala.annotation
* reason or another retain the same name and type signature,
* but some aspect of their behavior is different. An illustrative
* examples is Stack.iterator, which reversed from LIFO to FIFO
* order between scala 2.7 and 2.8.
* order between Scala 2.7 and 2.8.
*
* The version numbers are to mark the scala major/minor release
* version where the change took place.
* @param message A message describing the change, which is emitted
* by the compiler if the flag `-Xmigration` is set.
*
* @param changedIn The version, in which the behaviour change was
* introduced.
*
* @since 2.8
*/
private[scala] final class migration(
majorVersion: Int,
minorVersion: Int,
message: String)
extends annotation.StaticAnnotation {}
private[scala] final class migration(message: String, changedIn: String) extends annotation.StaticAnnotation {
@deprecated("Use the constructor taking two Strings instead.", "2.10")
def this(majorVersion: Int, minorVersion: Int, message: String) = this(message, majorVersion + "." + minorVersion)
}

View File

@ -123,10 +123,7 @@ trait GenTraversableLike[+A, +Repr] extends GenTraversableOnce[A] with Paralleli
* @param bf $bfinfo
* @return collection with intermediate results
*/
@migration(2, 9,
"This scanRight definition has changed in 2.9.\n" +
"The previous behavior can be reproduced with scanRight.reverse."
)
@migration("The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.", "2.9")
def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That
/** Applies a function `f` to all elements of this $coll.

View File

@ -12,8 +12,6 @@ package scala.collection
import generic._
import mutable.{ Builder, ArrayBuffer }
import TraversableView.NoBuilder
import annotation.migration
trait GenTraversableViewLike[+A,

View File

@ -9,7 +9,7 @@
package scala.collection
import mutable.ArrayBuffer
import annotation.{ tailrec, migration }
import annotation.migration
import immutable.Stream
/** The `Iterator` object provides various functions for creating specialized iterators.
@ -410,10 +410,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
* which `pf` is defined the image `pf(x)`.
* @note Reuse: $consumesAndProducesIterator
*/
@migration(2, 8,
"This collect implementation bears no relationship to the one before 2.8.\n"+
"The previous behavior can be reproduced with toSeq."
)
@migration("`collect` has changed. The previous behavior can be reproduced with `toSeq`.", "2.8")
def collect[B](pf: PartialFunction[A, B]): Iterator[B] = {
val self = buffered
new AbstractIterator[B] {

View File

@ -182,14 +182,14 @@ self =>
*
* @return the keys of this map as an iterable.
*/
@migration(2, 8, "As of 2.8, keys returns Iterable[A] rather than Iterator[A].")
@migration("`keys` returns `Iterable[A]` rather than `Iterator[A]`.", "2.8")
def keys: Iterable[A] = keySet
/** Collects all values of this map in an iterable collection.
*
* @return the values of this map as an iterable.
*/
@migration(2, 8, "As of 2.8, values returns Iterable[B] rather than Iterator[B].")
@migration("`values` returns `Iterable[B]` rather than `Iterator[B]`.", "2.8")
def values: Iterable[B] = new DefaultValuesIterable
/** The implementation class of the iterable returned by `values`.

View File

@ -85,11 +85,11 @@ self =>
copyToBuffer(result)
result
}
// note: this is only overridden here to add the migration annotation,
// which I hope to turn into an Xlint style warning as the migration aspect
// is not central to its importance.
@migration(2, 8, "Set.map now returns a Set, so it will discard duplicate values.")
@migration("Set.map now returns a Set, so it will discard duplicate values.", "2.8")
override def map[B, That](f: A => B)(implicit bf: CanBuildFrom[This, B, That]): That = super.map(f)(bf)
/** Tests if some element is contained in this set.

View File

@ -386,10 +386,7 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
b.result
}
@migration(2, 9,
"This scanRight definition has changed in 2.9.\n" +
"The previous behavior can be reproduced with scanRight.reverse."
)
@migration("The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.", "2.9")
def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[Repr, B, That]): That = {
var scanned = List(z)
var acc = z

View File

@ -185,10 +185,7 @@ trait TraversableViewLike[+A,
override def scanLeft[B, That](z: B)(op: (B, A) => B)(implicit bf: CanBuildFrom[This, B, That]): That =
newForced(thisSeq.scanLeft(z)(op)).asInstanceOf[That]
@migration(2, 9,
"This scanRight definition has changed in 2.9.\n" +
"The previous behavior can be reproduced with scanRight.reverse."
)
@migration("The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.", "2.9")
override def scanRight[B, That](z: B)(op: (A, B) => B)(implicit bf: CanBuildFrom[This, B, That]): That =
newForced(thisSeq.scanRight(z)(op)).asInstanceOf[That]

View File

@ -148,7 +148,7 @@ trait GenericTraversableTemplate[+A, +CC[X] <: GenTraversable[X]] extends HasNew
* @throws `IllegalArgumentException` if all collections in this $coll
* are not of the same size.
*/
@migration(2, 9, "As of 2.9, transpose throws an exception if collections are not uniformly sized.")
@migration("`transpose` throws an exception if collections are not uniformly sized.", "2.9")
def transpose[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[CC[B] @uncheckedVariance] = {
if (isEmpty)
return genericBuilder[CC[B]].result

View File

@ -234,10 +234,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
* @param elem the element to remove.
* @return a new collection consisting of all the elements of this collection except `elem`.
*/
@migration(2, 8,
"As of 2.8, - always creates a new collection, even on Buffers.\n"+
"Use -= instead if you intend to remove by side effect from an existing collection.\n"
)
@migration("`-` creates a new buffer. Use `-=` to remove an element from this buffer and return that buffer itself.", "2.8")
override def -(elem: A): This = clone() -= elem
/** Creates a new collection with all the elements of this collection except the two
@ -249,10 +246,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
* @return a new collection consisting of all the elements of this collection except
* `elem1`, `elem2` and those in `elems`.
*/
@migration(2, 8,
"As of 2.8, - always creates a new collection, even on Buffers.\n"+
"Use -= instead if you intend to remove by side effect from an existing collection.\n"
)
@migration("`-` creates a new buffer. Use `-=` to remove an element from this buffer and return that buffer itself.", "2.8")
override def -(elem1: A, elem2: A, elems: A*): This = clone() -= elem1 -= elem2 --= elems
/** Creates a new collection with all the elements of this collection except those
@ -262,10 +256,7 @@ trait BufferLike[A, +This <: BufferLike[A, This] with Buffer[A]]
* @return a new collection with all the elements of this collection except
* those in `xs`
*/
@migration(2, 8,
"As of 2.8, -- always creates a new collection, even on Buffers.\n"+
"Use --= instead if you intend to remove by side effect from an existing collection.\n"
)
@migration("`-` creates a new buffer. Use `-=` to remove an element from this buffer and return that buffer itself.", "2.8")
override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq
@bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A])

View File

@ -91,7 +91,7 @@ trait DoubleLinkedListLike[A, This <: Seq[A] with DoubleLinkedListLike[A, This]]
* current node, i.e. `this` node itself will still point "into" the list it
* was in.
*/
@migration(2, 9, "Double linked list now removes the current node from the list.")
@migration("Double linked list now removes the current node from the list.", "2.9")
def remove(): Unit = if (nonEmpty) {
next.prev = prev
if (prev ne null) prev.next = next // because this could be the first node

View File

@ -46,12 +46,12 @@ extends AbstractMap[A, B]
override def keysIterator: Iterator[A] = imap.keysIterator
@migration(2, 8, "As of 2.8, keys returns Iterable[A] rather than Iterator[A].")
@migration("`keys` returns Iterable[A] rather than Iterator[A].", "2.8")
override def keys: collection.Iterable[A] = imap.keys
override def valuesIterator: Iterator[B] = imap.valuesIterator
@migration(2, 8, "As of 2.8, values returns Iterable[B] rather than Iterator[B].")
@migration("`values` returns Iterable[B] rather than Iterator[B].", "2.8")
override def values: collection.Iterable[B] = imap.values
def iterator: Iterator[(A, B)] = imap.iterator

View File

@ -90,10 +90,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @param kv the key/value mapping to be added
* @return a new map containing mappings of this map and the mapping `kv`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To add an element as a\n"+
"side effect to an existing map and return that map itself, use +=."
)
@migration("`+` creates a new map. Use `+=` to add an element to this map and return that map itself.", "2.8")
def + [B1 >: B] (kv: (A, B1)): Map[A, B1] = clone().asInstanceOf[Map[A, B1]] += kv
/** Creates a new map containing two or more key/value mappings and all the key/value
@ -106,10 +103,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @param elems the remaining elements to add.
* @return a new map containing mappings of this map and two or more specified mappings.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To add an element as a\n"+
"side effect to an existing map and return that map itself, use +=."
)
@migration("`+` creates a new map. Use `+=` to add an element to this map and return that map itself.", "2.8")
override def + [B1 >: B] (elem1: (A, B1), elem2: (A, B1), elems: (A, B1) *): Map[A, B1] =
clone().asInstanceOf[Map[A, B1]] += elem1 += elem2 ++= elems
@ -121,10 +115,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @param xs the traversable object.
* @return a new map containing mappings of this map and those provided by `xs`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To add the elements as a\n"+
"side effect to an existing map and return that map itself, use ++=."
)
@migration("`+` creates a new map. Use `+=` to add an element to this map and return that map itself.", "2.8")
override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): Map[A, B1] =
clone().asInstanceOf[Map[A, B1]] ++= xs.seq
@ -154,10 +145,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @param key the key to be removed
* @return a new map with all the mappings of this map except that with a key `key`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To remove an element as a\n"+
"side effect to an existing map and return that map itself, use -=."
)
@migration("`-` creates a new map. Use `-=` to remove an element from this map and return that map itself.", "2.8")
override def -(key: A): This = clone() -= key
/** Removes all bindings from the map. After this operation has completed,
@ -223,10 +211,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @return a new map containing all the mappings of this map except mappings
* with a key equal to `elem1`, `elem2` or any of `elems`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To remove an element as a\n"+
"side effect to an existing map and return that map itself, use -=."
)
@migration("`-` creates a new map. Use `-=` to remove an element from this map and return that map itself.", "2.8")
override def -(elem1: A, elem2: A, elems: A*): This =
clone() -= elem1 -= elem2 --= elems
@ -237,10 +222,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
* @return a new map with all the key/value mappings of this map except mappings
* with a key equal to a key from `xs`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new map. To remove the elements as a\n"+
"side effect to an existing map and return that map itself, use --=."
)
@migration("`-` creates a new map. Use `-=` to remove an element from this map and return that map itself.", "2.8")
override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq
@bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A])

View File

@ -12,7 +12,7 @@ package scala.collection
package mutable
import generic._
import annotation.{migration, bridge}
import annotation.bridge
/** This class implements priority queues using a heap.
* To prioritize elements of type A there must be an implicit

View File

@ -141,10 +141,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @param elem the element to add.
* @return a new set consisting of elements of this set and `elem`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add an element as a\n"+
"side effect to an existing set and return that set itself, use +=."
)
@migration("`+` creates a new set. Use `+=` to add an element to this set and return that set itself.", "2.8")
override def + (elem: A): This = clone() += elem
/** Creates a new set consisting of all the elements of this set and two or more
@ -158,10 +155,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @return a new set consisting of all the elements of this set, `elem1`,
* `elem2` and those in `elems`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add the elements as a\n"+
"side effect to an existing set and return that set itself, use +=."
)
@migration("`+` creates a new set. Use `+=` to add an element to this set and return that set itself.", "2.8")
override def + (elem1: A, elem2: A, elems: A*): This =
clone() += elem1 += elem2 ++= elems
@ -173,10 +167,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @param xs the traversable object.
* @return a new set consisting of elements of this set and those in `xs`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To add the elements as a\n"+
"side effect to an existing set and return that set itself, use ++=."
)
@migration("`++` creates a new set. Use `++=` to add elements to this set and return that set itself.", "2.8")
override def ++(xs: GenTraversableOnce[A]): This = clone() ++= xs.seq
@bridge def ++(xs: TraversableOnce[A]): This = ++(xs: GenTraversableOnce[A])
@ -186,10 +177,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @param elem the element to remove.
* @return a new set consisting of all the elements of this set except `elem`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the element as a\n"+
"side effect to an existing set and return that set itself, use -=."
)
@migration("`-` creates a new set. Use `-=` to remove an element from this set and return that set itself.", "2.8")
override def -(elem: A): This = clone() -= elem
/** Creates a new set consisting of all the elements of this set except the two
@ -201,10 +189,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @return a new set consisting of all the elements of this set except
* `elem1`, `elem2` and `elems`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the elements as a\n"+
"side effect to an existing set and return that set itself, use -=."
)
@migration("`-` creates a new set. Use `-=` to remove an element from this set and return that set itself.", "2.8")
override def -(elem1: A, elem2: A, elems: A*): This =
clone() -= elem1 -= elem2 --= elems
@ -215,10 +200,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
* @return a new set consisting of all the elements of this set except
* elements from `xs`.
*/
@migration(2, 8,
"As of 2.8, this operation creates a new set. To remove the elements as a\n"+
"side effect to an existing set and return that set itself, use --=."
)
@migration("`--` creates a new set. Use `--=` to remove elements from this set and return that set itself.", "2.8")
override def --(xs: GenTraversableOnce[A]): This = clone() --= xs.seq
@bridge def --(xs: TraversableOnce[A]): This = --(xs: GenTraversableOnce[A])

View File

@ -148,23 +148,24 @@ extends AbstractSeq[A]
/** Returns an iterator over all elements on the stack. This iterator
* is stable with respect to state changes in the stack object; i.e.
* such changes will not be reflected in the iterator. The iterator
* issues elements in the reversed order they were inserted into the
* stack (LIFO order).
* such changes will not be reflected in the iterator.
*
* The iterator issues elements in the reversed order they were
* inserted into the stack (LIFO order).
*
* @return an iterator over all stack elements.
*/
@migration(2, 8, "Stack iterator and foreach now traverse in FIFO order.")
@migration("`iterator` traverses in FIFO order.", "2.8")
override def iterator: Iterator[A] = elems.iterator
/** Creates a list of all stack elements in LIFO order.
*
* @return the created list.
*/
@migration(2, 8, "Stack iterator and foreach now traverse in FIFO order.")
@migration("`toList` traverses in FIFO order.", "2.8")
override def toList: List[A] = elems
@migration(2, 8, "Stack iterator and foreach now traverse in FIFO order.")
@migration("`foreach` traverses in FIFO order.", "2.8")
override def foreach[U](f: A => U): Unit = super.foreach(f)
/** This method clones the stack.

View File

@ -401,7 +401,7 @@ final class StringBuilder(private val underlying: JavaStringBuilder)
*
* @return the reversed StringBuilder
*/
@migration(2, 8, "Since 2.8 reverse returns a new instance. Use 'reverseContents' to update in place.")
@migration("`reverse` returns a new instance. Use `reverseContents` to update in place and return that StringBuilder itself.", "2.8")
override def reverse: StringBuilder = new StringBuilder(new JavaStringBuilder(underlying) reverse)
override def clone(): StringBuilder = new StringBuilder(new JavaStringBuilder(underlying))

View File

@ -40,14 +40,14 @@ trait SynchronizedMap[A, B] extends Map[A, B] {
override def getOrElseUpdate(key: A, default: => B): B = synchronized { super.getOrElseUpdate(key, default) }
override def transform(f: (A, B) => B): this.type = synchronized[this.type] { super.transform(f) }
override def retain(p: (A, B) => Boolean): this.type = synchronized[this.type] { super.retain(p) }
@migration(2, 8, "As of 2.8, values returns Iterable[B] rather than Iterator[B].")
@migration("`values` returns `Iterable[B]` rather than `Iterator[B]`.", "2.8")
override def values: collection.Iterable[B] = synchronized { super.values }
override def valuesIterator: Iterator[B] = synchronized { super.valuesIterator }
override def clone(): Self = synchronized { super.clone() }
override def foreach[U](f: ((A, B)) => U) = synchronized { super.foreach(f) }
override def apply(key: A): B = synchronized { super.apply(key) }
override def keySet: collection.Set[A] = synchronized { super.keySet }
@migration(2, 8, "As of 2.8, keys returns Iterable[A] rather than Iterator[A].")
@migration("`keys` returns `Iterable[A]` rather than `Iterator[A]`.", "2.8")
override def keys: collection.Iterable[A] = synchronized { super.keys }
override def keysIterator: Iterator[A] = synchronized { super.keysIterator }
override def isEmpty: Boolean = synchronized { super.isEmpty }

View File

@ -97,7 +97,7 @@ object Codec extends LowPriorityCodecImplicits {
new Codec(decoder.charset()) { override def decoder = _decoder }
}
@migration(2, 9, "This method was previously misnamed `toUTF8`. Converts from Array[Byte] to Array[Char].")
@migration("This method was previously misnamed `toUTF8`. Converts from Array[Byte] to Array[Char].", "2.9")
def fromUTF8(bytes: Array[Byte]): Array[Char] = {
val bbuffer = java.nio.ByteBuffer wrap bytes
val cbuffer = UTF8.charSet decode bbuffer
@ -107,7 +107,7 @@ object Codec extends LowPriorityCodecImplicits {
chars
}
@migration(2, 9, "This method was previously misnamed `fromUTF8`. Converts from character sequence to Array[Byte].")
@migration("This method was previously misnamed `fromUTF8`. Converts from character sequence to Array[Byte].", "2.9")
def toUTF8(cs: CharSequence): Array[Byte] = {
val cbuffer = java.nio.CharBuffer wrap cs
val bbuffer = UTF8.charSet encode cbuffer

View File

@ -13,8 +13,6 @@ import java.{ lang => jl }
import java.math.{ MathContext, BigDecimal => BigDec }
import scala.collection.immutable.NumericRange
import annotation.migration
/**
* @author Stephane Micheloud
* @version 1.0

View File

@ -58,11 +58,11 @@ trait Ordered[A] extends java.lang.Comparable[A] {
*
* Returns `x` where:
*
* - `x < 0` when `this > that`
* - `x < 0` when `this < that`
*
* - `x == 0` when `this == that`
*
* - `x < 0` when `this > that`
* - `x > 0` when `this > that`
*
*/
def compare(that: A): Int

View File

@ -10,7 +10,7 @@ package scala.math
import java.util.Comparator
/** Ordering is trait whose instances each represent a strategy for sorting
/** Ordering is a trait whose instances each represent a strategy for sorting
* instances of a type.
*
* Ordering's companion object defines many implicit objects to deal with

View File

@ -226,7 +226,7 @@ trait Parsers {
// no filter yet, dealing with zero is tricky!
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def append[U >: T](p0: => Parser[U]): Parser[U] = { lazy val p = p0 // lazy argument
Parser{ in => this(in) append p(in)}
}
@ -245,7 +245,7 @@ trait Parsers {
* but easier to pattern match on) that contains the result of `p` and
* that of `q`. The resulting parser fails if either `p` or `q` fails.
*/
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def ~ [U](q: => Parser[U]): Parser[~[T, U]] = { lazy val p = q // lazy argument
(for(a <- this; b <- p) yield new ~(a,b)).named("~")
}
@ -258,7 +258,7 @@ trait Parsers {
* succeeds -- evaluated at most once, and only when necessary.
* @return a `Parser` that -- on success -- returns the result of `q`.
*/
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def ~> [U](q: => Parser[U]): Parser[U] = { lazy val p = q // lazy argument
(for(a <- this; b <- p) yield b).named("~>")
}
@ -273,7 +273,7 @@ trait Parsers {
* @param q a parser that will be executed after `p` (this parser) succeeds -- evaluated at most once, and only when necessary
* @return a `Parser` that -- on success -- returns the result of `p`.
*/
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def <~ [U](q: => Parser[U]): Parser[T] = { lazy val p = q // lazy argument
(for(a <- this; b <- p) yield a).named("<~")
}
@ -318,7 +318,7 @@ trait Parsers {
* @param q0 a parser that accepts if p consumes less characters. -- evaluated at most once, and only when necessary
* @return a `Parser` that returns the result of the parser consuming the most characters (out of `p` and `q`).
*/
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def ||| [U >: T](q0: => Parser[U]): Parser[U] = new Parser[U] {
lazy val q = q0 // lazy argument
def apply(in: Input) = {
@ -353,7 +353,7 @@ trait Parsers {
* @param v The new result for the parser, evaluated at most once (if `p` succeeds), not evaluated at all if `p` fails.
* @return a parser that has the same behaviour as the current parser, but whose successful result is `v`
*/
@migration(2, 9, "As of 2.9, the call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The call-by-name argument is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def ^^^ [U](v: => U): Parser[U] = new Parser[U] {
lazy val v0 = v // lazy argument
def apply(in: Input) = Parser.this(in) map (x => v0)
@ -636,7 +636,7 @@ trait Parsers {
* @return A parser that returns a list of results produced by first applying `f` and then
* repeatedly `p` to the input (it only succeeds if `f` matches).
*/
@migration(2, 9, "As of 2.9, the p0 call-by-name arguments is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.")
@migration("The `p0` call-by-name arguments is evaluated at most once per constructed Parser object, instead of on every need that arises during parsing.", "2.9")
def rep1[T](first: => Parser[T], p0: => Parser[T]): Parser[List[T]] = Parser { in =>
lazy val p = p0 // lazy argument
val elems = new ListBuffer[T]

View File

@ -1 +1 @@
-Xmigration -Xfatal-warnings
-Xmigration:2.8 -Xfatal-warnings

View File

@ -1,6 +1,5 @@
migration28.scala:4: error: method scanRight in trait TraversableLike has changed semantics:
This scanRight definition has changed in 2.9.
The previous behavior can be reproduced with scanRight.reverse.
migration28.scala:4: error: method scanRight in trait TraversableLike has changed semantics in version 2.9:
The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.
List(1,2,3,4,5).scanRight(0)(_+_)
^
one error found

View File

@ -1 +1 @@
-Xfatal-warnings -Xmigration
-Xfatal-warnings -Xmigration:2.8

View File

@ -0,0 +1,9 @@
t4990-mig-28.scala:2: error: method - in trait BufferLike has changed semantics in version 2.8:
`-` creates a new buffer. Use `-=` to remove an element from this buffer and return that buffer itself.
collection.mutable.Buffer(1,2,3,4) - 3 //@migrated in 2.8
^
t4990-mig-28.scala:3: error: method scanRight in trait TraversableLike has changed semantics in version 2.9:
The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
^
two errors found

View File

@ -0,0 +1 @@
-Xfatal-warnings -Xmigration:2.8

View File

@ -0,0 +1,4 @@
object t4990_mig_28 extends App {
collection.mutable.Buffer(1,2,3,4) - 3 //@migrated in 2.8
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
}

View File

@ -0,0 +1,5 @@
t4990-mig-29.scala:3: error: method scanRight in trait TraversableLike has changed semantics in version 2.9:
The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
^
one error found

View File

@ -0,0 +1 @@
-Xfatal-warnings -Xmigration:2.9

View File

@ -0,0 +1,4 @@
object t4990_mig_29 extends App {
collection.mutable.Buffer(1,2,3,4) - 3 //@migrated in 2.8
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
}

View File

@ -0,0 +1,5 @@
t4990-mig.scala:3: error: method scanRight in trait TraversableLike has changed semantics in version 2.9:
The behavior of `scanRight` has changed. The previous behavior can be reproduced with scanRight.reverse.
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
^
one error found

View File

@ -0,0 +1 @@
-Xfatal-warnings -Xmigration

View File

@ -0,0 +1,6 @@
object t4990_mig {
collection.mutable.Buffer(1,2,3,4) - 3 //@migrated in 2.8
List(1, 2, 3, 4).scanRight(0)(_ + _) //@migrated in 2.9
def run(args: Array[String]) { }
}