Переопределение номера строки в сгенерированном источнике Java

Есть ли способ переопределить номера строк в Java (например, с помощью какой-либо директивы препроцессора)?

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

С# имеет директиву #line, и я успешно использовал ее для сопоставления номеров строк из исходного файла в скомпилированный результат. Мне нужно то же самое для Java.

Спасибо!

Ответы

Ответ 1

Используя Janino, вы можете получить от Scanner и переопределить метод location(). Этот метод возвращает объект Location. Вы можете переопределить метод read() для поиска аннотаций, например, в комментариях (добавленных при генерации кода), содержащих информацию о номере линии.

Вы просто передаете свой сканер методу SimpleCompiler.cook(), и вы можете контролировать, какое имя файла, строка и столбец сообщаются при ошибке.

Ответ 2

Я никогда не видел, чтобы он использовался для других, чем JSP, но JSR-45 был разработан для этой цели для любого исходного языка, Процесс включает создание второго файла в специальном формате ( "SMAP" ), который отображает номера строк в исходном источнике на номера строк в сгенерированном исходном коде Java.

Ответ 3

К сожалению, нет, в Java нет эквивалентной директивы #line. Лучшее, что вы можете сделать, это изменить источник после его создания путем удаления/вставки новых строк в соответствии с реальным источником (или изменить генератор кода). Или, вы можете изменить номера строк, хранящихся в файлах двоичного класса, после их компиляции, но это, вероятно, будет еще более болезненным.

Ответ 4

Вместо того, чтобы генерировать Java-код как ваш промежуточный язык, вы можете попробовать использовать ассемблер JVM. Jasmin имеет хороший синтаксис, и вы можете вставлять директивы .line в соответствующие места вашего кода. Вы также можете указать исходный исходный файл с помощью директивы .source.

Конечно, переход на ассемблер может быть более сложным, чем это стоит:)

Ответ 5

Нет простого решения. Одним из способов решения этой проблемы было бы создание карты номеров строк с [вашего языка] на Java при генерации кода. Вы можете передать вывод компилятора и использовать карту, чтобы заменить номера строк в строке строки вашей строки.