覆盖生成的Java源代码中的行号

时间:2009-02-10 03:08:39

标签: java annotations code-generation janino

有没有办法覆盖Java中的行号(例如,通过使用某种预处理器指令)?

我正在使用Janino“编译”高级语言,直到Java字节代码。我需要编译器错误来报告原始文件中的行,而不是生成的Java代码。

C#有#line指令,我已成功利用它将源文件中的行号映射到编译结果。我需要相同的Java。

谢谢!

5 个答案:

答案 0 :(得分:9)

我从未见过它用于JSP以外的其他用途,但JSR-45被设计用于任何源语言。该过程涉及以特殊格式(“SMAP”)创建第二个文件,该文件将原始源中的行号映射到生成的Java源代码中的行号。

答案 1 :(得分:4)

不幸的是,不,Java中没有等效的#line指令。您可以做的最好的事情是在生成源之后通过删除/插入换行符来匹配实际源(或修改代码生成器)来修改源。或者,您可以在编译后修改存储在二进制类文件中的行号,但这可能会更加痛苦。

答案 2 :(得分:3)

您可以尝试使用JVM汇编程序,而不是生成Java代码作为中间语言。 Jasmin具有很好的语法,您可以在代码中的适当位置插入.line指令。您还可以使用.source指令指定原始源文件。

当然,走向汇编路线可能比它的价值更麻烦:)

答案 3 :(得分:3)

使用Janino,您可以从Scanner派生并覆盖location()方法。此方法返回Location对象。您可以覆盖read()方法以查找注释(例如,在代码生成期间添加),其中包含行号信息。

您只需将您的扫描程序传递给SimpleCompiler.cook()方法,即可控制错误时报告的文件名,行和列。

答案 4 :(得分:1)

没有简单的解决方案。一种解决方法是在生成代码时从[您的语言]生成一个行号映射到Java。您可以管道编译器输出并使用映射将Java的行号替换为行号。