0

パッケージからすべてのオブジェクトを抽出するためにscalaマクロを使用し、オブジェクトからいくつかの値を取得したいと思います:

 package example

 trait A {}
 object B extends A { val test = "test" }

 //macro
 object Macro
   def getVals(packageName: String) = macro getValsImpl

   def getValsImpl(c: Context)(packageName: c.Expr[String]): c.Expr[Unit] = {
     import c.universe._

     val pkg = from.tree match {
      case Literal(Constant(name: String)) => c.mirror.staticPackage(name)
     }

     val objects = pkg.typeSignature.members.collect {
       //get all objects which a subtype of `A`   
       case x if (x.isModule && x.typeSignature <:< typeOf[A]) => x  
     }.toList

     val o = objects(0)

     println(o.test)

     reify {}
   }
 }

しかし、私はエラーが発生しました

value test is not a member of c.universe.ModuleSymbol
4

1 に答える 1

1

コンパイル時のアーティファクトを実際のランタイム値と間違えています。

マクロの実装はコンパイル時に呼び出されます。アクセスしようとしている実際のオブジェクトはまだ存在しません (Symbolそれらを表す言語のみ)。ModuleSymbolそのため、オブジェクトを期待するときに取得していBます。

Bつまり、マクロ実装ではアクセスできません。

マクロは、コードExpr(および で表されるTree) を分析、変換、および生成するためのものです。したがって、できることはModuleSymbol、オブジェクトを表す を持ち、コンパイルされて最終的に実行時に実行されると、そのオブジェクトに評価されるコードを生成することです。しかし、これがあなたがここで望んでいるものかどうかはわかりません。

于 2013-11-09T16:09:13.837 に答える