Skip to content

Commit 1a4fa95

Browse files
committed
Bugfix: caret error marks in compiler output too short
This very old bug in EclipseAdapterUtils calculated the '^' caret error marks incorrectly. The marks were too short by the length of the previously cut off indentation, but actually in the corresponding 'for' loop they must not be considered at all, because the loop only calculates the length, which is independent of any previous indentation. Signed-off-by: Alexander Kriegisch <[email protected]>
1 parent 953a831 commit 1a4fa95

File tree

1 file changed

+70
-53
lines changed

1 file changed

+70
-53
lines changed

org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/core/builder/EclipseAdapterUtils.java

Lines changed: 70 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,17 @@ public class EclipseAdapterUtils {
2929

3030
// XXX some cut-and-paste from eclipse sources
3131
public static String makeLocationContext(ICompilationUnit compilationUnit, IProblem problem) {
32-
// extra from the source the innacurate token
33-
// and "highlight" it using some underneath ^^^^^
34-
// put some context around too.
32+
// Extract the erroneous token plus some context around it from the beginning of the first to the end of the last
33+
// problematic line. Usually, it will be a single line, but not necessarily. After extraction, highlight the
34+
// erroneous token, "underlining" it withthe appropriate number of carets ('^').
35+
//
36+
// This code assumes, that the console font is fixed size.
3537

36-
// this code assumes that the font used in the console is fixed size
37-
38-
// sanity .....
38+
// Sanity checks
3939
int startPosition = problem.getSourceStart();
4040
int endPosition = problem.getSourceEnd();
4141

42-
if ((startPosition > endPosition) || ((startPosition <= 0) && (endPosition <= 0)) || compilationUnit == null)
42+
if (startPosition > endPosition || startPosition <= 0 && endPosition <= 0 || compilationUnit == null)
4343
//return Util.bind("problem.noSourceInformation"); //$NON-NLS-1$
4444
return "(no source information available)";
4545

@@ -53,57 +53,74 @@ public static String makeLocationContext(ICompilationUnit compilationUnit, IProb
5353
// (the code still works but the display is not optimal !)
5454

5555
// compute the how-much-char we are displaying around the inaccurate token
56-
int begin = startPosition >= source.length ? source.length - 1 : startPosition;
57-
if (begin == -1)
58-
return "(no source information available)"; // Dont like this - why does it occur? pr152835
59-
int relativeStart = 0;
60-
int end = endPosition >= source.length ? source.length - 1 : endPosition;
61-
int relativeEnd = 0;
62-
label: for (relativeStart = 0;; relativeStart++) {
63-
if (begin == 0)
64-
break label;
65-
if ((source[begin - 1] == '\n') || (source[begin - 1] == '\r'))
66-
break label;
67-
begin--;
56+
int contextStart = startPosition >= source.length ? source.length - 1 : startPosition;
57+
if (contextStart == -1)
58+
return "(no source information available)"; // Don't like this - why does it occur? pr152835
59+
int contextEnd = endPosition >= source.length ? source.length - 1 : endPosition;
60+
int problemLength = contextEnd - contextStart + 1;
61+
int trimLeftIndex = 0;
62+
char c;
63+
while (
64+
trimLeftIndex <= problemLength &&
65+
((c = source[contextStart + trimLeftIndex]) == TAB || c == SPACE)
66+
) {
67+
trimLeftIndex++;
6868
}
69-
label: for (relativeEnd = 0;; relativeEnd++) {
70-
if ((end + 1) >= source.length)
71-
break label;
72-
if ((source[end + 1] == '\r') || (source[end + 1] == '\n')) {
73-
break label;
74-
}
75-
end++;
69+
contextStart += trimLeftIndex;
70+
problemLength -= trimLeftIndex;
71+
72+
// Find the beginning of the first line containing the problem (contextStart)
73+
// as well as the relative problem start offset (problemStartOffset) from there
74+
int problemStartOffset;
75+
for (problemStartOffset = 0; ; problemStartOffset++) {
76+
if (contextStart == 0)
77+
break;
78+
if ((c = source[contextStart - 1]) == '\n' || c == '\r')
79+
break;
80+
contextStart--;
7681
}
77-
// extract the message form the source
78-
char[] extract = new char[end - begin + 1];
79-
System.arraycopy(source, begin, extract, 0, extract.length);
80-
char c;
81-
// remove all SPACE and TAB that begin the error message...
82-
int trimLeftIndex = 0;
83-
while ((((c = extract[trimLeftIndex++]) == TAB) || (c == SPACE)) && trimLeftIndex < extract.length) {
82+
83+
// Find the end of the last line containing the problem (contextEnd)
84+
// as well as the relative problem end offset (problemEndOffset) from there
85+
int problemEndOffset;
86+
for (problemEndOffset = 0; ; problemEndOffset--) {
87+
if (contextEnd + 1 >= source.length)
88+
break;
89+
if ((c = source[contextEnd + 1]) == '\r' || c == '\n')
90+
break;
91+
contextEnd++;
92+
}
93+
94+
// Extract the problematic lines of code from the source
95+
char[] extract = new char[contextEnd - contextStart + 1];
96+
System.arraycopy(source, contextStart, extract, 0, extract.length);
97+
98+
// Dedent (left-trim) the first line, i.e. remove leading spaces and tabs
99+
trimLeftIndex = 0;
100+
while (
101+
trimLeftIndex < extract.length &&
102+
((c = extract[trimLeftIndex]) == TAB || c == SPACE)
103+
) {
104+
trimLeftIndex++;
84105
}
85106
if (trimLeftIndex >= extract.length)
86-
return new String(extract) + "\n";
87-
System.arraycopy(extract, trimLeftIndex - 1, extract = new char[extract.length - trimLeftIndex + 1], 0, extract.length);
88-
relativeStart -= trimLeftIndex;
89-
// buffer spaces and tabs in order to reach the error position
107+
return new String(extract) + "\n"; // TODO: Shouldn't it return "" or "\n"?
108+
System.arraycopy(extract, trimLeftIndex, extract = new char[extract.length - trimLeftIndex], 0, extract.length);
109+
problemStartOffset -= trimLeftIndex;
110+
111+
// Insert spaces to reach the error position
90112
int pos = 0;
91-
char[] underneath = new char[extract.length]; // can't be bigger
92-
for (int i = 0; i <= relativeStart; i++) {
93-
if (extract[i] == TAB) {
94-
underneath[pos++] = TAB;
95-
} else {
96-
underneath[pos++] = SPACE;
97-
}
98-
}
99-
// mark the error position
100-
for (int i = startPosition + trimLeftIndex; // AMC if we took stuff off the start, take it into account!
101-
i <= (endPosition >= source.length ? source.length - 1 : endPosition); i++)
102-
underneath[pos++] = MARK;
103-
// resize underneathto remove 'null' chars
104-
System.arraycopy(underneath, 0, underneath = new char[pos], 0, pos);
105-
106-
return new String(extract) + "\n" + new String(underneath); //$NON-NLS-2$ //$NON-NLS-1$
113+
char[] underline = new char[extract.length]; // can't be bigger
114+
for (int i = 0; i < problemStartOffset; i++)
115+
underline[pos++] = SPACE;
116+
// Underline the error position with a '^^^^^' character sequence
117+
for (int i = 0; i < problemLength; i++)
118+
underline[pos++] = MARK;
119+
120+
// Resize to remove trailing NUL characters
121+
System.arraycopy(underline, 0, underline = new char[problemStartOffset + problemLength], 0, pos);
122+
123+
return new String(extract) + "\n" + new String(underline); //$NON-NLS-2$ //$NON-NLS-1$
107124
}
108125

109126
/**

0 commit comments

Comments
 (0)