summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-03 08:21:22 +0000
committerPaul Phillips <paulp@improving.org>2011-06-03 08:21:22 +0000
commit6b67a342ab5b9f1630cff1d8b20491fed3c2a5f5 (patch)
treecd8c4ad2589a8284b129b656c21d63af32081ed9
parent33d45626bd1b13adfd36071cf8f4d94123c7d29d (diff)
downloadscala-6b67a342ab5b9f1630cff1d8b20491fed3c2a5f5.tar.gz
scala-6b67a342ab5b9f1630cff1d8b20491fed3c2a5f5.tar.bz2
scala-6b67a342ab5b9f1630cff1d8b20491fed3c2a5f5.zip
More polishing up repl power mode, no review.
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala30
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala11
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Imports.scala7
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala9
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Naming.scala6
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Power.scala100
-rw-r--r--test/files/run/repl-power.check1
7 files changed, 76 insertions, 88 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 75cbf6cdbc..d794845593 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -177,15 +177,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
// When you know you are most likely breaking into the middle
// of a line being typed. This softens the blow.
protected def echoAndRefresh(msg: String) = {
- if (in.currentLine == "") {
- in.eraseLine()
- echo(msg)
- echoNoNL(prompt)
- }
- else {
- echo("\n" + msg)
- in.redrawLine()
- }
+ echo("\n" + msg)
+ in.redrawLine()
}
protected def echo(msg: String) = {
out println msg
@@ -495,8 +488,8 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
)
val replayQuestionMessage =
- """|The repl compiler has crashed spectacularly. Shall I replay your
- |session? I can re-run all lines except the last one.
+ """|That entry seems to have slain the compiler. Shall I replay
+ |your session? I can re-run each line except the last one.
|[y/n]
""".trim.stripMargin
@@ -509,14 +502,12 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
if (isReplDebug) "[searching " + sources.path + " for exception contexts...]"
else "[searching for exception contexts...]"
)
- echo(Exceptional(ex).force().context())
- }
- else {
- echo(util.stackTraceString(ex))
}
+ echo(intp.global.throwableAsString(ex))
+
ex match {
case _: NoSuchMethodError | _: NoClassDefFoundError =>
- echo("Unrecoverable error.")
+ echo("\nUnrecoverable error.")
throw ex
case _ =>
def fn(): Boolean =
@@ -623,12 +614,13 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
def powerCmd(): Result = {
if (isReplPower) "Already in power mode."
- else enablePowerMode()
+ else enablePowerMode(false)
}
- def enablePowerMode() = {
+ def enablePowerMode(isAsync: Boolean) = {
replProps.power setValue true
power.unleash()
- echoAndRefresh(power.banner)
+ if (isAsync) asyncMessage(power.banner)
+ else echo(power.banner)
}
def verbosity() = {
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
index dbd4d77a44..a8fb619f97 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoopInit.scala
@@ -24,12 +24,11 @@ trait ILoopInit {
|Type :help for more information.""" .
stripMargin.format(versionString, javaVmName, javaVersion)
echo(welcomeMsg)
- if (isReplDebug || isReplPower)
- echo("[info] started at " + new java.util.Date)
+ replinfo("[info] started at " + new java.util.Date)
}
- private def asyncMessage(msg: String) {
- if (isReplDebug || isReplPower)
+ protected def asyncMessage(msg: String) {
+ if (isReplInfo || isReplPower)
echoAndRefresh(msg)
}
@@ -95,10 +94,10 @@ trait ILoopInit {
// called once after init condition is signalled
protected def postInitialization() {
addThunk(intp.setContextClassLoader())
+ if (isReplPower)
+ addThunk(enablePowerMode(true))
// do this last to avoid annoying uninterruptible startups
addThunk(installSigIntHandler())
- if (isReplPower)
- addThunk(enablePowerMode())
runThunks()
initIsComplete = true
diff --git a/src/compiler/scala/tools/nsc/interpreter/Imports.scala b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
index df8c1e7851..10e3796404 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Imports.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
@@ -117,12 +117,11 @@ trait Imports {
* 'wanted' is the set of names that need to be imported.
*/
def select(reqs: List[ReqAndHandler], wanted: Set[Name]): List[ReqAndHandler] = {
- val isWanted = wanted contains _
// Single symbol imports might be implicits! See bug #1752. Rather than
// try to finesse this, we will mimic all imports for now.
def keepHandler(handler: MemberHandler) = handler match {
case _: ImportHandler => true
- case x => x.definesImplicit || (x.definedNames exists isWanted)
+ case x => x.definesImplicit || (x.definedNames exists wanted)
}
reqs match {
@@ -160,7 +159,7 @@ trait Imports {
// If the user entered an import, then just use it; add an import wrapping
// level if the import might conflict with some other import
case x: ImportHandler =>
- if (x.importsWildcard || (currentImps exists (x.importedNames contains _)))
+ if (x.importsWildcard || currentImps.exists(x.importedNames contains _))
addWrapper()
code append (x.member + "\n")
@@ -178,7 +177,7 @@ trait Imports {
for (imv <- x.definedNames) {
if (currentImps contains imv) addWrapper()
- code append ("import %s\n" format (req fullPath imv))
+ code append ("import " + (req fullPath imv) + "\n")
currentImps += imv
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
index ed61240542..2e3dc506c6 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
@@ -68,12 +68,11 @@ class JLineReader(_completion: => Completion) extends InteractiveReader {
}
}
- def currentLine: String = consoleReader.getCursorBuffer.buffer.toString
+ def currentLine = consoleReader.getCursorBuffer.buffer.toString
def redrawLine() = consoleReader.redrawLineAndFlush()
- def eraseLine() = {
- // while (consoleReader.delete()) { }
- consoleReader.eraseLine()
- }
+ def eraseLine() = consoleReader.eraseLine()
+ // Alternate implementation, not sure if/when I need this.
+ // def eraseLine() = while (consoleReader.delete()) { }
def readOneLine(prompt: String) = consoleReader readLine prompt
def readOneKey(prompt: String) = consoleReader readOneKey prompt
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/Naming.scala b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
index 14322620b3..89868abfb5 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Naming.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Naming.scala
@@ -75,9 +75,9 @@ trait Naming {
private lazy val userVar = new NameCreator(sessionNames.res) // var name, like res0
private lazy val internalVar = new NameCreator(sessionNames.ires) // internal var name, like $ires0
- def isLineName(name: String) = (name startsWith sessionNames.line) && (name stripPrefix sessionNames.line forall (_.isDigit))
- def isUserVarName(name: String) = userVar didGenerate name
- def isInternalVarName(name: String): Boolean = internalVar didGenerate name
+ def isLineName(name: String) = (name startsWith sessionNames.line) && (name stripPrefix sessionNames.line forall (_.isDigit))
+ def isUserVarName(name: String) = userVar didGenerate name
+ def isInternalVarName(name: String) = internalVar didGenerate name
val freshLineId = {
var x = 0
diff --git a/src/compiler/scala/tools/nsc/interpreter/Power.scala b/src/compiler/scala/tools/nsc/interpreter/Power.scala
index 34b324f0ca..d706cb8245 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Power.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Power.scala
@@ -225,81 +225,81 @@ abstract class Power[G <: Global](
trait LowPriorityPrettifier {
implicit object AnyPrettifier extends Prettifier[Any] {
- def prettify(x: Any): List[String] = x match {
+ def show(x: Any): Unit = prettify(x) foreach println
+ def prettify(x: Any): TraversableOnce[String] = x match {
case x: Name => List(x.decode)
- case Tuple2(k, v) => List(prettify(k) ++ Seq("->") ++ prettify(v) mkString " ")
+ case Tuple2(k, v) => List(prettify(k).toIterator ++ Iterator("->") ++ prettify(v) mkString " ")
case xs: TraversableOnce[_] => (xs.toList flatMap prettify).sorted
- case x => List(rutil.stringOf(x))
+ case x => List(Prettifier.stringOf(x))
}
}
}
+ object StringPrettifier extends Prettifier[String] {
+ def show(x: String) = println(x)
+ def prettify(x: String) = List(Prettifier stringOf x)
+ }
object Prettifier extends LowPriorityPrettifier {
- def prettify[T](value: T): List[String] = default[T] prettify value
+ def stringOf(x: Any): String = scala.runtime.ScalaRunTime.stringOf(x)
+ def prettify[T](value: T): TraversableOnce[String] = default[T] prettify value
def default[T] = new Prettifier[T] {
- def prettify(x: T): List[String] = AnyPrettifier prettify x
+ def prettify(x: T): TraversableOnce[String] = AnyPrettifier prettify x
+ def show(x: T): Unit = AnyPrettifier show x
}
}
trait Prettifier[T] {
- def prettify(x: T): List[String]
-
- private var indentLevel = 0
- private def spaces = " " * indentLevel
- def indented[T](body: => T): T = {
- indentLevel += 1
- try body
- finally indentLevel -= 1
- }
+ def show(x: T): Unit
+ def prettify(x: T): TraversableOnce[String]
- def show(x: T): Unit = grep(x, _ => true)
- def grep(x: T, p: String => Boolean): Unit =
- prettify(x) filter p foreach (x => println(spaces + x))
+ def show(xs: TraversableOnce[T]): Unit = prettify(xs) foreach println
+ def prettify(xs: TraversableOnce[T]): TraversableOnce[String] = xs flatMap (x => prettify(x))
}
- class MultiPrintingConvenience[T: Prettifier](coll: TraversableOnce[T]) {
+
+ abstract class PrettifierClass[T: Prettifier]() {
+ private implicit val ord: Ordering[T] = Ordering[String] on (_.toString)
val pretty = implicitly[Prettifier[T]]
import pretty._
- def freqBy[U](p: T => U) = {
- val map = coll.toList groupBy p
- map.toList sortBy (-_._2.size)
- }
- def freqByFormatted[U](p: T => U) = {
- val buf = new mutable.ListBuffer[String]
+ def value: Seq[T]
- freqBy(p) foreach { case (k, vs) =>
- buf += "%d: %s".format(vs.size, Prettifier.prettify(k))
- vs flatMap prettify foreach (buf += " " + _)
- }
- buf.toList
- }
+ def pp(f: Seq[T] => Seq[T]): Unit =
+ pretty prettify f(value) foreach (StringPrettifier show _)
- /** It makes sense.
- *
- * # means how many
- * ? means "I said, HOW MANY?"
- * > means print
- *
- * Now don't you feel silly for what you were thinking.
- */
- def #?>[U](p: T => U) = this freqByFormatted p foreach println
- def #?[U](p: T => U) = this freqByFormatted p
- }
+ def freq[U](p: T => U) = (value.toSeq groupBy p mapValues (_.size)).toList sortBy (-_._2) map (_.swap)
+ def ppfreq[U](p: T => U): Unit = freq(p) foreach { case (count, key) => println("%5d %s".format(count, key)) }
- class PrintingConvenience[T: Prettifier](value: T) {
- val pretty = implicitly[Prettifier[T]]
+ def |[U](f: Seq[T] => Seq[U]): Seq[U] = f(value)
+ def ^^[U](f: T => U): Seq[U] = value map f
+ def ^?[U](pf: PartialFunction[T, U]): Seq[U] = value collect pf
+
+ def >>!(): Unit = pp(_.sorted.distinct)
+ def >>(): Unit = pp(_.sorted)
+ def >!(): Unit = pp(_.distinct)
+ def >(): Unit = pp(identity)
- def >() { >(_ => true) }
- def >(s: String): Unit = >(_ contains s)
- def >(r: Regex): Unit = >(_ matches r.pattern.toString)
- def >(p: String => Boolean): Unit = pretty.grep(value, p)
+ def >#(): Unit = this ># (identity[T] _)
+ def >#[U](p: T => U): Unit = this ppfreq p
+
+ def >?(p: T => Boolean): Unit = pp(_ filter p)
+ def >?(s: String): Unit = pp(_ filter (_.toString contains s))
+ def >?(r: Regex): Unit = pp(_ filter (_.toString matches r.pattern.toString))
}
+
+ class MultiPrettifierClass[T: Prettifier](val value: Seq[T]) extends PrettifierClass[T]() { }
+ class SinglePrettifierClass[T: Prettifier](single: T) extends PrettifierClass[T]() {
+ val value = List(single)
+ }
+
class RichInputStream(in: InputStream)(implicit codec: Codec) {
def bytes(): Array[Byte] = io.Streamable.bytes(in)
def slurp(): String = io.Streamable.slurp(in)
+ def <(url: URL): String = io.Streamable.slurp(url)
+ def <(): String = slurp()
}
protected trait Implicits1 {
// fallback
- implicit def replPrinting[T](x: T)(implicit pretty: Prettifier[T] = Prettifier.default[T]) = new PrintingConvenience[T](x)
+ implicit def replPrinting[T](x: T)(implicit pretty: Prettifier[T] = Prettifier.default[T]) =
+ new SinglePrettifierClass[T](x)
}
trait Implicits2 extends Implicits1 {
class RichSymbol(sym: Symbol) {
@@ -316,7 +316,8 @@ abstract class Power[G <: Global](
implicit lazy val powerSymbolOrdering: Ordering[Symbol] = Ordering[Name] on (_.name)
implicit lazy val powerTypeOrdering: Ordering[Type] = Ordering[Symbol] on (_.typeSymbol)
- implicit def replCollPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrintingConvenience[T] = new MultiPrintingConvenience[T](xs)
+ implicit def replMultiPrinting[T: Prettifier](xs: TraversableOnce[T]): MultiPrettifierClass[T] =
+ new MultiPrettifierClass[T](xs.toSeq)
implicit def replInternalInfo[T: Manifest](x: T): InternalInfo[T] = new InternalInfo[T](Some(x))
implicit def replPrettifier[T] : Prettifier[T] = Prettifier.default[T]
implicit def replTypeApplication(sym: Symbol): RichSymbol = new RichSymbol(sym)
@@ -346,7 +347,6 @@ abstract class Power[G <: Global](
case (next, rest) => next.map(_.toChar).mkString :: strings(rest)
}
}
- def stringOf(x: Any): String = scala.runtime.ScalaRunTime.stringOf(x)
}
lazy val rutil: ReplUtilities = new ReplUtilities { }
diff --git a/test/files/run/repl-power.check b/test/files/run/repl-power.check
index 249e0f71e8..9561c04eca 100644
--- a/test/files/run/repl-power.check
+++ b/test/files/run/repl-power.check
@@ -9,7 +9,6 @@ scala> :power
** New cmds! :help to discover them **
** New defs! Type power.<tab> to reveal **
-scala>
scala> // guarding against "error: reference to global is ambiguous"
scala> global.emptyValDef // "it is imported twice in the same scope by ..."