summaryrefslogtreecommitdiff
path: root/src/repl
diff options
context:
space:
mode:
authorPrashant Sharma <prashant.s@imaginea.com>2013-09-25 15:27:13 +0530
committerSom Snytt <som.snytt@gmail.com>2013-11-10 23:14:02 -0800
commit1f834cdc9be78c2a6850044a9db24d461b5151ec (patch)
treebfec6675b047a204796b51cdbe814e3a81fd8071 /src/repl
parent7ecfce1fb8d39275f082aaa3ad4dc0eee197391c (diff)
downloadscala-1f834cdc9be78c2a6850044a9db24d461b5151ec.tar.gz
scala-1f834cdc9be78c2a6850044a9db24d461b5151ec.tar.bz2
scala-1f834cdc9be78c2a6850044a9db24d461b5151ec.zip
SI-7747 Support class based wrappers as alternative through switch -Yrepl-class-based
Refactoring to reduce the number of if-else Fix test.
Diffstat (limited to 'src/repl')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala8
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala5
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala52
-rw-r--r--src/repl/scala/tools/nsc/interpreter/Imports.scala24
4 files changed, 75 insertions, 14 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala b/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala
new file mode 100644
index 0000000000..d242a6a0c0
--- /dev/null
+++ b/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala
@@ -0,0 +1,8 @@
+package scala.tools.nsc.interpreter
+
+trait ClassBasedPaths {
+ self: IMain =>
+ override def transformPath(p: String): String = p replaceFirst("read", "read.INSTANCE") replaceAll("iwC", "iw")
+
+ override def readRootPath(readPath: String) = getClassIfDefined(readPath)
+}
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index a96bed4696..4b90128a99 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -119,8 +119,9 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
def createInterpreter() {
if (addedClasspath != "")
settings.classpath append addedClasspath
-
- intp = new ILoopInterpreter
+ if (settings.Yreplclassbased.value)
+ intp = new ILoopInterpreter with ClassBasedPaths
+ else intp = new ILoopInterpreter
}
/** print a friendly help message */
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index e4a3416152..b2d5a0a149 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -81,6 +81,8 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
private var _classLoader: util.AbstractFileClassLoader = null // active classloader
private val _compiler: ReplGlobal = newCompiler(settings, reporter) // our private compiler
+ val classBasedWrappers = settings.Yreplclassbased.value
+
def compilerClasspath: Seq[java.net.URL] = (
if (isInitializeComplete) global.classPath.asURLs
else new PathResolver(settings).result.asURLs // the compiler's classpath
@@ -272,12 +274,14 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
case s => s
} mkString "."
)
+ def transformPath(p: String): String = p
+ def readRootPath(readPath: String) = getModuleIfDefined(readPath)
abstract class PhaseDependentOps {
def shift[T](op: => T): T
def path(name: => Name): String = shift(path(symbolOfName(name)))
- def path(sym: Symbol): String = backticked(shift(sym.fullName))
+ def path(sym: Symbol): String = backticked(transformPath(shift(sym.fullName)))
def sig(sym: Symbol): String = shift(sym.defString)
}
object typerOp extends PhaseDependentOps {
@@ -700,7 +704,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
*
* Read! Eval! Print! Some of that not yet centralized here.
*/
- class ReadEvalPrint(lineId: Int) {
+ class ReadEvalPrint(val lineId: Int) {
def this() = this(freshLineId())
val packageName = sessionNames.line + lineId
@@ -777,7 +781,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
* following accessPath into the outer one.
*/
def resolvePathToSymbol(accessPath: String): Symbol = {
- val readRoot = getModuleIfDefined(readPath) // the outermost wrapper
+ val readRoot = readRootPath(readPath) // the outermost wrapper
(accessPath split '.').foldLeft(readRoot: Symbol) {
case (sym, "") => sym
case (sym, name) => exitingTyper(termMember(sym, name))
@@ -854,7 +858,29 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
/** the line of code to compute */
def toCompute = line
- def fullPath(vname: String) = s"${lineRep.readPath}$accessPath.`$vname`"
+ def fullPath(vname: String) = s"${codeWrapper.fullAccessPath}.`$vname`"
+
+ trait ClassBasedWrappers {
+ self: Wrappers =>
+ override def preambleHeader = "class %s extends Serializable {"
+
+ override def fullAccessPath = s"${lineRep.readPath}.INSTANCE$accessPath"
+
+ override def postamble = importsTrailer + "\n}" + s"""
+ |object ${lineRep.readName} {
+ |val INSTANCE = new ${lineRep.readName}();
+ |}""".stripMargin
+ }
+
+ class Wrappers {
+ def preambleHeader = "object %s {"
+
+ def fullAccessPath = s"${lineRep.readPath}$accessPath"
+
+ def postamble = importsTrailer + "\n}"
+ }
+
+ val codeWrapper = if (!classBasedWrappers) new Wrappers else new Wrappers with ClassBasedWrappers
/** generate the source code for the object that computes this request */
private object ObjectSourceCode extends IMain.CodeAssembler[MemberHandler] {
@@ -863,12 +889,14 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
if (!isReplPower) Nil // power mode only for now
else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees"))
}
-
- val preamble = """
- |object %s {
+ val preamble = s"""
+ |${codeWrapper.preambleHeader}
|%s%s%s
- """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString, importsPreamble, indentCode(toCompute))
- val postamble = importsTrailer + "\n}"
+ """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString,
+ importsPreamble, indentCode(toCompute))
+
+ val postamble = codeWrapper.postamble
+
val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this
}
@@ -890,7 +918,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
| (""
""".stripMargin.format(
lineRep.evalName, evalResult, lineRep.printName,
- executionWrapper, lineRep.readName + accessPath
+ executionWrapper, codeWrapper.fullAccessPath
)
val postamble = """
@@ -1219,7 +1247,7 @@ object IMain {
// $line3.$read.$iw.$iw.Bippy =
// $line3.$read$$iw$$iw$Bippy@4a6a00ca
private def removeLineWrapper(s: String) = s.replaceAll("""\$line\d+[./]\$(read|eval|print)[$.]""", "")
- private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|read|eval|print)[$.]""", "")
+ private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|iwC|read|eval|print)[$.]""", "")
def stripString(s: String) = removeIWPackages(removeLineWrapper(s))
trait CodeAssembler[T] {
@@ -1239,6 +1267,7 @@ object IMain {
def stripImpl(str: String): String
def strip(str: String): String = if (isStripping) stripImpl(str) else str
}
+
trait TruncatingWriter {
def maxStringLength: Int
def isTruncating: Boolean
@@ -1248,6 +1277,7 @@ object IMain {
else str
}
}
+
abstract class StrippingTruncatingWriter(out: JPrintWriter)
extends JPrintWriter(out)
with StrippingWriter
diff --git a/src/repl/scala/tools/nsc/interpreter/Imports.scala b/src/repl/scala/tools/nsc/interpreter/Imports.scala
index ff7bfd432c..c8f9a677b2 100644
--- a/src/repl/scala/tools/nsc/interpreter/Imports.scala
+++ b/src/repl/scala/tools/nsc/interpreter/Imports.scala
@@ -130,13 +130,28 @@ trait Imports {
// add code for a new object to hold some imports
def addWrapper() {
+ if (classBasedWrappers) addClassBasedWrapper()
+ else addObjectBasedWrapper()
+ }
+
+ def addObjectBasedWrapper() {
val impname = nme.INTERPRETER_IMPORT_WRAPPER
code append "object %s {\n".format(impname)
trailingBraces append "}\n"
accessPath append ("." + impname)
currentImps.clear()
}
+
+ def addClassBasedWrapper() {
+ val impname = nme.INTERPRETER_IMPORT_WRAPPER
+ code append "class %sC extends Serializable {\n".format(impname)
+ trailingBraces append "}\nval " + impname + " = new " + impname + "C;\n"
+ accessPath append ("." + impname)
+ currentImps.clear()
+ }
+
def maybeWrap(names: Name*) = if (names exists currentImps) addWrapper()
+
def wrapBeforeAndAfter[T](op: => T): T = {
addWrapper()
try op finally addWrapper()
@@ -163,7 +178,14 @@ trait Imports {
case x =>
for (sym <- x.definedSymbols) {
maybeWrap(sym.name)
- code append s"import ${x.path}\n"
+ if (classBasedWrappers) {
+ if (!code.toString.endsWith(".`" + sym.name + "`;\n")) {
+ val valName = "$VAL" + req.lineRep.lineId
+ code.append("val " + valName + " = " + req.lineRep.readPath + ".INSTANCE;\n")
+ code.append("import " + valName + req.accessPath + ".`" + sym.name + "`;\n")
+ }
+ } else
+ code append s"import ${x.path}\n"
currentImps += sym.name
}
}