aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFelix Mulder <felix.mulder@gmail.com>2016-06-01 19:11:11 +0200
committerFelix Mulder <felix.mulder@gmail.com>2016-06-01 19:11:11 +0200
commit64ba4dfca1bfed077e220a8bfa5ea860150c8fb1 (patch)
tree1ea8360517d7ddef717757a0543e17da793eecd4 /src
parent5838fda0234b224203b1a304a11992e8c7c004c3 (diff)
parentf594b17ac5b7a05cfca3f7b4b1113c063b974327 (diff)
downloaddotty-64ba4dfca1bfed077e220a8bfa5ea860150c8fb1.tar.gz
dotty-64ba4dfca1bfed077e220a8bfa5ea860150c8fb1.tar.bz2
dotty-64ba4dfca1bfed077e220a8bfa5ea860150c8fb1.zip
Merge pull request #1251 from felixmulder/topic/fix-stdoutredirect-repl
Fix stdout redirect for REPL's println
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/config/ScalaSettings.scala1
-rw-r--r--src/dotty/tools/dotc/core/Contexts.scala4
-rw-r--r--src/dotty/tools/dotc/repl/AmmoniteReader.scala6
-rw-r--r--src/dotty/tools/dotc/repl/CompilingInterpreter.scala51
-rw-r--r--src/dotty/tools/dotc/repl/REPL.scala7
5 files changed, 59 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/config/ScalaSettings.scala b/src/dotty/tools/dotc/config/ScalaSettings.scala
index 583778db2..74ff76444 100644
--- a/src/dotty/tools/dotc/config/ScalaSettings.scala
+++ b/src/dotty/tools/dotc/config/ScalaSettings.scala
@@ -28,6 +28,7 @@ class ScalaSettings extends Settings.SettingGroup {
val help = BooleanSetting("-help", "Print a synopsis of standard options")
val nowarn = BooleanSetting("-nowarn", "Generate no warnings.")
val print = BooleanSetting("-print", "Print program with Scala-specific features removed.")
+ val color = ChoiceSetting("-color", "mode", "Colored output", List("always", "never"/*, "auto"*/), "always"/* "auto"*/)
val target = ChoiceSetting("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "jvm-1.8", "msil"),
"jvm-1.8")
diff --git a/src/dotty/tools/dotc/core/Contexts.scala b/src/dotty/tools/dotc/core/Contexts.scala
index 0c916eb4f..262443314 100644
--- a/src/dotty/tools/dotc/core/Contexts.scala
+++ b/src/dotty/tools/dotc/core/Contexts.scala
@@ -377,6 +377,10 @@ object Contexts {
/** Is the verbose option set? */
def verbose: Boolean = base.settings.verbose.value
+ /** Should use colors when printing? */
+ def useColors: Boolean =
+ base.settings.color.value == "always"
+
/** A condensed context containing essential information of this but
* no outer contexts except the initial context.
private var _condensed: CondensedContext = null
diff --git a/src/dotty/tools/dotc/repl/AmmoniteReader.scala b/src/dotty/tools/dotc/repl/AmmoniteReader.scala
index e399105b3..614654a28 100644
--- a/src/dotty/tools/dotc/repl/AmmoniteReader.scala
+++ b/src/dotty/tools/dotc/repl/AmmoniteReader.scala
@@ -57,7 +57,11 @@ class AmmoniteReader(val interpreter: Interpreter)(implicit ctx: Context) extend
writer,
allFilters,
displayTransform = (buffer, cursor) => {
- val ansiBuffer = Ansi.Str.parse(SyntaxHighlighting(buffer))
+ val coloredBuffer =
+ if (ctx.useColors) SyntaxHighlighting(buffer)
+ else buffer
+
+ val ansiBuffer = Ansi.Str.parse(coloredBuffer)
val (newBuffer, cursorOffset) = SelectionFilter.mangleBuffer(
selectionFilter, ansiBuffer, cursor, Ansi.Reversed.On
)
diff --git a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
index b3b7ab13c..7b8ba698a 100644
--- a/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
+++ b/src/dotty/tools/dotc/repl/CompilingInterpreter.scala
@@ -2,7 +2,10 @@ package dotty.tools
package dotc
package repl
-import java.io.{File, PrintWriter, StringWriter, Writer}
+import java.io.{
+ File, PrintWriter, PrintStream, StringWriter, Writer, OutputStream,
+ ByteArrayOutputStream => ByteOutputStream
+}
import java.lang.{Class, ClassLoader}
import java.net.{URL, URLClassLoader}
@@ -24,6 +27,7 @@ import dotty.tools.backend.jvm.GenBCode
import Symbols._, Types._, Contexts._, StdNames._, Names._, NameOps._
import Decorators._
import scala.util.control.NonFatal
+import printing.SyntaxHighlighting
/** An interpreter for Scala code which is based on the `dotc` compiler.
*
@@ -210,11 +214,11 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit
if (!req.compile())
Interpreter.Error // an error happened during compilation, e.g. a type error
else {
- val (interpreterResultString, succeeded) = req.loadAndRun()
+ val (resultStrings, succeeded) = req.loadAndRun()
if (delayOutput)
- previousOutput = clean(interpreterResultString) :: previousOutput
+ previousOutput = resultStrings.map(clean) ::: previousOutput
else if (printResults || !succeeded)
- out.print(clean(interpreterResultString))
+ resultStrings.map(x => out.print(clean(x)))
if (succeeded) {
prevRequests += req
Interpreter.Success
@@ -383,24 +387,53 @@ class CompilingInterpreter(out: PrintWriter, ictx: Context) extends Compiler wit
names1 ++ names2
}
+ /** Sets both System.{out,err} and Console.{out,err} to supplied
+ * `os: OutputStream`
+ */
+ private def withOutput[T](os: ByteOutputStream)(op: ByteOutputStream => T) = {
+ val ps = new PrintStream(os)
+ val oldOut = System.out
+ val oldErr = System.err
+ System.setOut(ps)
+ System.setErr(ps)
+
+ try {
+ Console.withOut(os)(Console.withErr(os)(op(os)))
+ } finally {
+ System.setOut(oldOut)
+ System.setErr(oldErr)
+ }
+ }
+
/** load and run the code using reflection.
- * @return A pair consisting of the run's result as a string, and
+ * @return A pair consisting of the run's result as a `List[String]`, and
* a boolean indicating whether the run succeeded without throwing
* an exception.
*/
- def loadAndRun(): (String, Boolean) = {
+ def loadAndRun(): (List[String], Boolean) = {
val interpreterResultObject: Class[_] =
Class.forName(resultObjectName, true, classLoader)
- val resultValMethod: java.lang.reflect.Method =
+ val valMethodRes: java.lang.reflect.Method =
interpreterResultObject.getMethod("result")
try {
- (resultValMethod.invoke(interpreterResultObject).toString, true)
+ withOutput(new ByteOutputStream) { ps =>
+ val rawRes = valMethodRes.invoke(interpreterResultObject).toString
+ val res =
+ if (ictx.useColors) new String(SyntaxHighlighting(rawRes).toArray)
+ else rawRes
+ val prints = ps.toString("utf-8")
+ val printList = if (prints != "") prints :: Nil else Nil
+
+ if (!delayOutput) out.print(prints)
+
+ (printList :+ res, true)
+ }
} catch {
case NonFatal(ex) =>
def cause(ex: Throwable): Throwable =
if (ex.getCause eq null) ex else cause(ex.getCause)
val orig = cause(ex)
- (stringFrom(str => orig.printStackTrace(str)), false)
+ (stringFrom(str => orig.printStackTrace(str)) :: Nil, false)
}
}
diff --git a/src/dotty/tools/dotc/repl/REPL.scala b/src/dotty/tools/dotc/repl/REPL.scala
index 1f5e3347b..977f67719 100644
--- a/src/dotty/tools/dotc/repl/REPL.scala
+++ b/src/dotty/tools/dotc/repl/REPL.scala
@@ -25,6 +25,11 @@ class REPL extends Driver {
lazy val config = new REPL.Config
+ override def setup(args: Array[String], rootCtx: Context): (List[String], Context) = {
+ val (strs, ctx) = super.setup(args, rootCtx)
+ (strs, config.context(ctx))
+ }
+
override def newCompiler(implicit ctx: Context): Compiler =
new repl.CompilingInterpreter(config.output, ctx)
@@ -45,6 +50,8 @@ object REPL {
val continuationPrompt = " | "
val version = ".next (pre-alpha)"
+ def context(ctx: Context): Context = ctx
+
/** The default input reader */
def input(in: Interpreter)(implicit ctx: Context): InteractiveReader = {
val emacsShell = System.getProperty("env.emacs", "") != ""