Skip to content

Commit 8f567bc

Browse files
committed
Merge pull request scala#5076 from soc/topic/deprecations-since
Improvements to deprecations related to `since` parameter
2 parents 9edbe3d + 85057d5 commit 8f567bc

File tree

195 files changed

+786
-677
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

195 files changed

+786
-677
lines changed

src/compiler/scala/tools/nsc/CompilationUnits.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ trait CompilationUnits { global: Global =>
128128
final def warning(pos: Position, msg: String): Unit = reporter.warning(pos, msg)
129129

130130
@deprecated("Call global.currentRun.reporting.deprecationWarning directly instead.", "2.11.2")
131-
final def deprecationWarning(pos: Position, msg: String): Unit = currentRun.reporting.deprecationWarning(pos, msg)
131+
final def deprecationWarning(pos: Position, msg: String, since: String): Unit = currentRun.reporting.deprecationWarning(pos, msg, since)
132132
@deprecated("Call global.currentRun.reporting.uncheckedWarning directly instead.", "2.11.2")
133133
final def uncheckedWarning(pos: Position, msg: String): Unit = currentRun.reporting.uncheckedWarning(pos, msg)
134134

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1054,9 +1054,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
10541054
var currentUnit: CompilationUnit = NoCompilationUnit
10551055

10561056
// used in sbt
1057-
def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings
1057+
def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings.map{case (pos, (msg, since)) => (pos, msg)}
10581058
// used in sbt
1059-
def deprecationWarnings: List[(Position, String)] = reporting.deprecationWarnings
1059+
def deprecationWarnings: List[(Position, String)] = reporting.deprecationWarnings.map{case (pos, (msg, since)) => (pos, msg)}
10601060

10611061
private class SyncedCompilationBuffer { self =>
10621062
private val underlying = new mutable.ArrayBuffer[CompilationUnit]
@@ -1267,11 +1267,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
12671267
private def warnDeprecatedAndConflictingSettings(unit: CompilationUnit) {
12681268
// issue warnings for any usage of deprecated settings
12691269
settings.userSetSettings filter (_.isDeprecated) foreach { s =>
1270-
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
1270+
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get, "")
12711271
}
12721272
val supportedTarget = "jvm-1.8"
12731273
if (settings.target.value != supportedTarget) {
1274-
currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget)
1274+
currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget, "2.12.0")
12751275
settings.target.value = supportedTarget
12761276
}
12771277
settings.conflictWarning.foreach(reporter.warning(NoPosition, _))

src/compiler/scala/tools/nsc/Reporting.scala

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,33 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
3030
def this(what: String, booleanSetting: Settings#BooleanSetting) {
3131
this(what, () => booleanSetting, booleanSetting)
3232
}
33-
val warnings = mutable.LinkedHashMap[Position, String]()
34-
def warn(pos: Position, msg: String) =
33+
val warnings = mutable.LinkedHashMap[Position, (String, String)]()
34+
def warn(pos: Position, msg: String, since: String = "") =
3535
if (doReport()) reporter.warning(pos, msg)
36-
else if (!(warnings contains pos)) warnings += ((pos, msg))
36+
else if (!(warnings contains pos)) warnings += ((pos, (msg, since)))
3737
def summarize() =
3838
if (warnings.nonEmpty && (setting.isDefault || doReport())) {
39-
val numWarnings = warnings.size
40-
val warningVerb = if (numWarnings == 1) "was" else "were"
41-
val warningCount = countElementsAsString(numWarnings, s"$what warning")
42-
43-
reporter.warning(NoPosition, s"there $warningVerb $warningCount; re-run with ${setting.name} for details")
39+
val sinceAndAmount = mutable.TreeMap[String, Int]()
40+
warnings.valuesIterator.foreach { case (_, since) =>
41+
val value = sinceAndAmount.get(since)
42+
if (value.isDefined) sinceAndAmount += ((since, value.get + 1))
43+
else sinceAndAmount += ((since, 1))
44+
}
45+
val deprecationSummary = sinceAndAmount.size > 1
46+
sinceAndAmount.foreach { case (since, amount) =>
47+
val numWarnings = amount
48+
val warningsSince = if (since.nonEmpty) s" (since $since)" else ""
49+
val warningVerb = if (numWarnings == 1) "was" else "were"
50+
val warningCount = countElementsAsString(numWarnings, s"$what warning")
51+
val rerun = if (deprecationSummary) "" else s"; re-run with ${setting.name} for details"
52+
reporter.warning(NoPosition, s"there $warningVerb $warningCount$warningsSince$rerun")
53+
}
54+
if (deprecationSummary) {
55+
val numWarnings = warnings.size
56+
val warningVerb = if (numWarnings == 1) "was" else "were"
57+
val warningCount = countElementsAsString(numWarnings, s"$what warning")
58+
reporter.warning(NoPosition, s"there $warningVerb $warningCount in total; re-run with ${setting.name} for details")
59+
}
4460
}
4561
}
4662

@@ -53,7 +69,7 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
5369
private val _allConditionalWarnings = List(_deprecationWarnings, _uncheckedWarnings, _featureWarnings, _inlinerWarnings)
5470

5571
// TODO: remove in favor of the overload that takes a Symbol, give that argument a default (NoSymbol)
56-
def deprecationWarning(pos: Position, msg: String): Unit = _deprecationWarnings.warn(pos, msg)
72+
def deprecationWarning(pos: Position, msg: String, since: String): Unit = _deprecationWarnings.warn(pos, msg, since)
5773
def uncheckedWarning(pos: Position, msg: String): Unit = _uncheckedWarnings.warn(pos, msg)
5874
def featureWarning(pos: Position, msg: String): Unit = _featureWarnings.warn(pos, msg)
5975
def inlinerWarning(pos: Position, msg: String): Unit = _inlinerWarnings.warn(pos, msg)
@@ -66,10 +82,12 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
6682
def allConditionalWarnings = _allConditionalWarnings flatMap (_.warnings)
6783

6884
// behold! the symbol that caused the deprecation warning (may not be deprecated itself)
69-
def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit = _deprecationWarnings.warn(pos, msg)
85+
def deprecationWarning(pos: Position, sym: Symbol, msg: String, since: String): Unit = _deprecationWarnings.warn(pos, msg, since)
7086
def deprecationWarning(pos: Position, sym: Symbol): Unit = {
71-
val suffix = sym.deprecationMessage match { case Some(msg) => ": "+ msg case _ => "" }
72-
deprecationWarning(pos, sym, s"$sym${sym.locationString} is deprecated$suffix")
87+
val version = sym.deprecationVersion.getOrElse("")
88+
val since = if (version.isEmpty) version else s" (since $version)"
89+
val message = sym.deprecationMessage match { case Some(msg) => s": $msg" case _ => "" }
90+
deprecationWarning(pos, sym, s"$sym${sym.locationString} is deprecated$since$message", version)
7391
}
7492

7593
private[this] var reportedFeature = Set[Symbol]()

src/compiler/scala/tools/nsc/ast/parser/Parsers.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ trait ParsersCommon extends ScannersCommon { self =>
3939
*/
4040
abstract class ParserCommon {
4141
val in: ScannerCommon
42-
def deprecationWarning(off: Offset, msg: String): Unit
42+
def deprecationWarning(off: Offset, msg: String, since: String): Unit
4343
def accept(token: Token): Int
4444

4545
/** Methods inParensOrError and similar take a second argument which, should
@@ -154,7 +154,7 @@ self =>
154154

155155
// suppress warnings; silent abort on errors
156156
def warning(offset: Offset, msg: String): Unit = ()
157-
def deprecationWarning(offset: Offset, msg: String): Unit = ()
157+
def deprecationWarning(offset: Offset, msg: String, since: String): Unit = ()
158158

159159
def syntaxError(offset: Offset, msg: String): Unit = throw new MalformedInput(offset, msg)
160160
def incompleteInputError(msg: String): Unit = throw new MalformedInput(source.content.length - 1, msg)
@@ -206,8 +206,8 @@ self =>
206206
override def warning(offset: Offset, msg: String): Unit =
207207
reporter.warning(o2p(offset), msg)
208208

209-
override def deprecationWarning(offset: Offset, msg: String): Unit =
210-
currentRun.reporting.deprecationWarning(o2p(offset), msg)
209+
override def deprecationWarning(offset: Offset, msg: String, since: String): Unit =
210+
currentRun.reporting.deprecationWarning(o2p(offset), msg, since)
211211

212212
private var smartParsing = false
213213
@inline private def withSmartParsing[T](body: => T): T = {
@@ -1822,7 +1822,7 @@ self =>
18221822
val hasEq = in.token == EQUALS
18231823

18241824
if (hasVal) {
1825-
if (hasEq) deprecationWarning(in.offset, "val keyword in for comprehension is deprecated")
1825+
if (hasEq) deprecationWarning(in.offset, "val keyword in for comprehension is deprecated", "2.10.0")
18261826
else syntaxError(in.offset, "val in for comprehension must be followed by assignment")
18271827
}
18281828

@@ -2358,7 +2358,7 @@ self =>
23582358
while (in.token == VIEWBOUND) {
23592359
val msg = "Use an implicit parameter instead.\nExample: Instead of `def f[A <% Int](a: A)` use `def f[A](a: A)(implicit ev: A => Int)`."
23602360
if (settings.future)
2361-
deprecationWarning(in.offset, s"View bounds are deprecated. $msg")
2361+
deprecationWarning(in.offset, s"View bounds are deprecated. $msg", "2.12.0")
23622362
contextBoundBuf += atPos(in.skipToken())(makeFunctionTypeTree(List(Ident(pname)), typ()))
23632363
}
23642364
while (in.token == COLON) {
@@ -2652,14 +2652,14 @@ self =>
26522652
if (isStatSep || in.token == RBRACE) {
26532653
if (restype.isEmpty) {
26542654
if (settings.future)
2655-
deprecationWarning(in.lastOffset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit`.")
2655+
deprecationWarning(in.lastOffset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit`.", "2.12.0")
26562656
restype = scalaUnitConstr
26572657
}
26582658
newmods |= Flags.DEFERRED
26592659
EmptyTree
26602660
} else if (restype.isEmpty && in.token == LBRACE) {
26612661
if (settings.future)
2662-
deprecationWarning(in.offset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit =`.")
2662+
deprecationWarning(in.offset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit =`.", "2.12.0")
26632663
restype = scalaUnitConstr
26642664
blockExpr()
26652665
} else {
@@ -2921,7 +2921,7 @@ self =>
29212921
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
29222922
copyValDef(vdef)(mods = mods | Flags.PRESUPER)
29232923
case tdef @ TypeDef(mods, name, tparams, rhs) =>
2924-
deprecationWarning(tdef.pos.point, "early type members are deprecated. Move them to the regular body: the semantics are the same.")
2924+
deprecationWarning(tdef.pos.point, "early type members are deprecated. Move them to the regular body: the semantics are the same.", "2.11.0")
29252925
treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs)
29262926
case docdef @ DocDef(comm, rhs) =>
29272927
treeCopy.DocDef(docdef, comm, rhs)

src/compiler/scala/tools/nsc/ast/parser/Scanners.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ trait ScannersCommon {
3535
// things to fill in, in addition to buf, decodeUni which come from CharArrayReader
3636
def error(off: Offset, msg: String): Unit
3737
def incompleteInputError(off: Offset, msg: String): Unit
38-
def deprecationWarning(off: Offset, msg: String): Unit
38+
def deprecationWarning(off: Offset, msg: String, since: String): Unit
3939
}
4040

4141
def createKeywordArray(keywords: Seq[(Name, Token)], defaultToken: Token): (Token, Array[Token]) = {
@@ -208,7 +208,7 @@ trait Scanners extends ScannersCommon {
208208
if (name == nme.MACROkw)
209209
syntaxError(s"$name is now a reserved word; usage as an identifier is disallowed")
210210
else if (emitIdentifierDeprecationWarnings)
211-
deprecationWarning(s"$name is now a reserved word; usage as an identifier is deprecated")
211+
deprecationWarning(s"$name is a reserved word (since 2.10.0); usage as an identifier is deprecated", "2.10.0")
212212
}
213213
}
214214
}
@@ -824,7 +824,7 @@ trait Scanners extends ScannersCommon {
824824
if (settings.future)
825825
syntaxError(start, msg("unsupported"))
826826
else
827-
deprecationWarning(start, msg("deprecated"))
827+
deprecationWarning(start, msg("deprecated"), "2.11.0")
828828
putChar(oct.toChar)
829829
} else {
830830
ch match {
@@ -1034,7 +1034,7 @@ trait Scanners extends ScannersCommon {
10341034
/** generate an error at the current token offset */
10351035
def syntaxError(msg: String): Unit = syntaxError(offset, msg)
10361036

1037-
def deprecationWarning(msg: String): Unit = deprecationWarning(offset, msg)
1037+
def deprecationWarning(msg: String, since: String): Unit = deprecationWarning(offset, msg, since)
10381038

10391039
/** signal an error where the input ended in the middle of a token */
10401040
def incompleteInputError(msg: String): Unit = {
@@ -1204,8 +1204,8 @@ trait Scanners extends ScannersCommon {
12041204
override val decodeUni: Boolean = !settings.nouescape
12051205

12061206
// suppress warnings, throw exception on errors
1207-
def deprecationWarning(off: Offset, msg: String): Unit = ()
1208-
def error (off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
1207+
def deprecationWarning(off: Offset, msg: String, since: String): Unit = ()
1208+
def error(off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
12091209
def incompleteInputError(off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
12101210
}
12111211

@@ -1214,9 +1214,9 @@ trait Scanners extends ScannersCommon {
12141214
class UnitScanner(val unit: CompilationUnit, patches: List[BracePatch]) extends SourceFileScanner(unit.source) {
12151215
def this(unit: CompilationUnit) = this(unit, List())
12161216

1217-
override def deprecationWarning(off: Offset, msg: String) = currentRun.reporting.deprecationWarning(unit.position(off), msg)
1218-
override def error (off: Offset, msg: String) = reporter.error(unit.position(off), msg)
1219-
override def incompleteInputError(off: Offset, msg: String) = currentRun.parsing.incompleteInputError(unit.position(off), msg)
1217+
override def deprecationWarning(off: Offset, msg: String, since: String) = currentRun.reporting.deprecationWarning(unit.position(off), msg, since)
1218+
override def error(off: Offset, msg: String) = reporter.error(unit.position(off), msg)
1219+
override def incompleteInputError(off: Offset, msg: String) = currentRun.parsing.incompleteInputError(unit.position(off), msg)
12201220

12211221
private var bracePatches: List[BracePatch] = patches
12221222

src/compiler/scala/tools/nsc/javac/JavaParsers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
2727
def freshName(prefix: String): Name = freshTermName(prefix)
2828
def freshTermName(prefix: String): TermName = unit.freshTermName(prefix)
2929
def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix)
30-
def deprecationWarning(off: Int, msg: String) = currentRun.reporting.deprecationWarning(off, msg)
30+
def deprecationWarning(off: Int, msg: String, since: String) = currentRun.reporting.deprecationWarning(off, msg, since)
3131
implicit def i2p(offset : Int) : Position = Position.offset(unit.source, offset)
3232
def warning(pos : Int, msg : String) : Unit = reporter.warning(pos, msg)
3333
def syntaxError(pos: Int, msg: String) : Unit = reporter.error(pos, msg)

src/compiler/scala/tools/nsc/javac/JavaScanners.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,9 +860,9 @@ trait JavaScanners extends ast.parser.ScannersCommon {
860860
class JavaUnitScanner(unit: CompilationUnit) extends JavaScanner {
861861
in = new JavaCharArrayReader(unit.source.content, !settings.nouescape.value, syntaxError)
862862
init()
863-
def error (pos: Int, msg: String) = reporter.error(pos, msg)
863+
def error(pos: Int, msg: String) = reporter.error(pos, msg)
864864
def incompleteInputError(pos: Int, msg: String) = currentRun.parsing.incompleteInputError(pos, msg)
865-
def deprecationWarning(pos: Int, msg: String) = currentRun.reporting.deprecationWarning(pos, msg)
865+
def deprecationWarning(pos: Int, msg: String, since: String) = currentRun.reporting.deprecationWarning(pos, msg, since)
866866
implicit def g2p(pos: Int): Position = Position.offset(unit.source, pos)
867867
}
868868
}

src/compiler/scala/tools/nsc/transform/patmat/ScalacPatternExpanders.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ trait ScalacPatternExpanders {
148148
val tupled = extractor.asSinglePattern
149149
if (effectivePatternArity(args) == 1 && isTupleType(extractor.typeOfSinglePattern)) {
150150
val sym = sel.symbol.owner
151-
currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
151+
currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)", "2.11.0")
152152
}
153153
tupled
154154
} else extractor

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ trait Adaptations {
7474
if (settings.future)
7575
context.error(t.pos, adaptWarningMessage("Adaptation of argument list by inserting () has been removed.", showAdaptation = false))
7676
else {
77-
val msg = "Adaptation of argument list by inserting () has been deprecated: " + (
77+
val msg = "Adaptation of argument list by inserting () is deprecated: " + (
7878
if (isLeakyTarget) "leaky (Object-receiving) target makes this especially dangerous."
7979
else "this is unlikely to be what you want.")
80-
context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg))
80+
context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg), "2.11.0")
8181
}
8282
} else if (settings.warnAdaptedArgs)
8383
context.warning(t.pos, adaptWarningMessage(s"Adapting argument list by creating a ${args.size}-tuple: this may not be what you want."))

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -586,8 +586,8 @@ trait Contexts { self: Analyzer =>
586586
}
587587

588588

589-
def deprecationWarning(pos: Position, sym: Symbol, msg: String): Unit =
590-
currentRun.reporting.deprecationWarning(fixPosition(pos), sym, msg)
589+
def deprecationWarning(pos: Position, sym: Symbol, msg: String, since: String): Unit =
590+
currentRun.reporting.deprecationWarning(fixPosition(pos), sym, msg, since)
591591
def deprecationWarning(pos: Position, sym: Symbol): Unit =
592592
currentRun.reporting.deprecationWarning(fixPosition(pos), sym) // TODO: allow this to escalate to an error, and implicit search will ignore deprecated implicits
593593

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,20 +559,22 @@ trait NamesDefaults { self: Analyzer =>
559559
def removeNames(typer: Typer)(args: List[Tree], params: List[Symbol]): (List[Tree], Array[Int]) = {
560560
implicit val context0 = typer.context
561561
def matchesName(param: Symbol, name: Name, argIndex: Int) = {
562-
def warn(w: String) = context0.deprecationWarning(args(argIndex).pos, param, w)
562+
def warn(msg: String, since: String) = context0.deprecationWarning(args(argIndex).pos, param, msg, since)
563563
def checkDeprecation(anonOK: Boolean) =
564564
when (param.deprecatedParamName) {
565565
case Some(`name`) => true
566566
case Some(nme.NO_NAME) => anonOK
567567
}
568+
def version = param.deprecatedParamVersion.getOrElse("")
569+
def since = if (version.isEmpty) version else s" (since $version)"
568570
def checkName = {
569571
val res = param.name == name
570-
if (res && checkDeprecation(true)) warn(s"naming parameter $name has been deprecated.")
572+
if (res && checkDeprecation(true)) warn(s"naming parameter $name is deprecated$since.", version)
571573
res
572574
}
573575
def checkAltName = {
574576
val res = checkDeprecation(false)
575-
if (res) warn(s"the parameter name $name has been deprecated. Use ${param.name} instead.")
577+
if (res) warn(s"the parameter name $name is deprecated$since: use ${param.name} instead", version)
576578
res
577579
}
578580
!param.isSynthetic && (checkName || checkAltName)

0 commit comments

Comments
 (0)