2

ネストされた関数のアプリケーションを分析するマクロがあります。アプリケーションを照合し、次の方法でパラメータ タイプを取得します。

case q"$f[..$targs](..$args)(...$otherArgs)" =>

    // retrieve the list of all parameter types
    val paramTpes = f.tpe match {
      case pmt: PolyType if pmt.paramLists.size == 0 =>
        Seq()
      case pmt: PolyType =>
        pmt.paramLists(0) map {_.typeSignature
             .substituteTypes(pmt.typeParams, targs map (_.tpe))}
      case pmt: MethodType if pmt.paramLists.size == 0 =>
        Seq()
      case pmt: MethodType =>
        pmt.paramLists(0) map (_.typeSignature)
    }

ここで、たまたま名前付きパラメーターがある場合、出力=> Tされるが何にも一致しない奇妙な型が得られます。リフレクション API には、これらを適切に処理する機能がないようです。私がやりたいのは、生成されたコードでさらに問題が発生するため、Tそれが の場合に取得することです。=> T=> T

4

1 に答える 1

4

通常はエクストラクターを使用します。使用するエクストラクタを覚えておくために、ランタイム クラスが何であるかを確認する必要がある場合があります。毎日 API を使用するわけではありません。

scala> import reflect.runtime._, universe._
import reflect.runtime._
import universe._

scala> class X { def x(i: => Int) = i * 2 }
defined class X

scala> typeOf[X].member(TermName("x"))
res0: reflect.runtime.universe.Symbol = method x

scala> .typeSignature
res1: reflect.runtime.universe.Type = (i: => scala.Int)scala.Int

scala> res1 match { case MethodType(ps, res) => ps }
res2: List[reflect.runtime.universe.Symbol] = List(value i)

scala> .head
res3: reflect.runtime.universe.Symbol = value i

scala> .typeSignature
res4: reflect.runtime.universe.Type = => scala.Int

scala> res4.getClass
res5: Class[_ <: reflect.runtime.universe.Type] = class scala.reflect.internal.Types$ClassArgsTypeRef

scala> res4 match { case TypeRef(pre, sym, args) => sym }
res6: reflect.runtime.universe.Symbol = class <byname>

scala> res4 match { case TypeRef(pre, sym, args) => args }
res7: List[reflect.runtime.universe.Type] = List(scala.Int)

scala> definitions
res8: reflect.runtime.universe.DefinitionsApi = scala.reflect.internal.Definitions$definitions$@4e80a001

scala> definitions.By
ByNameParamClass   ByteClass   ByteTpe

scala> definitions.ByNameParamClass
res9: reflect.runtime.universe.ClassSymbol = class <byname>

特別な名前を漠然と覚えていますが、パターン マッチング用の安定したプレフィックスを取得できますか? そうではないと思います。

scala> res4 match { case TypeRef(pre, definitions.ByNameParamClass, args) => args }
<console>:20: error: stable identifier required, but scala.reflect.runtime.`package`.universe.definitions.ByNameParamClass found.
 Note that method ByNameParamClass is not stable because its type, => reflect.runtime.universe.ClassSymbol, is volatile.
              res4 match { case TypeRef(pre, definitions.ByNameParamClass, args) => args }
                                                         ^

scala> val k = definitions.ByNameParamClass
k: reflect.runtime.universe.ClassSymbol = class <byname>

scala> res4 match { case TypeRef(pre, k, args) => args }
res11: List[reflect.runtime.universe.Type] = List(scala.Int)

scala> 
于 2015-04-20T21:25:13.263 に答える