Community
Participate
Working Groups
Classfiles with no trailing newline seem to get bad linetables. This breaks evaluation in all such types (VectorTest, for instance). For example (with no trailing newline): public class Foo { public static void main(String args[]) { int x= 3;}} The AST node (TypeDeclaration) for this class has start position 0 and length 71. We then try to get line number information from the corresponding compilation unit CompilationUnit.lineNumber(0) returns 1 CompilationUnit.lineNumber(70) returns 1 We've stepped into the lineNumber call and the CompilationUnit's line table only has a single entry (18). The call with lineNumber of 0 returns from here: if (position <= lineEndTable[low]) { // position illegal or before the first line delimiter return 1; } The call with lineNumber of 70 returns from here: if (position > lineEndTable[length - 1]) { // position beyond the end of last line return 1; } If the trailing newline is added to the file, it returns line numbers 1 and 2 Incidentally, the comment on the line table is confusing. Is the example correct? /** * Line end table. If <code>lineEndTable[i] == p</code> then the * line number <code>i+1</code> ends at character position * <code>p</code>. Except for the last line, the positions are that * of the last character of the line delimiter. * For example, the source string <code>A\nB\nC</code> has * line end table {1, 3, 4}. */ private int[] lineEndTable = new int[0];
Indeed, the mapping is wrong, it should read: if (position > lineEndTable[length - 1]) { // position beyond the end of last line return length; } Also fixed comment. Fixed
The fix doesn't work. I think we should have: int hi = length - 1; if (position > lineEndTable[hi]) { // position beyond the last line separator if (position > getStartPosition() + getLength()) { // this is beyond the end of the source length return 1; } else { return length + 1; } } The line ends collection is zero-based, but the line numbers are 1-based. Then we need to add one.
My final proposal is: int hi = length - 1; if (position > lineEndTable[hi]) { // position beyond the last line separator if (position >= getStartPosition() + getLength()) { // this is beyond the end of the source length return 1; } else { return length + 1; } } I misused a > for a >=. This fits to the specification of the method.
Regression tests added in the DOM tests (see test0314). Fixed and released.