Overriding line number in generated Java source
Asked Answered
P

5

15

Is there any way to override the line numbers in Java (e.g., by using some kind of preprocessor directive)?

I am "compiling" a high-level language, down to Java byte code using Janino. I need compiler errors to report the line from the original file, not the generated Java code.

C# has the #line directive, and I've successfully exploited it to map line numbers from a source file to the compiled result. I need the same for Java.

Thanks!

Paraplegia answered 10/2, 2009 at 3:8 Comment(1)
If you're compiling to Java byte code, then you should know the line numbers. Or do you mean that you're compiling to Java and the Java compiler is taking that and compiling to byte code?Phototypography
P
4

Using Janino you can derive from Scanner and override the location() method. This method returns a Location object. You can override the read() method to look for annotations, within comments for instance (added during code generation), that hold line number information.

You simply pass your scanner to the SimpleCompiler.cook() method and you can control what filename, line and column get reported on error.

Paraplegia answered 15/3, 2009 at 13:4 Comment(0)
M
10

I've never seen it used for other than JSP, but JSR-45 was designed to be used for this purpose for any source language. The process involves creating a second file in a special format ("SMAP") that maps line numbers in the original source to line numbers in the generated Java source code.

Marty answered 10/2, 2009 at 3:25 Comment(1)
Despite searching for days for a Java replacement for #line directives, I never knew this existed. Thanks for the link.Mikemikel
G
4

Unfortunately, no, there isn't an equivalent #line directive in Java. The best you can do is modify the source after it's been generated by deleting/inserting newlines to match the real source (or modify the code generator). Or, you could modify the line numbers stored in the binary class files after they've been compiled, but that will likely be even more painful.

Gloom answered 10/2, 2009 at 3:13 Comment(0)
P
4

Using Janino you can derive from Scanner and override the location() method. This method returns a Location object. You can override the read() method to look for annotations, within comments for instance (added during code generation), that hold line number information.

You simply pass your scanner to the SimpleCompiler.cook() method and you can control what filename, line and column get reported on error.

Paraplegia answered 15/3, 2009 at 13:4 Comment(0)
D
3

Instead of generating Java code as your intermediate language, you could try using JVM assembler. Jasmin has nice syntax, and you are free to insert .line directives at appropriate places in your code. You can also can also specify the original source file using the the .source directive.

Granted, going the assembler route may be more hassle than it's worth :)

Darling answered 10/2, 2009 at 10:1 Comment(0)
P
1

There is no simple solution. One workaround would be to generate a line number map from [your language] to Java when you generate the code. You can pipe the compiler output and use the map to replace Java's line numbers with your line numbers.

Phototypography answered 10/2, 2009 at 3:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.