Skip to content

Commit

Permalink
Small improvements to REPL -Yrepl-class-based
Browse files Browse the repository at this point in the history
  - add comments describing a problem I discovered with imports
    and a possible solution
  - Make strip wrappers from REPL output for the wrappers generated in this mode
  • Loading branch information
retronym committed Dec 10, 2019
1 parent eadbb3b commit 9ac3039
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 17 deletions.
7 changes: 3 additions & 4 deletions src/repl/scala/tools/nsc/interpreter/IMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -710,10 +710,9 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
val unwrapped = unwrap(t)

// Example input: $line3.$read$$iw$
val classNameRegex = (naming.lineRegex + ".*").r
def isWrapperInit(x: StackTraceElement) = PartialFunction.cond(x.getClassName) {
case classNameRegex() if x.getMethodName == nme.CONSTRUCTOR.decoded => true
}
val classNameRegex = naming.lineRegex
def isWrapperInit(x: StackTraceElement) =
x.getMethodName == nme.CONSTRUCTOR.decoded && classNameRegex.pattern.matcher(x.getClassName).find()
val stackTrace = unwrapped stackTracePrefixString (!isWrapperInit(_))

withLastExceptionLock[String]({
Expand Down
18 changes: 17 additions & 1 deletion src/repl/scala/tools/nsc/interpreter/Imports.scala
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,22 @@ trait Imports {
// try to finesse this, we will mimic all imports for now.
def keepHandler(handler: MemberHandler) = handler match {
// While defining classes in class based mode - implicits are not needed.
// JZ: Not true! This originated in https://github.com/apache/spark/commit/b63d3b28f0ce4a7eab0b1bc673312bc3e7c396dd
// to fix https://issues.apache.org/jira/browse/SPARK-5150 and https://issues.apache.org/jira/browse/SPARK-2576
// but changes semantics as reported https://issues.apache.org/jira/browse/SPARK-5150 or by running
// run/t6320 in -Yrepl-class-based mode.
//
// Instead, we should remove the special case below, allowing implicits to be imports, but
// prune unused temp vals after typechecking with a custom REPL phase.
//
// scala> class TestClass() { def testMethod = 3 }; val t = new TestClass
// scala> import t.testMethod
// scala> case class TestCaseClass(value: Int)
//
// // Remove this unused val with a post-typer REPL phase.
// val $line4$read: $line4.$read.INSTANCE.type = $line4.$read.INSTANCE;
// import $line4$read.$iw.t;
// import t.testMethod;
case h: ImportHandler if isClassBased && definesClass => h.importedNames.exists(x => wanted.contains(x))
case _: ImportHandler => true
case x if generousImports => x.definesImplicit || (x.definedNames exists (d => wanted.exists(w => d.startsWith(w))))
Expand Down Expand Up @@ -203,7 +219,7 @@ trait Imports {
case _ =>
val valName = s"${req.lineRep.packageName}${req.lineRep.readName}"
if (!tempValLines.contains(req.lineRep.lineId)) {
code.append(s"val $valName: ${objName}.type = $objName\n")
code.append(s"val $valName: ${objName}.type = $objName; ")
tempValLines += req.lineRep.lineId
}
code.append(s"import ${valName}${req.accessPath}.`${sym.name}`\n")
Expand Down
16 changes: 8 additions & 8 deletions src/repl/scala/tools/nsc/interpreter/Naming.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import scala.util.matching.Regex
trait Naming {
def unmangle(str: String): String = {
val ESC = '\u001b'
val cleaned = removeIWPackages(removeLineWrapper(str))
val cleaned = lineRegex.replaceAllIn(str, "")
// Looking to exclude binary data which hoses the terminal, but
// let through the subset of it we need, like whitespace and also
// <ESC> for ansi codes.
Expand All @@ -46,15 +46,14 @@ trait Naming {
//
// $line3.$read.$iw.Bippy =
// $line3.$read$$iw$$Bippy@4a6a00ca
lazy val lineRegex = {
lazy val lineRegex: Regex = {
val sn = sessionNames
val members = List(sn.read, sn.eval, sn.print) map Regex.quote mkString ("(?:", "|", ")")
debugging("lineRegex")(Regex.quote(sn.line) + """\d+[./]""" + members + """[$.]""")
import Regex.{quote => q}
val lineN = q(sn.line) + """\d+"""
val lineNRead = lineN + raw"""(${q(sn.read)})?"""
(raw"""($lineNRead|${q(sn.read)}(\$$${q(sn.iw)})?|${q(sn.eval)}|${q(sn.print)}|${q(sn.iw)})""" + """(\.this\.|\.|/|\$|$)""").r
}

private def removeLineWrapper(s: String) = s.replaceAll(lineRegex, "")
private def removeIWPackages(s: String) = s.replaceAll("""\$iw[$.]""", "")

trait SessionNames {
// All values are configurable by passing e.g. -Dscala.repl.name.read=XXX
final def propOr(name: String): String = propOr(name, "$" + name)
Expand All @@ -63,7 +62,8 @@ trait Naming {

// Prefixes used in repl machinery. Default to $line, $read, etc.
def line = propOr("line")
def read = propOr("read")
def read = "$read"
def iw = "$iw"
def eval = propOr("eval")
def print = propOr("print")
def result = propOr("result")
Expand Down
6 changes: 3 additions & 3 deletions test/files/run/t7185.check
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,21 @@ scala> object O { def apply() = 0 }
defined object O

scala> val ORef = reify { O }.tree
ORef: reflect.runtime.universe.Tree = $read.O
ORef: reflect.runtime.universe.Tree = O

scala> val tree = Apply(Block(Nil, Block(Nil, ORef)), Nil)
tree: reflect.runtime.universe.Apply =
{
{
$read.O
O
}
}()

scala> {val tb = reflect.runtime.currentMirror.mkToolBox(); tb.typecheck(tree): Any}
res0: Any =
{
{
$read.O.apply()
O.apply()
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/files/run/t7747-repl.check
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ scala> 55 ; ((2 + 2)) ; (1, 2, 3)
res15: (Int, Int, Int) = (1,2,3)

scala> 55 ; (x: Int) => x + 1 ; () => ((5))
<console>:13: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
<console>:12: warning: a pure expression does nothing in statement position; multiline expressions may require enclosing parentheses
55 ; (x: Int) => x + 1 ;;
^
res16: () => Int = <function0>
Expand Down

0 comments on commit 9ac3039

Please sign in to comment.