8

意図

コマンドのサポートを replに追加しようとしています。Eugene Burmako のおかげで、私は動くプロトタイプを手に入れることができました。ただし、完全修飾名でのみ機能し、インポートされた名前の解決に失敗します。:kind

replにインポートされたタイプを認識しているので、私は今IMain.exprTyper、仕事をするために使用しようとしています。しかし問題がある。私が試したものはすべてClassInfoType、次のようなものを返します( で表示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)

作業中の実装は 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))

質問

本当に近くにいるような気がします。これが遊び場です。自分ですべてを試すために使用できます。

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)

ClassInfoType必要な情報を含むValidに変換するにはどうすればよいTypeですか? Typeまたは、そもそも使用方法を取得するにはどうすればよいIMainですか?

4

2 に答える 2

5

これはどう?現在実行中の 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られる理由は、フェーズによるものです。電力モードの と同じ結果を得るにはglobal、位相を に設定する必要がありtyperます。REPLから @retronym の説明を引用するには: intp.global vs "global" available in :power mode :

scala> :power
** Power User mode enabled - BEEP WHIR GYVE **
** :phase has been set to 'typer'.          **
    ^
    `----  this part is relevant

シンボルには、コンパイラ フェーズによってインデックス付けされた型 (別名info-s) のリストがあります。(別名 TypeHistory)。多くのコンパイラ フェーズInfoTransformerでは、型をモーフィングするために s をインストールします。ドキュメントについては、src/compiler/scala/tools/nsc/transform/InfoTransform.scala を参照してください。

特定のフェーズで型を検査するには、「exitingTyper」などのメソッドを使用できます。

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

または、もう少し便利な :power モード:

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
于 2013-03-28T23:34:39.133 に答える
2

IMainのグローバルからのミラーを使用する必要があります。

scala> val imain = new IMain()
imain: scala.tools.nsc.interpreter.IMain = scala

scala> val mirror = imain.global.rootMirror
mirror: imain.global.Mirror = compiler mirror
于 2013-03-28T13:02:35.767 に答える