From dc677d2b36df5694e059f10d9cdd15fbb42f65b1 Mon Sep 17 00:00:00 2001 From: Jason Faust Date: Tue, 16 Oct 2018 15:37:17 -0400 Subject: [PATCH] Bug fixes to parsing of Eclipse output Fix parsing of multi-line source context in text log Counting of columns changed to one based though one after --- .../compiler/eclipse/EcjResponseParser.java | 10 + .../compiler/eclipse/EcjTextLogParser.java | 37 ++- .../eclipse/EcjResponseParserTest.java | 69 ++++-- .../eclipse/EcjTextLogParserTest.java | 71 ++++-- .../compiler/eclipse/eclipse-withinfo.txt | 42 ++++ .../compiler/eclipse/eclipse-withinfo.xml | 230 ++++++++++++++++++ 6 files changed, 398 insertions(+), 61 deletions(-) create mode 100644 plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.txt create mode 100644 plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.xml diff --git a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParser.java b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParser.java index a0da30be..acde7465 100644 --- a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParser.java +++ b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParser.java @@ -103,7 +103,17 @@ private void decodeProblem(List 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); diff --git a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParser.java b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParser.java index f62cbdc8..30f1f636 100644 --- a/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParser.java +++ b/plexus-compilers/plexus-compiler-eclipse/src/main/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParser.java @@ -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; @@ -33,7 +32,7 @@ public List parse(File logFile, boolean errorsAsWarnings) throw try (BufferedReader in = new BufferedReader( new InputStreamReader(new FileInputStream(logFile), StandardCharsets.UTF_8))) { String line; - Queue buffer = new LinkedList<>(); + List buffer = new LinkedList<>(); boolean header = true; while ((line = in.readLine()) != null) { @@ -56,14 +55,18 @@ public List parse(File logFile, boolean errorsAsWarnings) throw return ret; } - private CompilerMessage parse(Queue buffer, boolean errorsAsWarnings) { - String str; + private CompilerMessage parse(List 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); @@ -72,21 +75,17 @@ private CompilerMessage parse(Queue 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); diff --git a/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParserTest.java b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParserTest.java index 52e41d6c..87614509 100644 --- a/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParserTest.java +++ b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjResponseParserTest.java @@ -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. @@ -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 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); } /** @@ -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 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 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) { diff --git a/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParserTest.java b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParserTest.java index f23f847c..8da0ad6d 100644 --- a/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParserTest.java +++ b/plexus-compilers/plexus-compiler-eclipse/src/test/java/org/codehaus/plexus/compiler/eclipse/EcjTextLogParserTest.java @@ -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. @@ -32,15 +33,17 @@ public void testParse() throws Exception { EcjTextLogParser parser = new EcjTextLogParser(); List 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); } /** @@ -57,15 +60,17 @@ public void testParseErrorsAsWarnings() throws Exception { EcjTextLogParser parser = new EcjTextLogParser(); List 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); } /** @@ -79,10 +84,34 @@ public void testHeaderErrors() throws Exception { assertTrue("Input log file missing", logFile.exists()); EcjTextLogParser parser = new EcjTextLogParser(); - List cm = parser.parse(logFile, true); + List 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 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) { diff --git a/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.txt b/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.txt new file mode 100644 index 00000000..bc7102ad --- /dev/null +++ b/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.txt @@ -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) diff --git a/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.xml b/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.xml new file mode 100644 index 00000000..0204c553 --- /dev/null +++ b/plexus-compilers/plexus-compiler-eclipse/src/test/resources/org/codehaus/plexus/compiler/eclipse/eclipse-withinfo.xml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +