diff options
author | Paul Phillips <paulp@improving.org> | 2011-04-07 17:43:41 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-04-07 17:43:41 +0000 |
commit | caee04079fb8ed40a1458cf24649fad9d80a85c1 (patch) | |
tree | bc8fa7a77760582d91f135dcf72ff15a89ea4984 | |
parent | 42dbce32957e048173c1749697d6bf9273581030 (diff) | |
download | scala-caee04079fb8ed40a1458cf24649fad9d80a85c1.tar.gz scala-caee04079fb8ed40a1458cf24649fad9d80a85c1.tar.bz2 scala-caee04079fb8ed40a1458cf24649fad9d80a85c1.zip |
Made power mode more configurable.
long-term configuration answer, but what I have any chance of doing
before 2.9 ships.
// file to interpret when entering power mode instead of default
-Dscala.repl.power.initcode=/path/to/file // file holding banner to
display instead of default -Dscala.repl.power.banner=/path/to/file
No review.
14 files changed, 71 insertions, 35 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala index 2dadba3b4c..1b2f6443ae 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ByteCode.scala @@ -6,9 +6,7 @@ package scala.tools.nsc package interpreter -import java.io.File import java.lang.reflect -import java.util.jar.{ JarEntry, JarFile } import java.util.concurrent.ConcurrentHashMap import util.ScalaClassLoader import ScalaClassLoader.getSystemLoader diff --git a/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala b/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala index bfa6576b25..2c556656ca 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Dossiers.scala @@ -33,7 +33,7 @@ trait Dossiers { } class TermDossier(val symbol: TermSymbol, val staticType: Type, val value: AnyRef) extends Dossier { - def runtimeClass: Class[_] = value.getClass + def runtimeClass: JClass = value.getClass def runtimeSymbol: Symbol = safeClass(runtimeClass.getName) getOrElse NoSymbol def runtimeType: Type = runtimeSymbol.tpe def runtimeTypeString = TypeStrings.fromClazz(runtimeClass) diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala index 511581b5af..830fad5332 100644 --- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala @@ -52,7 +52,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) // TODO // object opt extends AestheticSettings - + // @deprecated("Use `intp` instead.") def interpreter = intp @@ -532,11 +532,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter) } def powerCmd(): Result = { - if (isReplPower) return "Already in power mode." + if (isReplPower) "Already in power mode." else enablePowerMode() } def enablePowerMode() = { - isReplPower = true + replProps.power setValue true power.unleash() out.println(power.banner) } diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala index 9dbcf37557..4e405de3b2 100644 --- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala +++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala @@ -288,7 +288,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { } } } - private def loadByName(s: String): Class[_] = + private def loadByName(s: String): JClass = (classLoader tryToInitializeClass s) getOrElse sys.error("Failed to load expected class: '" + s + "'") protected def parentClassLoader: ClassLoader = @@ -994,7 +994,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { def valueOfTerm(id: String): Option[AnyRef] = requestForIdent(id) flatMap (_.getEval) - def classOfTerm(id: String): Option[Class[_]] = + def classOfTerm(id: String): Option[JClass] = valueOfTerm(id) map (_.getClass) def typeOfTerm(id: String): Option[Type] = newTermName(id) match { @@ -1004,7 +1004,7 @@ class IMain(val settings: Settings, protected val out: PrintWriter) { def symbolOfTerm(id: String): Symbol = requestForIdent(id) flatMap (_.definedSymbols get newTermName(id)) getOrElse NoSymbol - def runtimeClassAndTypeOfTerm(id: String): Option[(Class[_], Type)] = { + def runtimeClassAndTypeOfTerm(id: String): Option[(JClass, Type)] = { for { clazz <- classOfTerm(id) tpe <- runtimeTypeOfTerm(id) diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala index d9260427b3..d222a80196 100644 --- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala +++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala @@ -6,7 +6,6 @@ package scala.tools.nsc package interpreter -import java.io.File import scala.tools.jline.console.ConsoleReader import scala.tools.jline.console.completer._ import session._ diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala index 5cbf13c298..1d68c14d4a 100644 --- a/src/compiler/scala/tools/nsc/interpreter/Power.scala +++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala @@ -119,7 +119,10 @@ abstract class Power[G <: Global]( def slurp() = apply(modClass) } - def banner = """ + private def customBanner = replProps.powerBanner.option flatMap (f => io.File(f).safeSlurp()) + private def customInit = replProps.powerInitCode.option flatMap (f => io.File(f).safeSlurp()) + + def banner = customBanner getOrElse """ |** Power User mode enabled - BEEP BOOP WHIR ** |** scala.tools.nsc._ has been imported ** |** global._ and definitions._ also imported ** @@ -128,7 +131,7 @@ abstract class Power[G <: Global]( |** New defs! Type power.<tab> to reveal ** """.stripMargin.trim - def init = """ + def init = customInit getOrElse """ |import scala.tools.nsc._ |import scala.collection.JavaConverters._ |import global._ diff --git a/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala new file mode 100644 index 0000000000..a8287e3a9a --- /dev/null +++ b/src/compiler/scala/tools/nsc/interpreter/ReplConfig.scala @@ -0,0 +1,42 @@ +/* NSC -- new Scala compiler + * Copyright 2005-2011 LAMP/EPFL + * @author Paul Phillips + */ + +package scala.tools.nsc +package interpreter + +import sys.{ Prop, BooleanProp } + +trait ReplConfig { + + class ReplProps { + private def bool(name: String) = BooleanProp.keyExists(name) + + val jlineDebug = bool("scala.tools.jline.internal.Log.debug") + val jlineTrace = bool("scala.tools.jline.internal.Log.trace") + + val debug = bool("scala.repl.debug") + val trace = bool("scala.repl.trace") + val power = bool("scala.repl.power") + + val replInitCode = Prop[JFile]("scala.repl.initcode") + val powerInitCode = Prop[JFile]("scala.repl.power.initcode") + val powerBanner = Prop[JFile]("scala.repl.power.banner") + } + lazy val replProps = new ReplProps + + /** Debug output */ + private[nsc] def repldbg(msg: String) = if (isReplDebug) Console println msg + + /** Tracing */ + private[nsc] def tracing[T](msg: String)(x: T): T = { + if (isReplDebug) + println("(" + msg + ") " + x) + + x + } + + def isReplDebug: Boolean = replProps.debug + def isReplPower: Boolean = replProps.power +} diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala index e377a140af..fc286b4868 100644 --- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala +++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala @@ -63,7 +63,7 @@ trait TypeStrings { private def tvarString(tvar: TypeVariable[_]): String = tvarString(tvar.getBounds.toList) private def tvarString(bounds: List[AnyRef]): String = { - val xs = bounds filterNot (_ == ObjectClass) collect { case x: Class[_] => x } + val xs = bounds filterNot (_ == ObjectClass) collect { case x: JClass => x } if (xs.isEmpty) "_" else scalaName(xs.head) } diff --git a/src/compiler/scala/tools/nsc/interpreter/package.scala b/src/compiler/scala/tools/nsc/interpreter/package.scala index 322224ed36..aaf07343cb 100644 --- a/src/compiler/scala/tools/nsc/interpreter/package.scala +++ b/src/compiler/scala/tools/nsc/interpreter/package.scala @@ -22,39 +22,20 @@ package scala.tools.nsc * InteractiveReader contains { history: History, completion: Completion } * IMain contains { global: Global } */ -package object interpreter { +package object interpreter extends ReplConfig { + type JFile = java.io.File type JClass = java.lang.Class[_] type JList[T] = java.util.List[T] type JCollection[T] = java.util.Collection[T] type InputStream = java.io.InputStream type OutputStream = java.io.OutputStream - private[nsc] val JLineDebug = "scala.tools.jline.internal.Log.debug" - private[nsc] val JLineTrace = "scala.tools.jline.internal.Log.trace" - - private[nsc] val DebugProperty = "scala.repl.debug" - private[nsc] val TraceProperty = "scala.repl.trace" - private[nsc] val PowerProperty = "scala.repl.power" - private[nsc] var isReplDebug = sys.props contains DebugProperty // Also set by -Yrepl-debug - private[nsc] var isReplPower = sys.props contains PowerProperty - private[nsc] implicit def enrichClass[T](clazz: Class[T]) = new RichClass[T](clazz) private[interpreter] implicit def javaCharSeqCollectionToScala(xs: JCollection[_ <: CharSequence]): List[String] = { import collection.JavaConverters._ xs.asScala.toList map ("" + _) } - /** Debug output */ - private[nsc] def repldbg(msg: String) = if (isReplDebug) Console println msg - - /** Tracing */ - private[nsc] def tracing[T](msg: String)(x: T): T = { - if (isReplDebug) - println("(" + msg + ") " + x) - - x - } - // Longest common prefix def longestCommonPrefix(xs: List[String]): String = { if (xs.isEmpty || xs.contains("")) "" diff --git a/src/compiler/scala/tools/nsc/io/File.scala b/src/compiler/scala/tools/nsc/io/File.scala index 60d9a0f169..b11151ab7e 100644 --- a/src/compiler/scala/tools/nsc/io/File.scala +++ b/src/compiler/scala/tools/nsc/io/File.scala @@ -137,6 +137,10 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w finally out close } + def safeSlurp(): Option[String] = + try Some(slurp()) + catch { case _: IOException => None } + def copyTo(destPath: Path, preserveFileDate: Boolean = false): Boolean = { val CHUNK = 1024 * 1024 * 16 // 16 MB val dest = destPath.toFile diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala index 2de5ce82ce..a92b5d7034 100644 --- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala +++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala @@ -144,7 +144,7 @@ trait ScalaSettings extends AbsScalaSettings with StandardScalaSettings { val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignments.") val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.") val Yrepldebug = BooleanSetting ("-Yrepl-debug", "Trace all repl activity.") . - withPostSetHook(set => interpreter.isReplDebug = true) + withPostSetHook(_ => interpreter.replProps.debug setValue true) val Ycompletion = BooleanSetting ("-Ycompletion-debug", "Trace all tab completion activity.") val Ydocdebug = BooleanSetting ("-Ydoc-debug", "Trace all scaladoc activity.") val Ypmatnaive = BooleanSetting ("-Ypmat-naive", "Desugar matches as naively as possible.") diff --git a/src/library/scala/sys/BooleanProp.scala b/src/library/scala/sys/BooleanProp.scala index 85719103de..e940990785 100644 --- a/src/library/scala/sys/BooleanProp.scala +++ b/src/library/scala/sys/BooleanProp.scala @@ -46,6 +46,8 @@ object BooleanProp { def setValue[T1 >: Boolean](newValue: T1): Boolean = value def get: String = "" + value val clear, enable, disable, toggle = () + def option = if (isSet) Some(value) else None + protected def zero = false } diff --git a/src/library/scala/sys/Prop.scala b/src/library/scala/sys/Prop.scala index fa866085c0..33b88f119f 100644 --- a/src/library/scala/sys/Prop.scala +++ b/src/library/scala/sys/Prop.scala @@ -53,6 +53,10 @@ trait Prop[+T] { */ def get: String + /** Some(value) if the property is set, None otherwise. + */ + def option: Option[T] + /** Removes the property from the underlying map. */ def clear(): Unit @@ -75,6 +79,7 @@ object Prop { def apply(key: String): Prop[T] } + implicit object FileProp extends CreatorImpl[java.io.File](s => new java.io.File(s)) implicit object StringProp extends CreatorImpl[String](s => s) implicit object IntProp extends CreatorImpl[Int](_.toInt) implicit object DoubleProp extends CreatorImpl[Double](_.toDouble) diff --git a/src/library/scala/sys/PropImpl.scala b/src/library/scala/sys/PropImpl.scala index 888e9d7327..b84553ea22 100644 --- a/src/library/scala/sys/PropImpl.scala +++ b/src/library/scala/sys/PropImpl.scala @@ -31,6 +31,8 @@ private[sys] class PropImpl[+T](val key: String, valueFn: String => T) extends P else "" def clear(): Unit = underlying -= key + def option: Option[T] = if (isSet) Some(value) else None + def or[T1 >: T](alt: => T1): T1 = if (isSet) value else alt /** The underlying property map, in our case always sys.props */ protected def underlying: mutable.Map[String, String] = scala.sys.props |