2016-07-16 18 views
0

スカラマクロを作成しています。スカラマクロは、指定された関数を調べて引数の名前と型を探します。スカラマクロ:関数参照の引数型

def hello(i: Int, s: String) = s + i 

私はこのようなマクロを養う場合には、これまでの作品:

val args: TypeInfo = signature(hello _) 

しかし、私はまた、元の関数への参照のみを供給することができるようにしたい:

def invokeMacro(f: (Int, String) => String) = signature(f) 
invokeMacro(hello) 

残念ながら、これは動作しません。マクロ の内側に元の関数「ハロー」のホールドを取得し、それが情報を入力します抽出することが可能であるならば、私は疑問に思う今

val typeInfo = TypeInfo(t.filter(_.isDef).collect { 
    case ValDef(_, name, typ, _) => 
    name.decodedName.toString -> typ.tpe.toString 
}) 

:ここ

は、私は、マクロ内の型情報を取得する方法です。 でマクロ内の情報を精査すると、デバッガは期待していたものを得られませんでした。

そうかもしれないが、そうでない場合は、どうしてですか?なぜですか?それが可能なら、どうですか?

+0

それはうまく動作します。私は新鮮な名前を期待していただろう。 –

答えて

1

invokeMacroはマクロではなく関数なので、引数のASTを取得せず、signatureは引数(またはそのようなもの)としてIdent(TermName("f"))と表示されます。これはValDefではないので、あなたの試合は失敗します。もちろん、helloという名前は決してありません(しかし、あなたはそのタイプを得ることができます)。

この問題を回避するには、invokeMacro自体がsignature(f)コールを生成するマクロである必要があります。または、より一般的には、

def invokeMacro0[A](f:() => A) = macro... 
def invokeMacro1[A, B](f: A => B) = macro... 
def invokeMacro2[A, B, C](f: (A, B) => C) = macro... 
... 
関連する問題