Skip to content

Commit

Permalink
Merge pull request #5076 from soc/topic/deprecations-since
Browse files Browse the repository at this point in the history
Improvements to deprecations related to `since` parameter
  • Loading branch information
lrytz committed May 30, 2016
2 parents 9edbe3d + 85057d5 commit 8f567bc
Show file tree
Hide file tree
Showing 195 changed files with 786 additions and 677 deletions.
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/CompilationUnits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ trait CompilationUnits { global: Global =>
final def warning(pos: Position, msg: String): Unit = reporter.warning(pos, msg)

@deprecated("Call global.currentRun.reporting.deprecationWarning directly instead.", "2.11.2")
final def deprecationWarning(pos: Position, msg: String): Unit = currentRun.reporting.deprecationWarning(pos, msg)
final def deprecationWarning(pos: Position, msg: String, since: String): Unit = currentRun.reporting.deprecationWarning(pos, msg, since)
@deprecated("Call global.currentRun.reporting.uncheckedWarning directly instead.", "2.11.2")
final def uncheckedWarning(pos: Position, msg: String): Unit = currentRun.reporting.uncheckedWarning(pos, msg)

Expand Down
8 changes: 4 additions & 4 deletions src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1054,9 +1054,9 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
var currentUnit: CompilationUnit = NoCompilationUnit

// used in sbt
def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings
def uncheckedWarnings: List[(Position, String)] = reporting.uncheckedWarnings.map{case (pos, (msg, since)) => (pos, msg)}
// used in sbt
def deprecationWarnings: List[(Position, String)] = reporting.deprecationWarnings
def deprecationWarnings: List[(Position, String)] = reporting.deprecationWarnings.map{case (pos, (msg, since)) => (pos, msg)}

private class SyncedCompilationBuffer { self =>
private val underlying = new mutable.ArrayBuffer[CompilationUnit]
Expand Down Expand Up @@ -1267,11 +1267,11 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
private def warnDeprecatedAndConflictingSettings(unit: CompilationUnit) {
// issue warnings for any usage of deprecated settings
settings.userSetSettings filter (_.isDeprecated) foreach { s =>
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get)
currentRun.reporting.deprecationWarning(NoPosition, s.name + " is deprecated: " + s.deprecationMessage.get, "")
}
val supportedTarget = "jvm-1.8"
if (settings.target.value != supportedTarget) {
currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget)
currentRun.reporting.deprecationWarning(NoPosition, settings.target.name + ":" + settings.target.value + " is deprecated and has no effect, setting to " + supportedTarget, "2.12.0")
settings.target.value = supportedTarget
}
settings.conflictWarning.foreach(reporter.warning(NoPosition, _))
Expand Down
42 changes: 30 additions & 12 deletions src/compiler/scala/tools/nsc/Reporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,33 @@ trait Reporting extends scala.reflect.internal.Reporting { self: ast.Positions w
def this(what: String, booleanSetting: Settings#BooleanSetting) {
this(what, () => booleanSetting, booleanSetting)
}
val warnings = mutable.LinkedHashMap[Position, String]()
def warn(pos: Position, msg: String) =
val warnings = mutable.LinkedHashMap[Position, (String, String)]()
def warn(pos: Position, msg: String, since: String = "") =
if (doReport()) reporter.warning(pos, msg)
else if (!(warnings contains pos)) warnings += ((pos, msg))
else if (!(warnings contains pos)) warnings += ((pos, (msg, since)))
def summarize() =
if (warnings.nonEmpty && (setting.isDefault || doReport())) {
val numWarnings = warnings.size
val warningVerb = if (numWarnings == 1) "was" else "were"
val warningCount = countElementsAsString(numWarnings, s"$what warning")

reporter.warning(NoPosition, s"there $warningVerb $warningCount; re-run with ${setting.name} for details")
val sinceAndAmount = mutable.TreeMap[String, Int]()
warnings.valuesIterator.foreach { case (_, since) =>
val value = sinceAndAmount.get(since)
if (value.isDefined) sinceAndAmount += ((since, value.get + 1))
else sinceAndAmount += ((since, 1))
}
val deprecationSummary = sinceAndAmount.size > 1
sinceAndAmount.foreach { case (since, amount) =>
val numWarnings = amount
val warningsSince = if (since.nonEmpty) s" (since $since)" else ""
val warningVerb = if (numWarnings == 1) "was" else "were"
val warningCount = countElementsAsString(numWarnings, s"$what warning")
val rerun = if (deprecationSummary) "" else s"; re-run with ${setting.name} for details"
reporter.warning(NoPosition, s"there $warningVerb $warningCount$warningsSince$rerun")
}
if (deprecationSummary) {
val numWarnings = warnings.size
val warningVerb = if (numWarnings == 1) "was" else "were"
val warningCount = countElementsAsString(numWarnings, s"$what warning")
reporter.warning(NoPosition, s"there $warningVerb $warningCount in total; re-run with ${setting.name} for details")
}
}
}

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

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

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

private[this] var reportedFeature = Set[Symbol]()
Expand Down
18 changes: 9 additions & 9 deletions src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ trait ParsersCommon extends ScannersCommon { self =>
*/
abstract class ParserCommon {
val in: ScannerCommon
def deprecationWarning(off: Offset, msg: String): Unit
def deprecationWarning(off: Offset, msg: String, since: String): Unit
def accept(token: Token): Int

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

// suppress warnings; silent abort on errors
def warning(offset: Offset, msg: String): Unit = ()
def deprecationWarning(offset: Offset, msg: String): Unit = ()
def deprecationWarning(offset: Offset, msg: String, since: String): Unit = ()

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

override def deprecationWarning(offset: Offset, msg: String): Unit =
currentRun.reporting.deprecationWarning(o2p(offset), msg)
override def deprecationWarning(offset: Offset, msg: String, since: String): Unit =
currentRun.reporting.deprecationWarning(o2p(offset), msg, since)

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

if (hasVal) {
if (hasEq) deprecationWarning(in.offset, "val keyword in for comprehension is deprecated")
if (hasEq) deprecationWarning(in.offset, "val keyword in for comprehension is deprecated", "2.10.0")
else syntaxError(in.offset, "val in for comprehension must be followed by assignment")
}

Expand Down Expand Up @@ -2358,7 +2358,7 @@ self =>
while (in.token == VIEWBOUND) {
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)`."
if (settings.future)
deprecationWarning(in.offset, s"View bounds are deprecated. $msg")
deprecationWarning(in.offset, s"View bounds are deprecated. $msg", "2.12.0")
contextBoundBuf += atPos(in.skipToken())(makeFunctionTypeTree(List(Ident(pname)), typ()))
}
while (in.token == COLON) {
Expand Down Expand Up @@ -2652,14 +2652,14 @@ self =>
if (isStatSep || in.token == RBRACE) {
if (restype.isEmpty) {
if (settings.future)
deprecationWarning(in.lastOffset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit`.")
deprecationWarning(in.lastOffset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit`.", "2.12.0")
restype = scalaUnitConstr
}
newmods |= Flags.DEFERRED
EmptyTree
} else if (restype.isEmpty && in.token == LBRACE) {
if (settings.future)
deprecationWarning(in.offset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit =`.")
deprecationWarning(in.offset, s"Procedure syntax is deprecated. Convert procedure `$name` to method by adding `: Unit =`.", "2.12.0")
restype = scalaUnitConstr
blockExpr()
} else {
Expand Down Expand Up @@ -2921,7 +2921,7 @@ self =>
case vdef @ ValDef(mods, _, _, _) if !mods.isDeferred =>
copyValDef(vdef)(mods = mods | Flags.PRESUPER)
case tdef @ TypeDef(mods, name, tparams, rhs) =>
deprecationWarning(tdef.pos.point, "early type members are deprecated. Move them to the regular body: the semantics are the same.")
deprecationWarning(tdef.pos.point, "early type members are deprecated. Move them to the regular body: the semantics are the same.", "2.11.0")
treeCopy.TypeDef(tdef, mods | Flags.PRESUPER, name, tparams, rhs)
case docdef @ DocDef(comm, rhs) =>
treeCopy.DocDef(docdef, comm, rhs)
Expand Down
18 changes: 9 additions & 9 deletions src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ trait ScannersCommon {
// things to fill in, in addition to buf, decodeUni which come from CharArrayReader
def error(off: Offset, msg: String): Unit
def incompleteInputError(off: Offset, msg: String): Unit
def deprecationWarning(off: Offset, msg: String): Unit
def deprecationWarning(off: Offset, msg: String, since: String): Unit
}

def createKeywordArray(keywords: Seq[(Name, Token)], defaultToken: Token): (Token, Array[Token]) = {
Expand Down Expand Up @@ -208,7 +208,7 @@ trait Scanners extends ScannersCommon {
if (name == nme.MACROkw)
syntaxError(s"$name is now a reserved word; usage as an identifier is disallowed")
else if (emitIdentifierDeprecationWarnings)
deprecationWarning(s"$name is now a reserved word; usage as an identifier is deprecated")
deprecationWarning(s"$name is a reserved word (since 2.10.0); usage as an identifier is deprecated", "2.10.0")
}
}
}
Expand Down Expand Up @@ -824,7 +824,7 @@ trait Scanners extends ScannersCommon {
if (settings.future)
syntaxError(start, msg("unsupported"))
else
deprecationWarning(start, msg("deprecated"))
deprecationWarning(start, msg("deprecated"), "2.11.0")
putChar(oct.toChar)
} else {
ch match {
Expand Down Expand Up @@ -1034,7 +1034,7 @@ trait Scanners extends ScannersCommon {
/** generate an error at the current token offset */
def syntaxError(msg: String): Unit = syntaxError(offset, msg)

def deprecationWarning(msg: String): Unit = deprecationWarning(offset, msg)
def deprecationWarning(msg: String, since: String): Unit = deprecationWarning(offset, msg, since)

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

// suppress warnings, throw exception on errors
def deprecationWarning(off: Offset, msg: String): Unit = ()
def error (off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
def deprecationWarning(off: Offset, msg: String, since: String): Unit = ()
def error(off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
def incompleteInputError(off: Offset, msg: String): Unit = throw new MalformedInput(off, msg)
}

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

override def deprecationWarning(off: Offset, msg: String) = currentRun.reporting.deprecationWarning(unit.position(off), msg)
override def error (off: Offset, msg: String) = reporter.error(unit.position(off), msg)
override def incompleteInputError(off: Offset, msg: String) = currentRun.parsing.incompleteInputError(unit.position(off), msg)
override def deprecationWarning(off: Offset, msg: String, since: String) = currentRun.reporting.deprecationWarning(unit.position(off), msg, since)
override def error(off: Offset, msg: String) = reporter.error(unit.position(off), msg)
override def incompleteInputError(off: Offset, msg: String) = currentRun.parsing.incompleteInputError(unit.position(off), msg)

private var bracePatches: List[BracePatch] = patches

Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/javac/JavaParsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def freshName(prefix: String): Name = freshTermName(prefix)
def freshTermName(prefix: String): TermName = unit.freshTermName(prefix)
def freshTypeName(prefix: String): TypeName = unit.freshTypeName(prefix)
def deprecationWarning(off: Int, msg: String) = currentRun.reporting.deprecationWarning(off, msg)
def deprecationWarning(off: Int, msg: String, since: String) = currentRun.reporting.deprecationWarning(off, msg, since)
implicit def i2p(offset : Int) : Position = Position.offset(unit.source, offset)
def warning(pos : Int, msg : String) : Unit = reporter.warning(pos, msg)
def syntaxError(pos: Int, msg: String) : Unit = reporter.error(pos, msg)
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/javac/JavaScanners.scala
Original file line number Diff line number Diff line change
Expand Up @@ -860,9 +860,9 @@ trait JavaScanners extends ast.parser.ScannersCommon {
class JavaUnitScanner(unit: CompilationUnit) extends JavaScanner {
in = new JavaCharArrayReader(unit.source.content, !settings.nouescape.value, syntaxError)
init()
def error (pos: Int, msg: String) = reporter.error(pos, msg)
def error(pos: Int, msg: String) = reporter.error(pos, msg)
def incompleteInputError(pos: Int, msg: String) = currentRun.parsing.incompleteInputError(pos, msg)
def deprecationWarning(pos: Int, msg: String) = currentRun.reporting.deprecationWarning(pos, msg)
def deprecationWarning(pos: Int, msg: String, since: String) = currentRun.reporting.deprecationWarning(pos, msg, since)
implicit def g2p(pos: Int): Position = Position.offset(unit.source, pos)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ trait ScalacPatternExpanders {
val tupled = extractor.asSinglePattern
if (effectivePatternArity(args) == 1 && isTupleType(extractor.typeOfSinglePattern)) {
val sym = sel.symbol.owner
currentRun.reporting.deprecationWarning(sel.pos, sym, s"${sym} expects $productArity patterns$acceptMessage but crushing into $productArity-tuple to fit single pattern (SI-6675)")
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")
}
tupled
} else extractor
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Adaptations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,10 @@ trait Adaptations {
if (settings.future)
context.error(t.pos, adaptWarningMessage("Adaptation of argument list by inserting () has been removed.", showAdaptation = false))
else {
val msg = "Adaptation of argument list by inserting () has been deprecated: " + (
val msg = "Adaptation of argument list by inserting () is deprecated: " + (
if (isLeakyTarget) "leaky (Object-receiving) target makes this especially dangerous."
else "this is unlikely to be what you want.")
context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg))
context.deprecationWarning(t.pos, t.symbol, adaptWarningMessage(msg), "2.11.0")
}
} else if (settings.warnAdaptedArgs)
context.warning(t.pos, adaptWarningMessage(s"Adapting argument list by creating a ${args.size}-tuple: this may not be what you want."))
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/typechecker/Contexts.scala
Original file line number Diff line number Diff line change
Expand Up @@ -586,8 +586,8 @@ trait Contexts { self: Analyzer =>
}


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

Expand Down
8 changes: 5 additions & 3 deletions src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala
Original file line number Diff line number Diff line change
Expand Up @@ -559,20 +559,22 @@ trait NamesDefaults { self: Analyzer =>
def removeNames(typer: Typer)(args: List[Tree], params: List[Symbol]): (List[Tree], Array[Int]) = {
implicit val context0 = typer.context
def matchesName(param: Symbol, name: Name, argIndex: Int) = {
def warn(w: String) = context0.deprecationWarning(args(argIndex).pos, param, w)
def warn(msg: String, since: String) = context0.deprecationWarning(args(argIndex).pos, param, msg, since)
def checkDeprecation(anonOK: Boolean) =
when (param.deprecatedParamName) {
case Some(`name`) => true
case Some(nme.NO_NAME) => anonOK
}
def version = param.deprecatedParamVersion.getOrElse("")
def since = if (version.isEmpty) version else s" (since $version)"
def checkName = {
val res = param.name == name
if (res && checkDeprecation(true)) warn(s"naming parameter $name has been deprecated.")
if (res && checkDeprecation(true)) warn(s"naming parameter $name is deprecated$since.", version)
res
}
def checkAltName = {
val res = checkDeprecation(false)
if (res) warn(s"the parameter name $name has been deprecated. Use ${param.name} instead.")
if (res) warn(s"the parameter name $name is deprecated$since: use ${param.name} instead", version)
res
}
!param.isSynthetic && (checkName || checkAltName)
Expand Down
Loading

0 comments on commit 8f567bc

Please sign in to comment.