diff options
author | Paul Phillips <paulp@improving.org> | 2012-10-29 12:36:33 -0700 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-10-29 16:39:10 -0700 |
commit | 1841114e6cbb1ab4e3ad6abcd17b0bc9ebef0481 (patch) | |
tree | 95f80c7aa60dfe55ca03691d7bb5289254183a94 /src | |
parent | b480d991072e6e68ed46574d87e4483da778ff0e (diff) | |
download | scala-1841114e6cbb1ab4e3ad6abcd17b0bc9ebef0481.tar.gz scala-1841114e6cbb1ab4e3ad6abcd17b0bc9ebef0481.tar.bz2 scala-1841114e6cbb1ab4e3ad6abcd17b0bc9ebef0481.zip |
An option for real repl output.
There have been many requests to expose the products of
the repl in some way outside in-memory. This does that.
scala # usual in-memory behavior
scala -Yrepl-outdir "" # make up a temp dir
scala -Yrepl-outdir /foo/bar # use /foo/bar
Diffstat (limited to 'src')
3 files changed, 65 insertions, 25 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 92c2fc9768..4e702a09e6 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -30,18 +30,6 @@ import scala.reflect.runtime.{ universe => ru } import scala.reflect.{ ClassTag, classTag } import scala.tools.reflect.StdRuntimeTags._ -/** directory to save .class files to */ -private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory("(memory)", None) { - private def pp(root: AbstractFile, indentLevel: Int) { - val spaces = " " * indentLevel - out.println(spaces + root.name) - if (root.isDirectory) - root.toList sortBy (_.name) foreach (x => pp(x, indentLevel + 1)) - } - // print the contents hierarchically - def show() = pp(this, 0) -} - /** An interpreter for Scala code. * * The main public entry points are compile(), interpret(), and bind(). @@ -77,16 +65,19 @@ private class ReplVirtualDirectory(out: JPrintWriter) extends VirtualDirectory(" class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends Imports { imain => - /** Leading with the eagerly evaluated. - */ - val virtualDirectory: VirtualDirectory = new ReplVirtualDirectory(out) // "directory" for classfiles - private var currentSettings: Settings = initialSettings - private[nsc] var printResults = true // whether to print result lines - private[nsc] var totalSilence = false // whether to print anything - private var _initializeComplete = false // compiler is initialized - private var _isInitialized: Future[Boolean] = null // set up initialization future - private var bindExceptions = true // whether to bind the lastException variable - private var _executionWrapper = "" // code to be wrapped around all lines + object replOutput extends ReplOutput(settings.Yreploutdir) { } + + @deprecated("Use replOutput.dir instead", "2.11.0") + def virtualDirectory = replOutput.dir + def showDirectory = replOutput.show(out) + + private var currentSettings: Settings = initialSettings + private[nsc] var printResults = true // whether to print result lines + private[nsc] var totalSilence = false // whether to print anything + private var _initializeComplete = false // compiler is initialized + private var _isInitialized: Future[Boolean] = null // set up initialization future + private var bindExceptions = true // whether to bind the lastException variable + private var _executionWrapper = "" // code to be wrapped around all lines /** We're going to go to some trouble to initialize the compiler asynchronously. * It's critical that nothing call into it until it's been initialized or we will @@ -258,7 +249,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends /** Instantiate a compiler. Overridable. */ protected def newCompiler(settings: Settings, reporter: Reporter): ReplGlobal = { - settings.outputDirs setSingleOutput virtualDirectory + settings.outputDirs setSingleOutput replOutput.dir settings.exposeEmptyPackage.value = true if (settings.Yrangepos.value) new Global(settings, reporter) with ReplGlobal with interactive.RangePositions @@ -296,7 +287,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends ensureClassLoader() _classLoader } - private class TranslatingClassLoader(parent: ClassLoader) extends AbstractFileClassLoader(virtualDirectory, parent) { + private class TranslatingClassLoader(parent: ClassLoader) extends AbstractFileClassLoader(replOutput.dir, parent) { /** Overridden here to try translating a simple name to the generated * class name if the original attempt fails. This method is used by * getResourceAsStream as well as findClass. @@ -670,7 +661,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends prevRequests.clear() referencedNameMap.clear() definedNameMap.clear() - virtualDirectory.clear() + replOutput.dir.clear() } /** This instance is no longer needed, so release any resources diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplDir.scala b/src/compiler/scala/tools/nsc/interpreter/ReplDir.scala new file mode 100644 index 0000000000..9fbf64acb5 --- /dev/null +++ b/src/compiler/scala/tools/nsc/interpreter/ReplDir.scala @@ -0,0 +1,48 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2012 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import io.VirtualDirectory +import settings.MutableSettings +import scala.reflect.io.{ AbstractFile, PlainDirectory, Directory } +import scala.collection.generic.Clearable + +/** Directory to save .class files to. */ +trait ReplDir extends AbstractFile with Clearable { } + +private class ReplVirtualDir() extends VirtualDirectory("(memory)", None) with ReplDir { } +private class ReplRealDir(dir: Directory) extends PlainDirectory(dir) with ReplDir { + def clear() = { + dir.deleteRecursively() + dir.createDirectory() + } +} + +class ReplOutput(val dirSetting: MutableSettings#StringSetting) { + // outdir for generated classfiles - may be in-memory (the default), + // a generated temporary directory, or a specified outdir. + val dir: ReplDir = ( + if (dirSetting.isDefault) + new ReplVirtualDir() + else if (dirSetting.value == "") + new ReplRealDir(Directory.makeTemp("repl")) + else + new ReplRealDir(Directory(dirSetting.value)) + ) + + // print the contents hierarchically + def show(out: JPrintWriter) = { + def pp(root: AbstractFile, indentLevel: Int) { + val label = root.name + val spaces = " " * indentLevel + out.println(spaces + label) + if (root.isDirectory) + root.toList sortBy (_.name) foreach (x => pp(x, indentLevel + 1)) + } + pp(dir, 0) + } +} diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 404f5e6b6e..80336d9fa3 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -170,6 +170,7 @@ trait ScalaSettings extends AbsScalaSettings val Ybuilderdebug = ChoiceSetting ("-Ybuilder-debug", "manager", "Compile using the specified build manager.", List("none", "refined", "simple"), "none") val Yreifycopypaste = BooleanSetting ("-Yreify-copypaste", "Dump the reified trees in copypasteable representation.") val Yreplsync = BooleanSetting ("-Yrepl-sync", "Do not use asynchronous code for repl startup") + val Yreploutdir = StringSetting ("-Yrepl-outdir", "path", "Write repl-generated classfiles to given output directory (use \"\" to generate a temporary dir)" , "") val Ynotnull = BooleanSetting ("-Ynotnull", "Enable (experimental and incomplete) scala.NotNull.") val YmethodInfer = BooleanSetting ("-Yinfer-argument-types", "Infer types for arguments of overriden methods.") val etaExpandKeepsStar = BooleanSetting ("-Yeta-expand-keeps-star", "Eta-expand varargs methods to T* rather than Seq[T]. This is a temporary option to ease transition.") |