Iはtranforms
コードのようなマクロがある場合:ランタイム反射ユニバースとマクロユニバースがscala.Noneの2つの異なるツリーを作成するのはなぜですか?
(src: a.b.c.TestEntity) =>
{
z.y.TestTable(None)
}
は、Iのような抽出器を使用することができ、そのASTのなし一部に一致するようにする:なし一部のshowRaw
として
object NoneExtractor {
def unapply(t: Tree): Boolean = t match {
case Select(Ident(scala), none) if scala.encoded == "scala" && none.encoded == "None" => true
case _ => false
}
}
ASTのようになっています
Select(Ident(scala), None)
しかし、私はNoneExtractor
のユニットテストを書きたい場合、私はしたくありませんマクロのコンパイルと再構築、およびマクロのコンパイル中のプロジェクトでのテストのホスト。私は、実行時の反射を示唆してマクロのプロジェクト内の抽出がして行く方法であるユニットテストしたい:
val t = reify {
(src: a.b.c.TestEntity) =>
{
z.y.TestTable(None)
}
}.tree
しかし、木は全く異なるとなしのように見えないその木のshowRaw
である:
Ident(scala.None)
これは、マイナステストを作成して、マクロのエラー処理をチェックするのに悪いニュースです。コードがコンパイルされず、コンパイルエラーでネガティブテストをデバッグすることができないため、別のプロジェクトのマクロを使用してマクロに対して否定的なテストを書くことはできません。
コンパイル時のリフレクションと実行時のリフレクションでは、何も全く同じように表現できないのはなぜですか?コンパイル時の反映中にマクロに渡されるのと同じASTであるマクロプロジェクト内にテスト可能なツリーフラグメントを作成する方法はありますか?
ツリー表示に基づいて特定の値を選ぶことは、マクロの土地に完全に入っていても、ややこしいことです。代わりに 't.tpe =:= typeOf [None.type]'のようなことをすることができますか? –
私は実際にネストされたマッチステートメントとASTを構造的にマッチさせる必要があります。私は機能的ではないので、if/then/else/callスタイルの命令コードから始めました。それは関数の一致/ case/match/case/....にリファクタリングしているので、コードの約5倍になりました。マクロ宇宙apiには膨大な量の抽出器が組み込まれています。だから私の理解エクストラクターとネストされた一致は、これを行うための標準的な方法です。私の質問は、どのように別のアプローチを完全に取るかという問題ではなく、標準的な方法をテストする方法です。 – simbo1905