diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-05-17 10:09:03 -0700 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2013-05-17 10:09:03 -0700 |
commit | bf3c44c3356456a4ee946334a5df76893ab3d322 (patch) | |
tree | 5b239e1b3e7daede0319a0127af70ea0eacebf81 /src/repl | |
parent | 07ef61a7d759c3944e01a77096346f5d2f1e7c74 (diff) | |
parent | 1d1492f7217f8f75f62febf1f68131931b31bfe2 (diff) | |
download | scala-bf3c44c3356456a4ee946334a5df76893ab3d322.tar.gz scala-bf3c44c3356456a4ee946334a5df76893ab3d322.tar.bz2 scala-bf3c44c3356456a4ee946334a5df76893ab3d322.zip |
Merge pull request #2340 from folone/topic/kind-pr
Added a :kind command to the REPL
Diffstat (limited to 'src/repl')
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/ExprTyper.scala | 15 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/ILoop.scala | 13 | ||||
-rw-r--r-- | src/repl/scala/tools/nsc/interpreter/package.scala | 42 |
3 files changed, 67 insertions, 3 deletions
diff --git a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala index 55182a4f95..9353215e1e 100644 --- a/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala +++ b/src/repl/scala/tools/nsc/interpreter/ExprTyper.scala @@ -95,4 +95,19 @@ trait ExprTyper { } finally typeOfExpressionDepth -= 1 } + + // This only works for proper types. + def typeOfTypeString(typeString: String): Type = { + def asProperType(): Option[Type] = { + val name = freshInternalVarName() + val line = "def %s: %s = ???" format (name, typeString) + interpretSynthetic(line) match { + case IR.Success => + val sym0 = symbolOfTerm(name) + Some(sym0.asMethod.returnType) + case _ => None + } + } + beSilentDuring(asProperType()) getOrElse NoType + } } diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala index 197e76d990..f4e06f6bfc 100644 --- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala +++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala @@ -222,6 +222,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) shCommand, nullary("silent", "disable/enable automatic printing of results", verbosity), cmd("type", "[-v] <expr>", "display the type of an expression without evaluating it", typeCommand), + cmd("kind", "[-v] <expr>", "display the kind of expression's type", kindCommand), nullary("warnings", "show the suppressed warnings from the most recent line which had any", warningsCommand) ) @@ -287,9 +288,15 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter) // Still todo: modules. private def typeCommand(line0: String): Result = { line0.trim match { - case "" => ":type [-v] <expression>" - case s if s startsWith "-v " => intp.typeCommandInternal(s stripPrefix "-v " trim, verbose = true) - case s => intp.typeCommandInternal(s, verbose = false) + case "" => ":type [-v] <expression>" + case s => intp.typeCommandInternal(s stripPrefix "-v " trim, verbose = s startsWith "-v ") + } + } + + private def kindCommand(expr: String): Result = { + expr.trim match { + case "" => ":kind [-v] <expression>" + case s => intp.kindCommandInternal(s stripPrefix "-v " trim, verbose = s startsWith "-v ") } } diff --git a/src/repl/scala/tools/nsc/interpreter/package.scala b/src/repl/scala/tools/nsc/interpreter/package.scala index 52a085080b..f82c38f5e7 100644 --- a/src/repl/scala/tools/nsc/interpreter/package.scala +++ b/src/repl/scala/tools/nsc/interpreter/package.scala @@ -10,6 +10,7 @@ import scala.reflect.{ classTag, ClassTag } import scala.reflect.runtime.{ universe => ru } import scala.reflect.{ClassTag, classTag} import scala.reflect.api.{Mirror, TypeCreator, Universe => ApiUniverse} +import scala.util.control.Exception.catching /** The main REPL related classes and values are as follows. * In addition to standard compiler classes Global and Settings, there are: @@ -127,6 +128,47 @@ package object interpreter extends ReplConfig with ReplStrings { "" } + def kindCommandInternal(expr: String, verbose: Boolean): Unit = { + val catcher = catching(classOf[MissingRequirementError], + classOf[ScalaReflectionException]) + def typeFromTypeString: Option[ClassSymbol] = catcher opt { + exprTyper.typeOfTypeString(expr).typeSymbol.asClass + } + def typeFromNameTreatedAsTerm: Option[ClassSymbol] = catcher opt { + val moduleClass = exprTyper.typeOfExpression(expr).typeSymbol + moduleClass.linkedClassOfClass.asClass + } + def typeFromFullName: Option[ClassSymbol] = catcher opt { + intp.global.rootMirror.staticClass(expr) + } + def typeOfTerm: Option[TypeSymbol] = replInfo(symbolOfLine(expr)).typeSymbol match { + case sym: TypeSymbol => Some(sym) + case _ => None + } + (typeFromTypeString orElse typeFromNameTreatedAsTerm orElse typeFromFullName orElse typeOfTerm) foreach { sym => + val (kind, tpe) = exitingTyper { + val tpe = sym.tpeHK + (intp.global.inferKind(NoPrefix)(tpe, sym.owner), tpe) + } + echoKind(tpe, kind, verbose) + } + } + + def echoKind(tpe: Type, kind: Kind, verbose: Boolean) { + def typeString(tpe: Type): String = { + tpe match { + case TypeRef(_, sym, _) => typeString(sym.typeSignature) + case RefinedType(_, _) => tpe.toString + case _ => tpe.typeSymbol.fullName + } + } + printAfterTyper(typeString(tpe) + "'s kind is " + kind.scalaNotation) + if (verbose) { + echo(kind.starNotation) + echo(kind.description) + } + } + /** TODO - * -n normalize * -l label with case class parameter names |