diff options
Diffstat (limited to 'src/repl')
4 files changed, 55 insertions, 74 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala b/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala deleted file mode 100644 index d242a6a0c0..0000000000 --- a/src/repl/scala/tools/nsc/interpreter/ClassBasedPaths.scala +++ /dev/null @@ -1,8 +0,0 @@ -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 4b90128a99..a96bed4696 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -119,9 +119,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) def createInterpreter() { if (addedClasspath != "") settings.classpath append addedClasspath - if (settings.Yreplclassbased.value) - intp = new ILoopInterpreter with ClassBasedPaths - else intp = new ILoopInterpreter + + 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 b2d5a0a149..0d55423247 100644 --- a/src/repl/scala/tools/nsc/interpreter/IMain.scala +++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala @@ -81,8 +81,6 @@ 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 @@ -274,14 +272,13 @@ 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(transformPath(shift(sym.fullName))) + def path(sym: Symbol): String = backticked(shift(sym.fullName)) def sig(sym: Symbol): String = shift(sym.defString) } object typerOp extends PhaseDependentOps { @@ -852,54 +849,69 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set /** Code to import bound names from previous lines - accessPath is code to * append to objectName to access anything bound by request. */ - val ComputedImports(importsPreamble, importsTrailer, accessPath) = - exitingTyper(importsCode(referencedNames.toSet)) + lazy val ComputedImports(importsPreamble, importsTrailer, accessPath) = + exitingTyper(importsCode(referencedNames.toSet, ObjectSourceCode)) /** the line of code to compute */ def toCompute = line - 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 {" + /** The path of the value that contains the user code. */ + def fullAccessPath = s"${lineRep.readPath}$accessPath" - def fullAccessPath = s"${lineRep.readPath}$accessPath" - - def postamble = importsTrailer + "\n}" - } - - val codeWrapper = if (!classBasedWrappers) new Wrappers else new Wrappers with ClassBasedWrappers + /** The path of the given member of the wrapping instance. */ + def fullPath(vname: String) = s"$fullAccessPath.`$vname`" /** generate the source code for the object that computes this request */ - private object ObjectSourceCode extends IMain.CodeAssembler[MemberHandler] { + abstract class Wrapper extends IMain.CodeAssembler[MemberHandler] { def path = originalPath("$intp") def envLines = { if (!isReplPower) Nil // power mode only for now else List("def %s = %s".format("$line", tquoted(originalLine)), "def %s = Nil".format("$trees")) } - val preamble = s""" - |${codeWrapper.preambleHeader} + def preamble = s""" + |$preambleHeader |%s%s%s """.stripMargin.format(lineRep.readName, envLines.map(" " + _ + ";\n").mkString, importsPreamble, indentCode(toCompute)) - val postamble = codeWrapper.postamble - val generate = (m: MemberHandler) => m extraCodeToEvaluate Request.this + + /** A format string with %s for $read, specifying the wrapper definition. */ + def preambleHeader: String + + /** Like preambleHeader for an import wrapper. */ + def prewrap: String = preambleHeader + "\n" + + /** Like postamble for an import wrapper. */ + def postwrap: String } + private class ObjectBasedWrapper extends Wrapper { + def preambleHeader = "object %s {" + + def postamble = importsTrailer + "\n}" + + def postwrap = "}\n" + } + + private class ClassBasedWrapper extends Wrapper { + def preambleHeader = "class %s extends Serializable {" + + /** Adds an object that instantiates the outer wrapping class. */ + def postamble = s"""$importsTrailer + |} + |object ${lineRep.readName} extends ${lineRep.readName} + |""".stripMargin + + import nme.{ INTERPRETER_IMPORT_WRAPPER => iw } + + /** Adds a val that instantiates the wrapping class. */ + def postwrap = s"}\nval $iw = new $iw\n" + } + + private lazy val ObjectSourceCode: Wrapper = + if (settings.Yreplclassbased) new ClassBasedWrapper else new ObjectBasedWrapper + private object ResultObjectSourceCode extends IMain.CodeAssembler[MemberHandler] { /** We only want to generate this code when the result * is a value which can be referred to as-is. @@ -918,7 +930,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set | ("" """.stripMargin.format( lineRep.evalName, evalResult, lineRep.printName, - executionWrapper, codeWrapper.fullAccessPath + executionWrapper, fullAccessPath ) val postamble = """ @@ -1247,7 +1259,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|iwC|read|eval|print)[$.]""", "") + private def removeIWPackages(s: String) = s.replaceAll("""\$(iw|read|eval|print)[$.]""", "") def stripString(s: String) = removeIWPackages(removeLineWrapper(s)) trait CodeAssembler[T] { @@ -1267,7 +1279,6 @@ 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 @@ -1277,7 +1288,6 @@ 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 c8f9a677b2..5244858a62 100644 --- a/src/repl/scala/tools/nsc/interpreter/Imports.scala +++ b/src/repl/scala/tools/nsc/interpreter/Imports.scala @@ -92,7 +92,7 @@ trait Imports { * last one imported is actually usable. */ case class ComputedImports(prepend: String, append: String, access: String) - protected def importsCode(wanted: Set[Name]): ComputedImports = { + protected def importsCode(wanted: Set[Name], wrapper: Request#Wrapper): ComputedImports = { /** Narrow down the list of requests from which imports * should be taken. Removes requests which cannot contribute * useful imports for the specified set of wanted names. @@ -130,23 +130,10 @@ 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) + import nme.{ INTERPRETER_IMPORT_WRAPPER => iw } + code append (wrapper.prewrap format iw) + trailingBraces append wrapper.postwrap + accessPath append s".$iw" currentImps.clear() } @@ -178,14 +165,7 @@ trait Imports { case x => for (sym <- x.definedSymbols) { maybeWrap(sym.name) - 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" + code append s"import ${x.path}\n" currentImps += sym.name } } |