Intent
I am trying to add support for :kind
command to scala repl. Thanks to Eugene Burmako, I was able to get a working prototype. Though it only works with fully qualified names and fails to resolve imported names.
I am now trying to use IMain.exprTyper
to do the job, as it is aware of types, imported into the repl. But there is a problem. Everything I've tried returns a ClassInfoType
like the following (displayed with showRaw
):
ClassInfoType(List(TypeRef(TypeRef(TypeRef(TypeRef(NoPrefix(), package <root>, List()), package java, List()), package lang, List()), class Object, List()), TypeRef(TypeRef(TypeRef(NoPrefix(), package <root>, List()), package scala, List()), trait Serializable, List())), Scope{
def <init>(): Option.type;
implicit def option2Iterable(xo: Option): Iterable;
def apply(x: Object): Option;
def empty(): Option;
private def readResolve(): Object
}, object Option)
While the working implementation returns specific Type
:
PolyType(List(TypeName("A")), ClassInfoType(List(TypeRef(ThisType(scala), TypeName("AnyRef"), List()), TypeRef(ThisType(scala), scala.Product, List()), TypeRef(ThisType(scala), scala.Serializable, List())), Scope(nme.CONSTRUCTOR, TermName("isEmpty"), TermName("isDefined"), TermName("get"), TermName("getOrElse"), TermName("orNull"), TermName("map"), TermName("fold"), TermName("flatMap"), TermName("flatten"), TermName("filter"), TermName("filterNot"), TermName("nonEmpty"), TermName("withFilter"), TypeName("WithFilter"), TermName("contains"), TermName("exists"), TermName("forall"), TermName("foreach"), TermName("collect"), TermName("orElse"), TermName("iterator"), TermName("toList"), TermName("toRight"), TermName("toLeft")), scala.Option))
Question
I feel like I'm really close. Here's a playground, you can use to try everything yourself:
Welcome to Scala version 2.11.0-20130328-093148-47645c7e7e (OpenJDK 64-Bit Server VM, Java 1.7.0_17).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._
scala> import scala.tools.nsc.interpreter.IMain
import scala.tools.nsc.interpreter.IMain
scala> val mirror = runtimeMirror(getClass.getClassLoader) // Working approach
mirror: reflect.runtime.universe.Mirror = JavaMirror with scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@3d34ec98 of type class scala.tools.nsc.interpreter.IMain$TranslatingClassLoader with classpath [<unknown>] and parent being scala.tools.nsc.util.ScalaClassLoader$URLClassLoader@5d990e8c of type class scala.tools.nsc.util.ScalaClassLoader$URLClassLoader with classpath [file:/usr/lib/jvm/java-7-openjdk/jre/lib/resources.jar,file:/usr/lib/jvm/java-7-openjdk/jre/lib/rt.jar,file:/usr/lib/jvm/java-7-openjdk/jre/lib/jsse.jar,file:/usr/lib/jvm/java-7-openjdk/jre/lib/jce.jar,file:/usr/lib/jvm/java-7-openjdk/jre/lib/charsets.jar,file:/usr/lib/jvm/java-7-openjdk/jre/lib/rhino.jar,file:/home/folone/workspace/scala-myfork/build/pack/lib/jline.jar,file:/home/folone/workspace/scala-myfork...
scala> val typer = new IMain().exprTyper // Not working approach
typer: scala.tools.nsc.interpreter.IMain#exprTyper.type = scala.tools.nsc.interpreter.IMain$exprTyper$@68c181f0
scala> val expr = "scala.Option"
expr: String = scala.Option
scala> showRaw(mirror.staticClass(expr).toType.typeSymbol.typeSignature) // Correct signature
res6: String = PolyType(List(TypeName("A")), ClassInfoType(List(TypeRef(ThisType(scala), TypeName("AnyRef"), List()), TypeRef(ThisType(scala), scala.Product, List()), TypeRef(ThisType(scala), scala.Serializable, List())), Scope(nme.CONSTRUCTOR, TermName("isEmpty"), TermName("isDefined"), TermName("get"), TermName("getOrElse"), TermName("orNull"), TermName("map"), TermName("fold"), TermName("flatMap"), TermName("flatten"), TermName("filter"), TermName("filterNot"), TermName("nonEmpty"), TermName("withFilter"), TypeName("WithFilter"), TermName("contains"), TermName("exists"), TermName("forall"), TermName("foreach"), TermName("collect"), TermName("orElse"), TermName("iterator"), TermName("toList"), TermName("toRight"), TermName("toLeft")), scala.Option))
scala> showRaw(typer.typeOfExpression(expr).typeSymbol.typeSignature) // Wrong signature
res7: String =
ClassInfoType(List(TypeRef(TypeRef(TypeRef(TypeRef(NoPrefix(), package <root>, List()), package java, List()), package lang, List()), class Object, List()), TypeRef(TypeRef(TypeRef(NoPrefix(), package <root>, List()), package scala, List()), trait Serializable, List())), Scope{
def <init>(): Option.type;
implicit def option2Iterable(xo: Option): Iterable;
def apply(x: Object): Option;
def empty(): Option;
private def readResolve(): Object
}, object Option)
How do I transform ClassInfoType
into a valid Type
containing the needed info? Alternatively, how do I get the Type
using IMain
in the first place?