Bug 12326 - Bad line number information returned from CompilationUnit with no trailing newline
Summary: Bad line number information returned from CompilationUnit with no trailing ne...
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 2.0   Edit
Hardware: Other other
: P3 normal (vote)
Target Milestone: 2.0 M5   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 12208
  Show dependency tree
 
Reported: 2002-03-26 17:59 EST by Jared Burns CLA
Modified: 2002-03-27 14:52 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jared Burns CLA 2002-03-26 17:59:12 EST
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];
Comment 1 Philipe Mulet CLA 2002-03-27 05:02:28 EST
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
Comment 2 Olivier Thomann CLA 2002-03-27 14:41:55 EST
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.
Comment 3 Olivier Thomann CLA 2002-03-27 14:48:53 EST
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.
Comment 4 Olivier Thomann CLA 2002-03-27 14:52:40 EST
Regression tests added in the DOM tests (see test0314).
Fixed and released.