summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Completion.scala31
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/History.scala15
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/ILoop.scala40
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala1
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala33
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala58
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineHistory.scala56
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/JLineReader.scala77
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala20
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala57
10 files changed, 222 insertions, 166 deletions
diff --git a/src/compiler/scala/tools/nsc/interpreter/Completion.scala b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
index 3436c6631e..79f0317533 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Completion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Completion.scala
@@ -7,30 +7,37 @@ package scala.tools.nsc
package interpreter
import java.util.{ List => JList }
+import Completion._
/** An implementation-agnostic completion interface which makes no
* reference to the jline classes.
*/
trait Completion {
type ExecResult
- trait Instance {
- def complete(buffer: String, cursor: Int, candidates: JList[CharSequence]): Int
- }
def resetVerbosity(): Unit
def execute(line: String): Option[ExecResult]
- def completer(): Instance
+ def completer(): ScalaCompleter
+}
+object NoCompletion extends Completion {
+ type ExecResult = Nothing
+ def resetVerbosity() = ()
+ def execute(line: String) = None
+ def completer() = NullCompleter
}
object Completion {
- object Empty extends Completion {
- type ExecResult = Nothing
- object NullCompleter extends Instance {
- def complete(buffer: String, cursor: Int, candidates: JList[CharSequence]) = -1
- }
- def resetVerbosity() = ()
- def execute(line: String) = None
- def completer() = NullCompleter
+ def empty: Completion = NoCompletion
+
+ case class Candidates(cursor: Int, candidates: List[String]) { }
+ val NoCandidates = Candidates(-1, Nil)
+
+ object NullCompleter extends ScalaCompleter {
+ def complete(buffer: String, cursor: Int): Candidates = NoCandidates
+ }
+ trait ScalaCompleter {
+ def complete(buffer: String, cursor: Int): Candidates
}
+
def looksLikeInvocation(code: String) = (
(code != null)
&& (code startsWith ".")
diff --git a/src/compiler/scala/tools/nsc/interpreter/History.scala b/src/compiler/scala/tools/nsc/interpreter/History.scala
index e0364b5c6e..246cea12dd 100644
--- a/src/compiler/scala/tools/nsc/interpreter/History.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/History.scala
@@ -16,13 +16,14 @@ trait History {
def grep(s: String): List[String]
def flush(): Unit
}
+object NoHistory extends History {
+ def asStrings = Nil
+ def grep(s: String) = Nil
+ def index = 0
+ def size = 0
+ def flush() = ()
+}
object History {
- object Empty extends History {
- def asStrings = Nil
- def grep(s: String) = Nil
- def index = 0
- def size = 0
- def flush() = ()
- }
+ def empty: History = NoHistory
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
index 413f08dfb1..5c57e70927 100644
--- a/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/ILoop.scala
@@ -154,7 +154,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
/** Show the history */
def printHistory(xs: List[String]): Result = {
- if (in.history eq History.Empty)
+ if (in.history eq NoHistory)
return "No history available."
val defaultLines = 20
@@ -273,7 +273,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
val oldReplay = replayCommandStack
try file applyReader { reader =>
- in = new SimpleReader(reader, out, false)
+ in = SimpleReader(reader, out, false)
plushln("Loading " + file + "...")
loop()
}
@@ -530,29 +530,39 @@ class ILoop(in0: Option[BufferedReader], protected val out: PrintWriter)
case _ =>
}
+ /** Tries to create a JLineReader, falling back to SimpleReader:
+ * unless settings or properties are such that it should start
+ * with SimpleReader.
+ */
+ def chooseReader(settings: Settings): InteractiveReader = {
+ if (settings.Xnojline.value || Properties.isEmacsShell)
+ SimpleReader()
+ else try JLineReader(
+ if (settings.noCompletion.value) NoCompletion
+ else new JLineCompletion(intp)
+ )
+ catch {
+ case _: Exception | _: NoClassDefFoundError => SimpleReader()
+ }
+ }
+
def process(settings: Settings): Boolean = {
this.settings = settings
createInterpreter()
// sets in to some kind of reader depending on environmental cues
in = in0 match {
- case Some(in0) => new SimpleReader(in0, out, true)
- case None =>
- // the interpreter is passed as an argument to expose tab completion info
- if (settings.Xnojline.value || Properties.isEmacsShell) new SimpleReader
- else JLineReader(
- if (settings.noCompletion.value) Completion.Empty
- else new JLineCompletion(intp)
- )
+ case Some(reader) => SimpleReader(reader, out, true)
+ case None => chooseReader(settings)
}
loadFiles(settings)
- try {
- // it is broken on startup; go ahead and exit
- if (intp.reporter.hasErrors) return false
-
- printWelcome()
+ // it is broken on startup; go ahead and exit
+ if (intp.reporter.hasErrors)
+ return false
+ printWelcome()
+ try {
// this is about the illusion of snappiness. We call initialize()
// which spins off a separate thread, then print the prompt and try
// our best to look ready. Ideally the user will spend a
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 84189cddad..794e6c158a 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -91,7 +91,6 @@ class IMain(val settings: Settings, out: PrintWriter) {
out.flush()
}
-
/** directory to save .class files to */
val virtualDirectory = new VirtualDirectory("(memory)", None)
diff --git a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
index e7ef50ddf7..1a67cc647d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/InteractiveReader.scala
@@ -10,38 +10,35 @@ import java.io.IOException
import java.nio.channels.ClosedByInterruptException
import scala.util.control.Exception._
import InteractiveReader._
+import Properties.isMac
/** Reads lines from an input stream */
trait InteractiveReader {
val interactive: Boolean
- protected def readOneLine(prompt: String): String
def history: History
def completion: Completion
+
def init(): Unit
def reset(): Unit
- def redrawLine(): Unit = ()
- def currentLine = "" // the current buffer contents, if available
-
- def readLine(prompt: String): String = {
- def handler: Catcher[String] = {
- case e: ClosedByInterruptException => sys.error("Reader closed by interrupt.")
- // Terminal has to be re-initialized after SIGSTP or up arrow etc. stop working.
- case e: IOException if restartSystemCall(e) => reset() ; readLine(prompt)
- }
- catching(handler) { readOneLine(prompt) }
- }
+ protected def readOneLine(prompt: String): String
+ def redrawLine(): Unit
+ def currentLine: String
- // hack necessary for OSX jvm suspension because read calls are not restarted after SIGTSTP
- private def restartSystemCall(e: Exception): Boolean =
- Properties.isMac && (e.getMessage == msgEINTR)
+ def readLine(prompt: String): String =
+ // hack necessary for OSX jvm suspension because read calls are not restarted after SIGTSTP
+ if (isMac) restartSysCalls(readOneLine(prompt), reset())
+ else readOneLine(prompt)
}
object InteractiveReader {
val msgEINTR = "Interrupted system call"
- def apply(): InteractiveReader = new SimpleReader
+ def restartSysCalls[R](body: => R, reset: => Unit): R =
+ try body catch {
+ case e: IOException if e.getMessage == msgEINTR => reset ; body
+ }
- // @deprecated("Use `apply` instead") def createDefault(intp: IMain): InteractiveReader = apply(intp)
- // @deprecated("Use `apply` instead") def createDefault(comp: Completion): InteractiveReader = apply(comp)
+ def apply(): InteractiveReader = SimpleReader()
}
+
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
index 3f2003a2f7..148b80df12 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -264,7 +264,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
def completions(buf: String): List[String] =
topLevelFor(Parsed.dotted(buf + ".", buf.length + 1))
- def completer() = new JLineCompleterClass
+ def completer(): ScalaCompleter = new JLineTabCompletion
/** This gets a little bit hairy. It's no small feat delegating everything
* and also keeping track of exactly where the cursor is and where it's supposed
@@ -272,7 +272,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
* string in the list of completions, that means we are expanding a unique
* completion, so don't update the "last" buffer because it'll be wrong.
*/
- class JLineCompleterClass extends Instance with Completer {
+ class JLineTabCompletion extends ScalaCompleter {
// For recording the buffer on the last tab hit
private var lastBuf: String = ""
private var lastCursor: Int = -1
@@ -281,35 +281,43 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
def isConsecutiveTabs(buf: String, cursor: Int) =
cursor == lastCursor && buf == lastBuf
+ def sameHead(xs: List[String]) = {
+ if (xs.isEmpty || xs.head.length == 0) false
+ else {
+ val y :: ys = xs
+ val ch = y.head
+ ys forall (s => s.length > 0 && s.head == ch)
+ }
+ }
// Longest common prefix
- def commonPrefix(xs: List[String]) =
- if (xs.isEmpty) ""
- else xs.reduceLeft(_ zip _ takeWhile (x => x._1 == x._2) map (_._1) mkString)
+ def commonPrefix(xs: List[String]): String = {
+ if (sameHead(xs)) xs.head + commonPrefix(xs map (_.tail))
+ else ""
+ }
// This is jline's entry point for completion.
- override def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
- val buf = if (_buf == null) "" else _buf
+ override def complete(buf: String, cursor: Int): Candidates = {
verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0
DBG("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity))
// we don't try lower priority completions unless higher ones return no results.
- def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Int] = {
+ def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = {
completionFunction(p) match {
case Nil => None
case xs =>
- // modify in place and return the position
- xs foreach (candidates add _)
-
- // update the last buffer unless this is an alternatives list
- if (xs contains "") Some(p.cursor)
- else {
- val advance = commonPrefix(xs)
- lastCursor = p.position + advance.length
- lastBuf = (buf take p.position) + advance
-
- DBG("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(p, lastBuf, lastCursor, p.position))
- Some(p.position)
- }
+ Some(Candidates(
+ if (xs contains "") p.cursor
+ else {
+ // update the last buffer unless this is an alternatives list
+ val advance = commonPrefix(xs)
+ lastCursor = p.position + advance.length
+ lastBuf = (buf take p.position) + advance
+ DBG("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(
+ p, lastBuf, lastCursor, p.position))
+ p.position
+ },
+ xs)
+ )
}
}
@@ -332,14 +340,12 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
* compiler still throws some Errors it may not be.
*/
try {
- (lastResultCompletion orElse regularCompletion orElse fileCompletion) getOrElse cursor
+ (lastResultCompletion orElse regularCompletion orElse fileCompletion) getOrElse Candidates(cursor, Nil)
}
catch {
case ex: Exception =>
- DBG("Error: complete(%s, %s, _) provoked %s".format(_buf, cursor, ex))
- candidates add " "
- candidates add "<completion error>"
- cursor
+ DBG("Error: complete(%s, %s) provoked %s".format(buf, cursor, ex))
+ Candidates(cursor, List(" ", "<completion error>"))
}
}
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineHistory.scala b/src/compiler/scala/tools/nsc/interpreter/JLineHistory.scala
new file mode 100644
index 0000000000..e9be7141f1
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineHistory.scala
@@ -0,0 +1,56 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2011 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package interpreter
+
+import java.io.File
+import java.util.{ List => JList }
+import scala.tools.jline.console.ConsoleReader
+import scala.tools.jline.console.completer._
+import scala.tools.jline.console.history._
+import scala.tools.jline.console.history.{ FileHistory, PersistentHistory, History => JHistory }
+import scala.tools.jline.console.history.History.{ Entry => JEntry }
+import scala.tools.jline.console.ConsoleReader
+import scala.collection.JavaConverters._
+import Properties.userHome
+
+/** A wrapper for JLine's History.
+ */
+class JLineHistory(val jhistory: JHistory) extends History {
+ def asJavaList = jhistory.entries()
+ def asStrings = asList map (_.value.toString)
+ def asList: List[JEntry] = asJavaList.asScala.toList
+ def index = jhistory.index()
+ def size = jhistory.size()
+
+ def grep(s: String) = asStrings filter (_ contains s)
+ def flush() = jhistory match {
+ case x: PersistentHistory => x.flush()
+ case _ => ()
+ }
+}
+
+object JLineHistory {
+ val ScalaHistoryFile = ".scala_history"
+
+ def apply() = new JLineHistory(
+ try newFile()
+ catch { case x : Exception =>
+ Console.println("Error creating file history: memory history only. " + x)
+ newMemory()
+ }
+ )
+
+ def newMemory() = new MemoryHistory()
+ def newFile() = new FileHistory(new File(userHome, ScalaHistoryFile)) {
+ // flush after every add to avoid installing a shutdown hook.
+ // (The shutdown hook approach also loses history when they aren't run.)
+ override def add(item: CharSequence): Unit = {
+ super.add(item)
+ flush()
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
index d09567eadf..7652e6646b 100644
--- a/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/JLineReader.scala
@@ -16,65 +16,27 @@ import scala.tools.jline.console.history.History.{ Entry => JEntry }
import scala.tools.jline.console.ConsoleReader
import scala.collection.JavaConverters._
import Properties.userHome
-
-/** A wrapper for JLine's History.
- */
-class JLineHistory(val jhistory: JHistory) extends History {
- def asJavaList = jhistory.entries()
- def asStrings = asList map (_.value.toString)
- def asList: List[JEntry] = asJavaList.asScala.toList
- def index = jhistory.index()
- def size = jhistory.size()
-
- def grep(s: String) = asStrings filter (_ contains s)
- def flush() = jhistory match {
- case x: PersistentHistory => x.flush()
- case _ => ()
- }
-}
-
-object JLineHistory {
- val ScalaHistoryFile = ".scala_history"
-
- def apply() = new JLineHistory(
- try newFile()
- catch { case x : Exception =>
- Console.println("Error creating file history: memory history only. " + x)
- newMemory()
- }
- )
-
- def newMemory() = new MemoryHistory()
- def newFile() = new FileHistory(new File(userHome, ScalaHistoryFile)) {
- // flush after every add to avoid installing a shutdown hook.
- // (The shutdown hook approach also loses history when they aren't run.)
- override def add(item: CharSequence): Unit = {
- super.add(item)
- flush()
- }
- }
-}
+import Completion._
/** Reads from the console using JLine */
class JLineReader(val completion: Completion) extends InteractiveReader {
+ val interactive = true
lazy val history = JLineHistory()
def reset() = consoleReader.getTerminal().reset()
def init() = consoleReader.getTerminal().init()
- override def redrawLine() = {
- consoleReader.flush()
- consoleReader.drawLine()
- consoleReader.flush()
+ def scalaToJline(tc: ScalaCompleter): Completer = new Completer {
+ def complete(_buf: String, cursor: Int, candidates: JList[CharSequence]): Int = {
+ val buf = if (_buf == null) "" else _buf
+ val Candidates(newCursor, newCandidates) = tc.complete(buf, cursor)
+ newCandidates foreach (candidates add _)
+ newCursor
+ }
}
def argCompletor: ArgumentCompleter = {
- val wrapped = new Completer {
- val cc = completion.completer()
- def complete(buffer: String, cursor: Int, candidates: JList[CharSequence]): Int =
- cc.complete(buffer, cursor, candidates)
- }
- val c = new ArgumentCompleter(new JLineDelimiter, wrapped)
+ val c = new ArgumentCompleter(new JLineDelimiter, scalaToJline(completion.completer()))
c setStrict false
c
}
@@ -82,10 +44,10 @@ class JLineReader(val completion: Completion) extends InteractiveReader {
val consoleReader = {
val r = new ConsoleReader()
r setBellEnabled false
- if (history ne History.Empty)
+ if (history ne NoHistory)
r setHistory history.jhistory
- if (completion ne Completion.Empty) {
+ if (completion ne NoCompletion) {
r addCompleter argCompletor
r setAutoprintThreshold 400 // max completion candidates without warning
}
@@ -93,15 +55,16 @@ class JLineReader(val completion: Completion) extends InteractiveReader {
r
}
- override def currentLine: String = consoleReader.getCursorBuffer.buffer.toString
+ def currentLine: String = consoleReader.getCursorBuffer.buffer.toString
+ def redrawLine() = {
+ consoleReader.flush()
+ consoleReader.drawLine()
+ consoleReader.flush()
+ }
def readOneLine(prompt: String) = consoleReader readLine prompt
- val interactive = true
}
object JLineReader {
- def apply(intp: IMain): InteractiveReader = apply(new JLineCompletion(intp))
- def apply(comp: Completion): InteractiveReader = {
- try new JLineReader(comp)
- catch { case e @ (_: Exception | _: NoClassDefFoundError) => new SimpleReader }
- }
+ def apply(intp: IMain): JLineReader = apply(new JLineCompletion(intp))
+ def apply(comp: Completion): JLineReader = new JLineReader(comp)
}
diff --git a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
index e4c0bf8307..079fa4b9fb 100644
--- a/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/SimpleReader.scala
@@ -13,15 +13,15 @@ class SimpleReader(
in: BufferedReader,
out: PrintWriter,
val interactive: Boolean)
-extends InteractiveReader {
- def this() = this(Console.in, new PrintWriter(Console.out), true)
- def this(in: io.File, out: PrintWriter, interactive: Boolean) = this(in.bufferedReader(), out, interactive)
-
- lazy val history = History.Empty
- lazy val completion = Completion.Empty
+extends InteractiveReader
+{
+ val history = NoHistory
+ val completion = NoCompletion
def init() = ()
def reset() = ()
+ def redrawLine() = ()
+ def currentLine = ""
def readOneLine(prompt: String): String = {
if (interactive) {
out.print(prompt)
@@ -30,3 +30,11 @@ extends InteractiveReader {
in.readLine()
}
}
+
+object SimpleReader {
+ def defaultIn = Console.in
+ def defaultOut = new PrintWriter(Console.out)
+
+ def apply(in: BufferedReader = defaultIn, out: PrintWriter = defaultOut, interactive: Boolean = true): SimpleReader =
+ new SimpleReader(in, out, interactive)
+} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index 91dee97277..f72409c8e7 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -19,46 +19,55 @@ import scala.reflect.NameTransformer
*/
trait TypeStrings {
private val ObjectClass = classOf[java.lang.Object]
- private val primitives = Set[String]("byte", "char", "short", "int", "long", "float", "double", "boolean")
- private def unbox(s: String): String = s.stripPrefix("java.lang.") match {
- case "Integer" => "scala.Int"
- case "Character" => "scala.Char"
- case "Void" => "scala.Unit"
- case x @ ("Byte" | "Short" | "Long" | "Float" | "Double" | "Boolean") => "scala." + x
- case _ => NameTransformer.decode(s)
- }
+ private val primitives = Set[String]("byte", "char", "short", "int", "long", "float", "double", "boolean", "void")
+ private val primitiveMap = primitives.toList map { x =>
+ val key = x match {
+ case "void" => "Void"
+ case "int" => "Integer"
+ case "char" => "Character"
+ case s => s.capitalize
+ }
+ val value = x match {
+ case "void" => "Unit"
+ case s => s.capitalize
+ }
+
+ ("java.lang." + key) -> ("scala." + value)
+ } toMap
def scalaName(s: String): String = {
- if (s endsWith "$") (s dropRight 1) + ".type"
- else if (primitives(s)) "scala." + s.capitalize
+ if (s endsWith "$") s.init + ".type"
else if (s == "void") "scala.Unit"
- else unbox(s)
+ else if (primitives(s)) "scala." + s.capitalize
+ else primitiveMap.getOrElse(s, NameTransformer decode s)
}
def scalaName(clazz: JClass): String = scalaName(clazz.getName)
def scalaName(m: ClassManifest[_]): String = scalaName(m.erasure)
def anyClass(x: Any): JClass = if (x == null) null else x.asInstanceOf[AnyRef].getClass
+ private def brackets(tps: String*): String =
+ if (tps.isEmpty) ""
+ else tps.mkString("[", ", ", "]")
+
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 }
if (xs.isEmpty) "_"
else scalaName(xs.head)
}
- private def tparamString(clazz: JClass): String = {
- val tps = clazz.getTypeParameters.toList
- if (tps.isEmpty)
- return ""
+ private def tparamString(clazz: JClass): String =
+ brackets(clazz.getTypeParameters map tvarString: _*)
- (tps map tvarString).mkString("[", ", ", "]")
- }
- private def tparamString[T: Manifest] : String = {
- val tps = manifest[T].typeArguments
- if (tps.isEmpty)
- return ""
+ private def tparamString[T: Manifest] : String =
+ brackets(manifest[T].typeArguments map (m => tvarString(List(m.erasure))): _*)
- tps.map(m => tvarString(List(m.erasure))).mkString("[", ", ", "]")
- }
- /** Going for an overabundance of caution right now.
+ /** Going for an overabundance of caution right now. Later these types
+ * can be a lot more precise, but right now the manifests have a habit of
+ * introducing material which is not syntactically valid as scala source.
+ * When this happens it breaks the repl. It would be nice if we mandated
+ * that manifest toString methods (or some other method, since it's bad
+ * practice to rely on toString for correctness) generated the VALID string
+ * representation of the type.
*/
def fromTypedValue[T: Manifest](x: T): String = fromManifest[T]
def fromValue(value: Any): String = if (value == null) "Null" else fromClazz(anyClass(value))