Если у меня есть макрос, который имеет код tranforms
, например:
(src: a.b.c.TestEntity) =>
{
z.y.TestTable(None)
}
Чтобы соответствовать ни одной части этого AST, я могу использовать экстрактор, например:
object NoneExtractor {
def unapply(t: Tree): Boolean = t match {
case Select(Ident(scala), none) if scala.encoded == "scala" && none.encoded == "None" => true
case _ => false
}
}
В качестве showRaw
части "Нет" АСТ выглядит следующим образом:
Select(Ident(scala), None)
Но если я хочу написать unit test NoneExtractor
, я не хочу компилировать и перестраивать макросы и размещать тест в проекте, который компилирует макрос. Я хочу unit test экстрактор в проекте макроса, который предполагает, что отражение во время выполнения - это путь:
val t = reify {
(src: a.b.c.TestEntity) =>
{
z.y.TestTable(None)
}
}.tree
Но дерево совершенно другое, а в showRaw
этого дерева None выглядит так:
Ident(scala.None)
Это плохая новость для написания отрицательных тестов и проверки обработки ошибок моего макроса. Вы не можете писать отрицательные тесты для макроса, используя макрос из другого проекта, поскольку код не будет компилироваться (и вы не можете отлаживать свой отрицательный тест с ошибками компиляции).
Почему представления о чем-то столь же фундаментальном, как None, настолько различаются между отражением времени компиляции и отражением времени выполнения? Есть ли способ создать тестируемые фрагменты дерева в макропроекте, который является тем же самым AST, который будет передан макросу во время отражения времени компиляции?