Автоматическая генерация исходного кода Java - PullRequest
5 голосов
/ 21 апреля 2011

Я ищу способ автоматического создания исходного кода для новых методов в существующем файле исходного кода Java на основе полей, определенных в классе.

По сути, я хочу выполнить следующие шаги:

  1. Чтение и анализ SomeClass.java
  2. Итерация по всем полям, определенным в исходном коде
  3. Добавить метод исходного кода someMethod()
  4. Сохранить SomeClass.java (в идеале, сохранение форматирования существующего кода)

Какие инструменты и методы лучше всего подходят для этого?

EDIT

Я не хочу генерировать код во время выполнения; Я хочу дополнить существующий исходный код Java

Ответы [ 7 ]

11 голосов
/ 22 апреля 2011

Требуется система Program Transformation .

У хороших есть парсеры для языка, который вам небезразличен, создайте AST, представляющие программу для проанализированного кода, предоставьте вам доступ кAST для анализа и модификации, и может восстановить исходный текст из AST.Ваше замечание о «сканировании полей» является всего лишь прохождением AST, представляющего программу.Для каждого интересного результата анализа, который вы производите, вы хотите внести изменения в AST, возможно, где-то еще, но тем не менее в AST.И после того, как все ошибки сделаны, вы хотите регенерировать текст с комментариями (как первоначально введено, или как вы создали в своем новом коде).

Есть несколько инструментов, которые делают это специально для Java.

Джекпот предоставляет синтаксический анализатор, создает AST и позволяет кодировать Java-процедуры для выполнения того, что вы хотите с деревьями.Перевернутый: легко концептуально.Недостаток: вы пишете гораздо больше Java-кода, чтобы лазить по деревьям / взламывать их, чем вы ожидаете.Джекпот работает только с Java.

Stratego и TXL анализирует ваш код, создает AST и позволяет вам записывать преобразования "surce-to-source" (используя синтаксисцелевого языка (например, Java в данном случае) для выражения шаблонов и исправлений.Дополнительные хорошие новости: вы можете определить любой язык программирования, который вам нравится, в качестве целевого языка для обработки, и оба из них имеют определения Java.Но они слабы в анализе: часто вам нужны таблицы символов и анализ потока данных, чтобы действительно провести анализ и необходимые изменения.И они настаивают на том, что все является правилом переписывания, помогает ли это вам или нет;это немного похоже на настаивание на том, что вам нужен только молоток в наборе инструментов;в конце концов, все можно рассматривать как гвоздь, не так ли?

Наш инструментарий реинжиниринга программного обеспечения DMS позволяет определять произвольный целевой язык (и имеет множество предопределенных языков, включая Java ), включает в себя все возможности преобразования источника в источник в Stratego, TXL, процедурные возможности джекпота и дополнительно предоставляет таблицы символов, информацию управления и анализа потока данных.Ребята из компилятора научили нас, что эти вещи необходимы для создания сильных компиляторов (= «анализ + оптимизация + уточнение»), и это верно и для систем генерации кода, по точно таким же причинам.Используя этот подход, вы можете генерировать код и оптимизировать его в той степени, в которой у вас есть для этого знания.Один пример, аналогичный вашим идеалам сериализации, - это создание быстрых программ чтения и записи XML для указанных XML DTD;мы сделали это с помощью DMS для Java и COBOL.

DMS использовалась для чтения / изменения / записи многих типов исходных файлов.Хороший пример, который прояснит идеи, можно найти в этом техническом документе, который показывает, как изменить код для вставки измерительных зондов: Покрытие для филиала Made Easy .Более простой, но более полный пример определения произвольных языков и преобразований для применения к нему можно найти в Как преобразовать алгебру , используя те же идеи.

4 голосов
/ 21 апреля 2011

Посмотрите на Шаблоны Java Emitter . Они позволяют создавать исходные файлы Java с использованием языка разметки. Это похоже на то, как вы можете использовать язык сценариев, чтобы выплевывать HTML, за исключением того, что вы выплевываете скомпилированный исходный код. Синтаксис для JET очень похож на JSP и поэтому не слишком сложен для понимания. Однако это может быть излишним для того, что вы пытаетесь достичь. Вот некоторые ресурсы, если вы решите пойти по этому пути:

2 голосов
/ 21 апреля 2011

Изменение того же исходного файла Java с помощью автоматически сгенерированного кода - кошмар обслуживания.Попробуйте создать новый класс, который расширяет ваш текущий класс и добавляет нужный метод.Используйте отражение для чтения из определенного пользователем класса и создания шаблонов скорости для автоматически генерируемых классов.Затем для каждого пользовательского класса генерируют свой расширяющий класс.Интегрируйте фазу генерации кода в свой жизненный цикл сборки.

Или вы можете использовать методы «улучшения байт-кода» для улучшения классов без необходимости изменения исходного кода.

Обновления:

  1. смешивание автоматически сгенерированного кода всегда создает риск того, что кто-то изменит его в будущем, чтобы просто настроить небольшое поведение.Это просто вопрос следующей сборки, когда эти изменения будут потеряны.
  2. вам придется полагаться исключительно на комментарии поверх автоматически сгенерированного источника, чтобы не допустить этого разработчики.
  3. управление версиями - допустим, вы обновили шаблон someMethod (), теперь все версии вашего исходного файла будут обновлены, даже если исходные обновления генерируются автоматически.вы увидите избыточную историю.
2 голосов
/ 21 апреля 2011

Вы можете использовать cglib для генерации кода во время выполнения.

1 голос
/ 05 августа 2013

Antlr действительно отличный инструмент, который можно очень легко использовать для преобразования исходного кода Java в исходный код Java.

1 голос
/ 21 апреля 2011

Я бы очень осторожно вставлял сгенерированный код в файлы, содержащие рукописный код. Рукописный код должен быть проверен в контроле версий, но сгенерированный код не должен быть; генерация кода должна выполняться как часть процесса сборки. Вам придется структурировать процесс сборки так, чтобы для каждого файла вы делали временную копию, вставляли в нее сгенерированный исходный код и компилировали результат, не касаясь исходного исходного файла, над которым работают разработчики.

1 голос
/ 21 апреля 2011

Итерирование по полям и определение someMethod - довольно расплывчатая формулировка проблемы, поэтому трудно дать вам очень полезный ответ, но поддержка рефакторинга в Eclipse предоставляет несколько отличных инструментов. Он даст вам конструкторы, которые инициализируют выбранный набор определенных членов, а также определит метод toString для вас.

Я не знаю, какие еще некоторые методы () вы бы хотели рассмотреть, но для вас есть начало.

...