2017-01-15 13 views
0
package scalaworld.macros 
import scala.meta._ 

class Argument(arg: Int) extends scala.annotation.StaticAnnotation { 
    inline def apply(defn: Any): Any = meta { 
    println(this.structure) 
    val arg = this match { 
     // The argument needs to be a literal like `1` or a string like `"foobar"`. 
     // You can't pass in a variable name. 
     case q"new $_(${Lit(arg: Int)})"      => arg 
     // Example if you have more than one argument. 
     case q"new $_(${Lit(arg: Int)}, ${Lit(foo: String)})" => arg 
     case _            => ??? // default  value 
    } 
    println(s"Arg is $arg") 
    defn.asInstanceOf[Stat] 
    } 
} 

上記のマクロを修正し、型パラメータ[A]を追加したいと思います。 は、私は次のことを試してみましたが、それはマクロの注釈に渡される引数は、メタ木として渡され型パラメータをスカラメタマクロ/注釈に渡す

package scalaworld.macros 
import scala.meta._ 

class Argument2[A](arg: A) extends scala.annotation.StaticAnnotation { 
    inline def apply(defn: Any): Any = meta { 
    println(this.structure) 
    val arg = this match { 
     case q"new $_(${Lit(arg: A)})"      => arg 
     case q"new $_(${Lit(arg: A)}, ${Lit(foo: String)})" => arg 
     case _            => ??? 
    } 
    println(s"Arg is $arg") 
    defn.asInstanceOf[Stat] 
    } 
} 
+0

ここで説明するものに似た何かをしようとしています。https://github.com/scalameta/sips/blob/3520d5c761abfdfeff66d396456791971795f6af/sips/保留中/ _posts/2016-09-09-inline-meta.md#inlinemeta – Bate

答えて

0

をコンパイルしません。

Lit()抽出器でInt/Double/Stringなどのリテラルを抽出することはできますが、これは他の事例に当てはまらない。

メタ

  • @someMacro(1)で解析@someMacro(Lit(1))
  • @someMacro("Foo")@someMacro(Lit("Foo"))

それが正常に

  • @someMacro(foo)なっされるように他のすべてが渡さなっとなり
  • @someMacro(Option(2))これは、あなたがこの事への実行時アクセスを持たないことを意味@someMacro(Term.Apply(Term.Name("Option"), Seq(Lit(2))))

になります。あなたはシンボルを解決するためにセマンティックApiなしでオブジェクトを正しくインスタンス化することさえできません。スケーラメタ2とパラダイス4ではが可能ですが、今は確かに不可能です。あなたができることは、値をチェックするランタイムパターンマッチを作ることです。

私はここにいくつかの類似したもの(これはWIP非常にであることに注意してください)を実行します。 https://github.com/DavidDudson/Elysium/blob/master/gen/src/main/scala/nz/daved/elysium/gen/MacroAnnotation.scala

が、具体的https://github.com/DavidDudson/Elysium/blob/master/gen/src/main/scala/nz/daved/elysium/gen/MacroAnnotation.scala#L149

を参照してください。注:これは、ちょうどそのための例では、時間をコンパイルすることを起こるランタイム(で)、argが間違った型で渡された場合、ランタイム例外

+0

@David Dudsonありがとうございました – Bate

+0

@David Dudsonありがとうございました このクラスをコンパイルしようとするとエラーが発生します https://github.com/DavidDudson/Elysium/blob/master/gen/src/main/scala/nz /daved/elysium/gen/MacroAnnotation.scala paradise_2.11.8-3.0.0-SNAPSHOT.jarを提供できますか? '[エラー] /Users/batemady/tools/scala/samples/meta/scalameta-tutorial/src/main/scala/scala/meta/serialiser/MacroAnnotation.scala:14:;期待値だがdefが見つかりました [エラー] val newStat = q "$ compileTimeOnly inline def apply(a:Any):Any = meta {.. $ inMetaBlockStats}" ' – Bate

+0

Elysiumプロジェクト全体をコンパイルしようとしているときに次のエラーが発生しました '[error]必須プラグインがありません:macroparadise' – Bate

関連する問題