Как создать новый исходный код в текстовой форме в плагине компилятора Scala? - PullRequest
8 голосов
/ 02 октября 2011

Я только что закончил первую версию плагина компилятора Java 6, который автоматически генерирует оболочки (прокси, адаптер, делегат, называйте это как хотите) на основе аннотации.

Поскольку я занимаюсь смешанными проектами Java / Scala, я хотел бы иметь возможность использовать одну и ту же аннотацию внутри моего кода Scala и получать такой же сгенерированный код (кроме, конечно, в Scala). Это в основном означает начинать с нуля.

То, что я хотел бы сделать, и для которого я еще не нашел пример, - это как сгенерировать код внутри плагина компилятора Scala так же, как и в плагине компилятора Java. То есть я сопоставляю / нахожу, где используется моя аннотация, получаю AST для аннотированного интерфейса, а затем прошу API дать мне Stream / Writer, в котором я выводю сгенерированный исходный код Scala, используя манипуляции со строками .

Эту последнюю часть я не смог найти. Итак, как мне сказать API создать новый исходный файл Scala и дать мне Stream / Writer / File / Handle, чтобы я мог просто написать в нем, и когда я это сделаю, компилятор Scala компилирует его в тот же прогон, в котором был запущен плагин?

Зачем мне это делать? Во-первых, потому что чем оба плагина имеют одинаковую структуру, то и обслуживание простое. Во-вторых, я хочу открыть его с открытым исходным кодом, и просто нет способа поддержать каждый вариант, который бы кто-нибудь захотел, поэтому я ожидаю, что потенциальные пользователи захотят расширить генерацию своим собственным кодом. Для них это будет намного проще, если им просто нужно выполнить printf () вместо изучения AST API (это относится и ко мне).

Ответы [ 2 ]

5 голосов
/ 03 октября 2011

Краткий ответ:

Это невозможно сделать

Длинный ответ:

Вы можете создать свой исходный файл и передать его через экземпляр анализатора в вашем плагине. Но никоим образом не может быть полезным для вас, потому что теперь вам придется столкнуться с более серьезной проблемой:

Чтобы получить всю информацию о типе / имени для создания delagate / proxy, вам нужно выбрать AST аннотированного типа после того, как он прошел через фазы namer и typer (которые неотделимы). Подвох в том, что любые попытки вызвать ваш сгенерированный код уже потерпели неудачу при проверке типов, компилятор выдаст ошибку и все дальнейшие ставки будут отключены.

Синтез метода возможен в ограниченных случаях, при условии, что вы можете каким-то образом одурачить проверку типов на достаточно долгое время для генерации кода, что я и использовал при помощи Autoproxy 'lite 'плагин . Даже тогда вам гораздо лучше работать с TreeDSL для генерации кода, а не откачивать исходный код.

1 голос
/ 17 октября 2011

Кевин полностью прав, но просто для полноты стоит упомянуть, что есть другая альтернатива - написать плагин компилятора, который генерирует исходный код.Это подход, который я принял в Borachio .Это не очень удовлетворительное решение, но его можно заставить работать.

Редактировать - я просто перечитал ваш вопрос и понял, что вы все равно спрашиваете о создании источника

Таким образом, это напрямую не поддерживается, но в основном это просто вопрос открытия файла и написания соответствующих «печатных» операторов.Нет никакого способа вызвать компилятор «внутри» плагина AFAIK, но я написал плагин sbt , который скрывает большую часть сложности вызова компилятора дважды.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...