Closed tombentley closed 11 years ago
Perhaps more disturbingly, I didn't notice that the top-most frame was attributed to the last asset(true)
! (updated description to show where I mean).
The problem with the current API is that it relies on us maintaining the current position using at()
. That was bad enough initially, but now that we do things like pass around MethodDefinitionBuilders
and invoke their build()
at a later point when visiting the tree it's pretty hopeless. If we continue like this I can foresee a never-ending stream of issues. I think we need a better mechanism in the code generator for keeping track of this stuff. But I can't think of anything great. I struggle to think of ways we can effectively test this.
For debugging, we need to get the position of pretty much every thing right. http://docs.oracle.com/javase/7/docs/jdk/api/jpda/jdi/com/sun/jdi/Location.html suggests that locations can pertain to any offset within the code of a method.
We also need to decide which Tree
nodes correspond to which JCTree
nodes. For example with an invocation like:
foo
{
a = 1;
b = 2;
};
which Ceylon line does the Apply get associated with? (In this case I would argue it should be the start of the NamedArgumentList
, since that's what makes the thing an invocation in Ceylon).
I came up with a way to test this stuff by using JDI which I think will be better than producing some eye-watering JCTree dump with line number info added (i.e. easier to verify initially, and then easier to maintain).
The basic idea is that we programmatically set a breakpoint when we enter main() and then start stepping, logging everywhere we go within the target program. It's fairly easy to verify the logged locations are "correct" simply by looking at the code (and knowing, for instance about the existence of overload methods and default parameter methods). By asserting that the trace we obtain is the same as a previously verified trace file we should be able to catch regressions.
Annoyingly the OpenJDK implementation of JDI lives inside tools.jar
, which then makes other tests fail because instead of finding our compiler message file, the class loader seems to find the one inside tools.jar. So this breaks tests which make assertions about error messages produced by the compiler, for instance. Not sure what to do about that.
Can you run the test in a forked process?
Well, I guess I'll have to, because I can't figure anything else out. But that subprocess will then start another JVM as the debug target, I believe, so we'll need 2 JVMs for each test :-(
Actually, even that doesn't work, because I need JDI on the classpath for my JUnit test classes.
Fixed, at least for this particular weirdness.
We now have TraceTests which can be used to check for regressions.
If I have a method with defaulted parameters, such as this:
And I call it so that a default argument is used, e.g.
bugXXXX_1()
then the stacktrace has an additional stackframe (which seems to be related to the overload method) attributed to the given line.