2016-09-13 2 views
0

Учитывая аннотированную черту, как мне следует генерировать абстрактный класс, который реализует черту?Как программно генерировать абстрактный класс Scala, расширяющий аннотированный признак?

Таким образом, учитывая следующие пользовательские черта ...

@Neuron 
trait SomeTrait { 
    // ... 
} 

... в моей библиотеке, я хочу, чтобы вставить что-то вроде следующего рядом с ним:

abstract class SomeTraitImpl extends SomeTrait 

Обратите внимание, что я знаю ничего о данной черте, кроме того, что она аннотируется @Neuron.

Я попытался сделать это с помощью ASM, реализовав концепцию, объясненную в ответе на вопрос Using Scala traits with implemented methods in Java, но эта концепция царапает только поверхность того, что компилятор Scala испускает как байтовый код. Даже если мне удалось овладеть всеми возможными комбинациями var, val, lazy val, abstract override и т. Д., Вероятность того, что он сломается со следующей версией компилятора Scala.

Так что, похоже, я должен написать макрос времени компиляции. Тем не менее, я почесываю голову над документацией для макросов Scala, поэтому я задаюсь вопросом, может ли кто-нибудь нарисовать что-то, что заставляет меня начать? Любые намеки приветствуются, пожалуйста!

+0

Вы хотите изменить код без аннотации '@ Neuron'? Поэтому '@Neuron trait SomeTrait' останется без изменений, но« абстрактный класс SomeTraitImpl extends SomeTrait »будет создан где-то, верно? – dveim

+0

Да, исходный признак должен быть оставлен как есть, вместо него следует добавить новый 'SomeTraitImpl'. –

+0

Предположим, что проект с атрибутом '@Neuron SomeTrait' был скомпилирован отдельно от проекта с помощью' SomeTraitImpl' (помните, что макросы работают во время компиляции). Как будет генерироваться код для 'SomeTraitImpl'? Возможный обходной путь - используйте еще один макрос «NeuronGenerator» во втором проекте, он будет лучше всего искать '@ Neuron' и создавать АСТ. Это возможно для вашего случая? – dveim

ответ

0

Правильный подход для этого состоит в том, чтобы сделать @Neuron a macro annotation (используя плагин компилятора Macro Paradise) и реализовать макрос для преобразования кода. Получившийся код теперь является частью Neuron DI, рамки для инъекции зависимостей, которую я написал.

Смежные вопросы