Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REPL summarizes warnings #7756

Merged
merged 2 commits into from
Feb 3, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/compiler/scala/tools/nsc/Reporting.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ trait Reporting extends internal.Reporting { self: ast.Positions with Compilatio

def allConditionalWarnings = _allConditionalWarnings flatMap (_.warnings)

// useful in REPL because line parsing doesn't entail a new Run
def clearAllConditionalWarnings() = _allConditionalWarnings.foreach(_.warnings.clear())

// behold! the symbol that caused the deprecation warning (may not be deprecated itself)
def deprecationWarning(pos: Position, sym: Symbol, msg: String, since: String): Unit = _deprecationWarnings.warn(pos, msg, since)
def deprecationWarning(pos: Position, sym: Symbol): Unit = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ class ReplReporterImpl(val config: ShellConfig, val settings: Settings = new Set
withoutTruncating { printMessage(error) }
}


// whether to print anything
var totalSilence: Boolean = false
def suppressOutput[T](operation: => T): T = {
Expand Down
33 changes: 17 additions & 16 deletions src/repl/scala/tools/nsc/interpreter/IMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ package scala.tools.nsc.interpreter
import java.io.{PrintWriter, StringWriter, Closeable}
import java.net.URL

import scala.language.implicitConversions
import scala.annotation.tailrec
import scala.collection.mutable
import scala.collection.mutable.ListBuffer
import scala.language.implicitConversions
import scala.reflect.internal.{FatalError, Flags, MissingRequirementError, NoPhase}
import scala.reflect.runtime.{universe => ru}
import scala.reflect.{ClassTag, classTag}
Expand All @@ -31,12 +32,12 @@ import scala.tools.nsc.reporters.StoreReporter
import scala.tools.nsc.typechecker.{StructuredTypeStrings, TypeStrings}
import scala.reflect.internal.util.ScalaClassLoader.URLClassLoader
import scala.tools.util.PathResolver
import scala.util.{Try => Trying}
import scala.tools.nsc.util.{stackTraceString, stringFromWriter}
import scala.tools.nsc.interpreter.Results.{Error, Incomplete, Result, Success}
import scala.tools.nsc.util.Exceptional.rootCause
import scala.util.{Try => Trying}
import scala.util.chaining._
import scala.util.control.NonFatal
import scala.annotation.tailrec


/** An interpreter for Scala code.
Expand Down Expand Up @@ -423,7 +424,6 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
def compileSourcesKeepingRun(sources: SourceFile*) = {
val run = new Run()
assert(run.typerPhase != NoPhase, "REPL requires a typer phase.")
reporter.reset()
run compileSources sources.toList
(!reporter.hasErrors, run)
}
Expand Down Expand Up @@ -487,10 +487,17 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
}
}

compile(line, synthetic, fatally).fold(identity, loadAndRunReq)
compile(line, synthetic, fatally).fold(identity, loadAndRunReq).tap(res =>
// besides regular errors, clear deprecation and feature warnings
// so they don't leak from last compilation run into next provisional parse
if (res != Incomplete) {
reporter.reset()
currentRun.reporting.clearAllConditionalWarnings()
}
)
}

// create a Request and compile it
// create a Request and compile it if input is complete
def compile(line: String, synthetic: Boolean): Either[Result, Request] = compile(line, synthetic, fatally = false)
def compile(line: String, synthetic: Boolean, fatally: Boolean): Either[Result, Request] =
if (global == null) Left(Error)
Expand Down Expand Up @@ -702,7 +709,6 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
val run = new Run()
assert(run.typerPhase != NoPhase, "REPL requires a typer phase.")

reporter.reset()
run.compileUnits(unit :: Nil)
val success = !reporter.hasErrors

Expand Down Expand Up @@ -786,7 +792,6 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
case _ => Nil
}


/** The path of the value that contains the user code. */
def fullAccessPath = s"${lineRep.readPathInstance}$accessPath"

Expand Down Expand Up @@ -914,8 +919,6 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
/** Compile the object file. Returns whether the compilation succeeded.
* If all goes well, the "types" map is computed. */
def compile: Boolean = {
// error counting is wrong, hence interpreter may overlook failure - so we reset
reporter.reset()

// compile the object containing the user's code
lineRep.compile(mkUnit) && {
Expand Down Expand Up @@ -1125,17 +1128,15 @@ class IMain(val settings: Settings, parentClassLoaderOverride: Option[ClassLoade
var isIncomplete = false
val handler = if (fatally) null else (_: Position, _: String) => isIncomplete = true
currentRun.parsing.withIncompleteHandler(handler) {
reporter.reset()
val unit = newCompilationUnit(line, label)
val trees = newUnitParser(unit).parseStats()
if (reporter.hasErrors) Left(Error)
else if (reporter.hasWarnings && settings.fatalWarnings) {
if (!isIncomplete)
currentRun.reporting.summarizeErrors()
Left(Error)
}
if (reporter.hasErrors) Left(Error)
else if (isIncomplete) Left(Incomplete)
else if (reporter.hasWarnings && settings.fatalWarnings) Left(Error)
else Right((trees, unit.firstXmlPos))
}
}.tap(_ => if (!isIncomplete) reporter.reset())
}

/** Does code start with a package definition? */
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/reify_newimpl_23.check
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.tools.reflect.ToolBox
scala> import scala.tools.reflect.Eval
import scala.tools.reflect.Eval

scala> def foo[T]{
scala> def foo[T] = {
val code = reify {
List[T]()
}
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/reify_newimpl_23.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Test extends ReplTest {
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
import scala.tools.reflect.Eval
def foo[T]{
def foo[T] = {
val code = reify {
List[T]()
}
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/reify_newimpl_26.check
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

scala> def foo[T]{
scala> def foo[T] = {
import scala.reflect.runtime.universe._
val tt = implicitly[WeakTypeTag[List[T]]]
println(tt)
Expand Down
2 changes: 1 addition & 1 deletion test/files/run/reify_newimpl_26.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import scala.tools.partest.ReplTest
object Test extends ReplTest {
override def extraSettings = "-Xlog-free-types"
def code = """
def foo[T]{
def foo[T] = {
import scala.reflect.runtime.universe._
val tt = implicitly[WeakTypeTag[List[T]]]
println(tt)
Expand Down
1 change: 1 addition & 0 deletions test/files/run/repl-paste-2.check
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ res10: Int = 12
// Replaying 8 commands from transcript.

scala> 999l
warning: 1 deprecation (since 2.13.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
val res0: Long = 999

scala> val res5 = { 123 }
Expand Down
12 changes: 12 additions & 0 deletions test/files/run/t11402.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

scala> def f = {
val x = 'abc
val x = 'abc
^
On line 2: warning: symbol literal is deprecated; use Symbol("abc") instead
val y = x.toString
y
}
def f: String

scala> :quit
14 changes: 14 additions & 0 deletions test/files/run/t11402.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

import scala.tools.nsc.Settings
import scala.tools.partest.ReplTest
import scala.util.chaining._

object Test extends ReplTest {
override def transformSettings(ss: Settings) = ss.tap(_.deprecation.value = true)
override def code =
"""|def f = {
| val x = 'abc
| val y = x.toString
| y
|}""".stripMargin
}
1 change: 1 addition & 0 deletions test/files/run/t4710.check
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@

scala> def method : String = { implicit def f(s: Symbol) = "" ; 'symbol }
warning: 1 deprecation (since 2.13.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
warning: 1 feature warning; for details, enable `:setting -feature' or `:replay -feature'
def method: String

Expand Down
2 changes: 2 additions & 0 deletions test/files/run/t6549.check
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ scala> case class `X"`(var xxx: Any)
class X$u0022

scala> val m = Map(("": Any) -> `X"`("\""), ('s: Any) -> `X"`("\""))
warning: 1 deprecation (since 2.13.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
val m: scala.collection.immutable.Map[Any,X"] = Map("" -> X"("), 's -> X"("))

scala> m("")
Expand All @@ -18,6 +19,7 @@ scala> m("").xxx = "\""
// mutated m("").xxx

scala> m('s).xxx = 's
warning: 2 deprecations (since 2.13.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
// mutated m(scala.Symbol("s")).xxx

scala> val `"` = 0
Expand Down