Skip to content

Commit

Permalink
Bug fixes to parsing of Eclipse output
Browse files Browse the repository at this point in the history
Fix parsing of multi-line source context in text log
Counting of columns changed to one based though one after
  • Loading branch information
jftsunami committed Oct 16, 2018
1 parent 4f27ca7 commit dc677d2
Show file tree
Hide file tree
Showing 6 changed files with 398 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,17 @@ private void decodeProblem(List<CompilerMessage> list, String sourcePath, XMLStr
}
if("source_context".equals(xsr.getLocalName())) {
column = getInt(xsr, "sourceStart");
if (column != -1) {
column += 1; // Offset to 1-based index
} else {
column = 0;
}
endCol = getInt(xsr, "sourceEnd");
if (endCol != -1) {
endCol += 2; // Offset to 1-based index with one-after counting
} else {
endCol = 0;
}
}
ignoreTillEnd(xsr);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -33,7 +32,7 @@ public List<CompilerMessage> parse(File logFile, boolean errorsAsWarnings) throw
try (BufferedReader in = new BufferedReader(
new InputStreamReader(new FileInputStream(logFile), StandardCharsets.UTF_8))) {
String line;
Queue<String> buffer = new LinkedList<>();
List<String> buffer = new LinkedList<>();
boolean header = true;

while ((line = in.readLine()) != null) {
Expand All @@ -56,14 +55,18 @@ public List<CompilerMessage> parse(File logFile, boolean errorsAsWarnings) throw
return ret;
}

private CompilerMessage parse(Queue<String> buffer, boolean errorsAsWarnings) {
String str;
private CompilerMessage parse(List<String> buffer, boolean errorsAsWarnings) {

// Kind, File, Line
Kind kind = null;
String file = null;
int lineNum = 0;
if ((str = buffer.poll()) != null) {
int startCol = 0;
int endCol = 0;
String message = null;

// First line, kind, file, lineNum
if (buffer.size() > 1) {
String str = buffer.get(0);
Matcher matcher = levelFile.matcher(str);
if (matcher.find()) {
file = matcher.group(2);
Expand All @@ -72,21 +75,17 @@ private CompilerMessage parse(Queue<String> buffer, boolean errorsAsWarnings) {
}
}

// Discard second line
buffer.poll();

// Column start and end
int startCol = 0;
int endCol = 0;
if ((str = buffer.poll()) != null) {
startCol = str.indexOf('^') - 1;
endCol = str.lastIndexOf('^') - 1;
// Last line, message
if (buffer.size() >= 2) {
String str = buffer.get(buffer.size() - 1);
message = str.trim();
}

// Output message
String message = null;
if ((str = buffer.poll()) != null) {
message = str.trim();
// 2nd to last line, columns
if (buffer.size() >= 3) {
String str = buffer.get(buffer.size() - 2);
startCol = str.indexOf('^');
endCol = str.lastIndexOf('^') + 1;
}

return new CompilerMessage(file, kind, lineNum, startCol, lineNum, endCol, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
*/
public class EcjResponseParserTest extends PlexusTestCase {

private static final String LOG_FILE = "src/test/resources/org/codehaus/plexus/compiler/eclipse/3.15.0.log.xml";
private static final String LOG_FILE_1 = "src/test/resources/org/codehaus/plexus/compiler/eclipse/3.15.0.log.xml";
private static final String LOG_FILE_2 = "src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.xml";

/**
* Test for example compiler output in XML format.
Expand All @@ -25,21 +26,23 @@ public class EcjResponseParserTest extends PlexusTestCase {
*/
@Test
public void testParse() throws Exception {
File logFile = getTestFile(LOG_FILE);
File logFile = getTestFile(LOG_FILE_1);
assertTrue("Input log file missing", logFile.exists());

EcjResponseParser parser = new EcjResponseParser();
List<CompilerMessage> cm = parser.parse(logFile, false);

checkCompilerMessage(cm.get(0), "Bad.java", Kind.ERROR, 6, 0, 4);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.ERROR, 6, 0, 4);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 4, 29);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.ERROR, 4, 7, 16);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.ERROR, 12, 20, 30);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 10, 10);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.ERROR, 5, 7, 12);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.ERROR, 7, 0, 2);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.ERROR, 3, 13, 26);
assertEquals("Wrong message count", 9, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.ERROR, 6, 1, 6);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.ERROR, 6, 1, 6);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 5, 31);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.ERROR, 4, 8, 18);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.ERROR, 12, 21, 32);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 11, 12);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.ERROR, 5, 8, 14);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.ERROR, 7, 1, 4);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.ERROR, 3, 14, 28);
}

/**
Expand All @@ -50,21 +53,45 @@ public void testParse() throws Exception {
*/
@Test
public void testParseErrorsAsWarnings() throws Exception {
File logFile = getTestFile(LOG_FILE);
File logFile = getTestFile(LOG_FILE_1);
assertTrue("Input log file missing", logFile.exists());

EcjResponseParser parser = new EcjResponseParser();
List<CompilerMessage> cm = parser.parse(logFile, true);

checkCompilerMessage(cm.get(0), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 4, 29);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.WARNING, 4, 7, 16);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.WARNING, 12, 20, 30);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 10, 10);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.WARNING, 5, 7, 12);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.WARNING, 7, 0, 2);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.WARNING, 3, 13, 26);
assertEquals("Wrong message count", 9, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.WARNING, 6, 1, 6);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.WARNING, 6, 1, 6);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 5, 31);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.WARNING, 4, 8, 18);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.WARNING, 12, 21, 32);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 11, 12);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.WARNING, 5, 8, 14);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.WARNING, 7, 1, 4);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.WARNING, 3, 14, 28);
}

/**
* Tests for parsing the contents of {@value #LOG_FILE_2}.
*
* @throws Exception on test failure.
*/
public void testParse2() throws Exception {
File logFile = getTestFile(LOG_FILE_2);
assertTrue("Input log file missing", logFile.exists());

EcjResponseParser parser = new EcjResponseParser();
List<CompilerMessage> cm = parser.parse(logFile, false);

assertEquals("Wrong message count", 6, cm.size());

checkCompilerMessage(cm.get(0), "ECE.java", Kind.ERROR, 8, 13, 17);
checkCompilerMessage(cm.get(1), "ECE.java", Kind.ERROR, 16, 8, 41);
checkCompilerMessage(cm.get(2), "ECE.java", Kind.WARNING, 22, 9, 10);
checkCompilerMessage(cm.get(3), "ECE.java", Kind.WARNING, 27, 8, 41);
checkCompilerMessage(cm.get(4), "ECE.java", Kind.NOTE, 33, 13, 19);
checkCompilerMessage(cm.get(5), "ECE.java", Kind.NOTE, 35, 1, 96);
}

private void checkCompilerMessage(CompilerMessage cm, String file, Kind kind, int line, int startCol, int endCol) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public class EcjTextLogParserTest extends PlexusTestCase {

private static final String LOG_FILE_1 = "src/test/resources/org/codehaus/plexus/compiler/eclipse/3.15.0.log.txt";
private static final String LOG_FILE_2 = "src/test/resources/org/codehaus/plexus/compiler/eclipse/log-text-0.log";
private static final String LOG_FILE_3 = "src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.txt";

/**
* Test for example compiler output in non-XML format.
Expand All @@ -32,15 +33,17 @@ public void testParse() throws Exception {
EcjTextLogParser parser = new EcjTextLogParser();
List<CompilerMessage> cm = parser.parse(logFile, false);

checkCompilerMessage(cm.get(0), "Bad.java", Kind.ERROR, 6, 0, 4);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.ERROR, 6, 0, 4);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 4, 29);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.ERROR, 4, 7, 16);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.ERROR, 12, 20, 30);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 10, 10);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.ERROR, 5, 7, 12);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.ERROR, 7, 0, 2);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.ERROR, 3, 13, 26);
assertEquals("Wrong message count", 9, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.ERROR, 6, 1, 6);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.ERROR, 6, 1, 6);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 5, 31);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.ERROR, 4, 8, 18);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.ERROR, 12, 21, 32);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 11, 12);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.ERROR, 5, 8, 14);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.ERROR, 7, 1, 4);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.ERROR, 3, 14, 28);
}

/**
Expand All @@ -57,15 +60,17 @@ public void testParseErrorsAsWarnings() throws Exception {
EcjTextLogParser parser = new EcjTextLogParser();
List<CompilerMessage> cm = parser.parse(logFile, true);

checkCompilerMessage(cm.get(0), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 4, 29);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.WARNING, 4, 7, 16);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.WARNING, 12, 20, 30);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 10, 10);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.WARNING, 5, 7, 12);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.WARNING, 7, 0, 2);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.WARNING, 3, 13, 26);
assertEquals("Wrong message count", 9, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.WARNING, 6, 1, 6);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.WARNING, 6, 1, 6);
checkCompilerMessage(cm.get(2), "Deprecation.java", Kind.WARNING, 7, 5, 31);
checkCompilerMessage(cm.get(3), "ExternalDeps.java", Kind.WARNING, 4, 8, 18);
checkCompilerMessage(cm.get(4), "ExternalDeps.java", Kind.WARNING, 12, 21, 32);
checkCompilerMessage(cm.get(5), "Info.java", Kind.NOTE, 5, 11, 12);
checkCompilerMessage(cm.get(6), "ReservedWord.java", Kind.WARNING, 5, 8, 14);
checkCompilerMessage(cm.get(7), "UnknownSymbol.java", Kind.WARNING, 7, 1, 4);
checkCompilerMessage(cm.get(8), "WrongClassname.java", Kind.WARNING, 3, 14, 28);
}

/**
Expand All @@ -79,10 +84,34 @@ public void testHeaderErrors() throws Exception {
assertTrue("Input log file missing", logFile.exists());

EcjTextLogParser parser = new EcjTextLogParser();
List<CompilerMessage> cm = parser.parse(logFile, true);
List<CompilerMessage> cm = parser.parse(logFile, false);

assertEquals("Wrong message count", 2, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.ERROR, 6, 1, 6);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.ERROR, 6, 1, 6);
}

/**
* Tests for parsing the contents of {@value #LOG_FILE_3}.
*
* @throws Exception on test failure.
*/
public void testParse3() throws Exception {
File logFile = getTestFile(LOG_FILE_3);
assertTrue("Input log file missing", logFile.exists());

EcjTextLogParser parser = new EcjTextLogParser();
List<CompilerMessage> cm = parser.parse(logFile, false);

assertEquals("Wrong message count", 6, cm.size());

checkCompilerMessage(cm.get(0), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(1), "Bad.java", Kind.WARNING, 6, 0, 4);
checkCompilerMessage(cm.get(0), "ECE.java", Kind.ERROR, 8, 13, 17);
checkCompilerMessage(cm.get(1), "ECE.java", Kind.ERROR, 16, 8, 41);
checkCompilerMessage(cm.get(2), "ECE.java", Kind.WARNING, 22, 9, 10);
checkCompilerMessage(cm.get(3), "ECE.java", Kind.WARNING, 27, 8, 41);
checkCompilerMessage(cm.get(4), "ECE.java", Kind.NOTE, 33, 13, 19);
checkCompilerMessage(cm.get(5), "ECE.java", Kind.NOTE, 35, 1, 96);
}

private void checkCompilerMessage(CompilerMessage cm, String file, Kind kind, int line, int startCol, int endCol) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# 10/15/18, 2:50:59 PM EDT
# Eclipse Compiler for Java(TM) v20180905-0317, 3.15.0, Copyright IBM Corp 2000, 2015. All rights reserved.
----------
1. ERROR in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 8)
Integer x = 0.0f;
^^^^
Type mismatch: cannot convert from float to Integer
----------
2. ERROR in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 16)
} else {
x = 20;
}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Dead code
----------
3. WARNING in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 22)
Integer x;
^
The value of the local variable x is not used
----------
4. WARNING in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 27)
} else {
x = 30;
}
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Statement unnecessarily nested within else clause. The corresponding then clause does not complete normally
----------
5. INFO in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 33)
Boolean x = 7 == 7;
^^^^^^
Comparing identical expressions
----------
6. INFO in C:\devenv\workspace\x\y\src\main\java\y\ECE.java (at line 35)
new Object() {
{
System.out.println(x);
}
};
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The allocated object is never used
----------
6 problems (2 errors, 2 warnings, 2 info)
Loading

0 comments on commit dc677d2

Please sign in to comment.