From 596b85373b0203e7557f71e1bced980e277ec751 Mon Sep 17 00:00:00 2001 From: Som Snytt Date: Wed, 3 Jul 2013 02:06:25 -0700 Subject: SI-4594 Repl settings command A settings command for the rest of us. The usual command line options are used, except that boolean flags are enabled with +flag and disabled with -flag. ``` scala> :settings +deprecation scala> new BigInt(java.math.BigInteger.TEN) { } :8: warning: inheritance from class BigInt in package math is deprecated: This class will me made final. new BigInt(java.math.BigInteger.TEN) { } ^ res0: BigInt = 10 scala> :settings -deprecation scala> new BigInt(java.math.BigInteger.TEN) { } res1: BigInt = 10 ``` Multivalue "colon" options can be reset by supplying no values after the colon. This behavior is different from the command line. ``` scala> 1 toString warning: there were 1 feature warning(s); re-run with -feature for details res0: String = 1 scala> :settings -language:postfixOps scala> 1 toString res1: String = 1 scala> :settings -d = . -encoding = UTF-8 -explaintypes = false -language = List(postfixOps) -nowarn = false scala> :settings -language: scala> :settings -d = . -encoding = UTF-8 -explaintypes = false -language = List() -nowarn = false ``` --- src/repl/scala/tools/nsc/interpreter/ILoop.scala | 64 ++++++++++++++++++++---- 1 file changed, 54 insertions(+), 10 deletions(-) (limited to 'src/repl') diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala index a84d076e76..e8265e55f4 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -7,22 +7,22 @@ package scala package tools.nsc package interpreter -import Predef.{ println => _, _ } -import java.io.{ BufferedReader, FileReader } -import session._ +import scala.language.{ implicitConversions, existentials } import scala.annotation.tailrec +import Predef.{ println => _, _ } +import interpreter.session._ +import StdReplTags._ import scala.util.Properties.{ jdkHome, javaVersion, versionString, javaVmName } -import util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream } -import io.{ File, Directory } -import util.ScalaClassLoader +import scala.tools.nsc.util.{ ClassPath, Exceptional, stringFromWriter, stringFromStream } +import scala.reflect.classTag +import scala.reflect.internal.util.{ BatchSourceFile, ScalaClassLoader } import ScalaClassLoader._ +import scala.reflect.io.{ File, Directory } import scala.tools.util._ -import scala.language.{implicitConversions, existentials} -import scala.reflect.classTag -import StdReplTags._ +import scala.collection.generic.Clearable import scala.concurrent.{ ExecutionContext, Await, Future, future } import ExecutionContext.Implicits._ -import scala.reflect.internal.util.BatchSourceFile +import java.io.{ BufferedReader, FileReader } /** The Scala interactive shell. It provides a read-eval-print loop * around the Interpreter class. @@ -221,6 +221,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) nullary("replay", "reset execution and replay all previous commands", replay), nullary("reset", "reset the repl to its initial state, forgetting all session entries", resetCommand), shCommand, + cmd("settings", "[+|-]", "+enable/-disable flags, set compiler options", changeSettings), nullary("silent", "disable/enable automatic printing of results", verbosity), cmd("type", "[-v] ", "display the type of an expression without evaluating it", typeCommand), cmd("kind", "[-v] ", "display the kind of expression's type", kindCommand), @@ -300,6 +301,49 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) intp.lastWarnings foreach { case (pos, msg) => intp.reporter.warning(pos, msg) } } + private def changeSettings(args: String): Result = { + def showSettings() = { + for (s <- settings.userSetSettings.toSeq.sorted) echo(s.toString) + } + def updateSettings() = { + // put aside +flag options + val (pluses, rest) = (args split "\\s+").toList partition (_.startsWith("+")) + val tmps = new Settings + val (ok, leftover) = tmps.processArguments(rest, processAll = true) + if (!ok) echo("Bad settings request.") + else if (leftover.nonEmpty) echo("Unprocessed settings.") + else { + // boolean flags set-by-user on tmp copy should be off, not on + val offs = tmps.userSetSettings filter (_.isInstanceOf[Settings#BooleanSetting]) + val (minuses, nonbools) = rest partition (arg => offs exists (_ respondsTo arg)) + // update non-flags + settings.processArguments(nonbools, processAll = true) + // also snag multi-value options for clearing, e.g. -Ylog: and -language: + for { + s <- settings.userSetSettings + if s.isInstanceOf[Settings#MultiStringSetting] || s.isInstanceOf[Settings#PhasesSetting] + if nonbools exists (arg => arg.head == '-' && arg.last == ':' && (s respondsTo arg.init)) + } s match { + case c: Clearable => c.clear() + case _ => + } + def update(bs: Seq[String], name: String=>String, setter: Settings#Setting=>Unit) = { + for (b <- bs) + settings.lookupSetting(name(b)) match { + case Some(s) => + if (s.isInstanceOf[Settings#BooleanSetting]) setter(s) + else echo(s"Not a boolean flag: $b") + case _ => + echo(s"Not an option: $b") + } + } + update(minuses, identity, _.tryToSetFromPropertyValue("false")) // turn off + update(pluses, "-" + _.drop(1), _.tryToSet(Nil)) // turn on + } + } + if (args.isEmpty) showSettings() else updateSettings() + } + private def javapCommand(line: String): Result = { if (javap == null) ":javap unavailable, no tools.jar at %s. Set JDK_HOME.".format(jdkHome) -- cgit v1.2.3