summaryrefslogtreecommitdiff
path: root/src/repl/scala/tools/nsc/interpreter/package.scala
diff options
context:
space:
mode:
authorEugene Yokota <eed3si9n@gmail.com>2013-04-20 21:12:39 -0400
committerEugene Yokota <eed3si9n@gmail.com>2013-04-20 21:12:39 -0400
commit1d1492f7217f8f75f62febf1f68131931b31bfe2 (patch)
tree35866756a2359379dd6e0834e5fa258ea3c39779 /src/repl/scala/tools/nsc/interpreter/package.scala
parent68c6ba7e59befa88b2f383dd7eca71a9329a8b6d (diff)
downloadscala-1d1492f7217f8f75f62febf1f68131931b31bfe2.tar.gz
scala-1d1492f7217f8f75f62febf1f68131931b31bfe2.tar.bz2
scala-1d1492f7217f8f75f62febf1f68131931b31bfe2.zip
Add :kind command to REPL
:kind command diplays the kind of types and type constructors in Scala syntax notation. scala> :kind (Int, Int) => Int scala.Function2's kind is F[-A1,-A2,+A3]
Diffstat (limited to 'src/repl/scala/tools/nsc/interpreter/package.scala')
-rw-r--r--src/repl/scala/tools/nsc/interpreter/package.scala42
1 files changed, 42 insertions, 0 deletions
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