通过IMain在scala repl中获取类型信息
意图
我是trying to add支持:对scala repl的亲切命令.感谢Eugene Burmako,我得到了working prototype.虽然它只适用于完全限定的名称,但无法解析导入的名称. 我现在正在尝试使用 ClassInfoType(List(TypeRef(TypeRef(TypeRef(TypeRef(NoPrefix(),package <root>,List()),package java,package lang,class Object,TypeRef(TypeRef(TypeRef(NoPrefix(),package scala,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) 工作实现返回特定类型: PolyType(List(TypeName("A")),ClassInfoType(List(TypeRef(ThisType(scala),TypeName("AnyRef"),TypeRef(ThisType(scala),scala.Product,scala.Serializable,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)) 题 我觉得我真的很亲密.这是一个游乐场,您可以自己尝试一切: 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")),scala.Option)) scala> showRaw(typer.typeOfExpression(expr).typeSymbol.typeSignature) // Wrong signature res7: String = ClassInfoType(List(TypeRef(TypeRef(TypeRef(TypeRef(NoPrefix(),object Option) 如何将ClassInfoType转换为包含所需信息的有效类型?或者,我如何首先使用IMain获取Type? 解决方法
这个怎么样?我正在使用电源模式,它允许您从当前运行的REPL访问全局,这比创建新的IMain更方便.
scala> :power Already in power mode. scala> val g = global g: $r.intp.global.type = <global> scala> val context = g.analyzer.rootContext(NoCompilationUnit) context: g.analyzer.Context = Context(<root>@EmptyTree unit=NoCompilationUnit scope=997093283 errors=false,reportErrors=true,throwErrors=false) // aware imports of scala._,etc. scala> val sym = context.lookupSymbol("Option": TypeName,_ => true).symbol sym: g.analyzer.global.Symbol = class Option scala> sym.tpeHK.typeParams res21: List[g.analyzer.global.Symbol] = List(type A) 也可以看看: scala> intp.symbolOfType("Foo") res26: $r.intp.global.Symbol = class Foo 但我不知道如何获得以前导入的符号: scala> object Bar { class Bop } defined object Bar scala> import Bar.Bop import Bar.Bop scala> intp.symbolOfType("Bop") res27: $r.intp.global.Symbol = <none> 编辑: OP获得ClassInfoType而不是PolyType的原因是由于阶段.要获得与电源模式的全局相同的结果,必须将阶段设置为typer.从REPL: intp.global vs “global” available in :power mode引用@ retronym的解释: scala> :power ** Power User mode enabled - BEEP WHIR GYVE ** ** :phase has been set to 'typer'. ** ^ `---- this part is relevant
scala> exitingPostErasure($intp.global.rootMirror.staticClass("scala.Option").typeSignature).getClass res6: Class[_ <: $intp.global.Type] = class scala.reflect.internal.Types$ClassInfoType scala> exitingTyper($intp.global.rootMirror.staticClass("scala.Option").typeSignature).getClass res7: Class[_ <: $intp.global.Type] = class scala.reflect.internal.Types$PolyType
scala> :phase typer Active phase is now: Typer scala> global.rootMirror.staticClass("scala.Option").typeSignature.getClass res16: Class[_ <: $r.global.Type] = class scala.reflect.internal.Types$PolyType scala> :phase cleanup Active phase is now: Cleanup scala> global.rootMirror.staticClass("scala.Option").typeSignature.getClass res17: Class[_ <: $r.global.Type] = class scala.reflect.internal.Types$ClassInfoType (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |