From 0482006f9decc003a54969efd999279d4ff02fa0 Mon Sep 17 00:00:00 2001 From: Alexander Bubenchikov Date: Tue, 19 Feb 2019 17:30:12 +0300 Subject: [PATCH] IDEA-207490, IDEA-207493 - fix navigation and kotlin files --- .../output/MavenLoggedEventParser.java | 1 - .../output/MavenOutputParserProvider.java | 5 +- .../output/events/BuildErrorNotification.java | 73 ++++++++++++++----- ...ventParser.java => CommonErrorParser.java} | 18 ++--- .../events/JavaBuildErrorNotification.java | 8 ++ .../events/KotlinBuildErrorNotification.java | 8 ++ .../output/MavenBuildToolLogTestUtils.java | 2 +- .../events/TestBuildErrorNotification.java | 30 ++++++++ 8 files changed, 111 insertions(+), 34 deletions(-) rename plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/{OOMEventParser.java => CommonErrorParser.java} (67%) create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/JavaBuildErrorNotification.java create mode 100644 plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/KotlinBuildErrorNotification.java create mode 100644 plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/TestBuildErrorNotification.java diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLoggedEventParser.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLoggedEventParser.java index 8847f276d78c..34d0cc1fdb99 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLoggedEventParser.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenLoggedEventParser.java @@ -11,7 +11,6 @@ import java.util.function.Consumer; @ApiStatus.Experimental public interface MavenLoggedEventParser { - String COMPILER_MESSAGES_GROUP = "Java compiler"; boolean supportsType(@Nullable LogMessageType type); diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenOutputParserProvider.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenOutputParserProvider.java index 814a9b82dd40..f30479dd670a 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenOutputParserProvider.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenOutputParserProvider.java @@ -29,10 +29,11 @@ public class MavenOutputParserProvider implements ExternalSystemOutputParserProv return new MavenLogOutputParser(taskId, ContainerUtil.list( new ArtifactDownloadScanning(), - new BuildErrorNotification(), + new JavaBuildErrorNotification(), + new KotlinBuildErrorNotification(), new ProjectScanning(), new WarningNotifier(), - new OOMEventParser() + new CommonErrorParser() )); } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/BuildErrorNotification.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/BuildErrorNotification.java index 7a65b8b05f6f..adc03ed3884d 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/BuildErrorNotification.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/BuildErrorNotification.java @@ -7,6 +7,8 @@ import com.intellij.build.events.MessageEvent; import com.intellij.build.events.impl.FileMessageEventImpl; import com.intellij.build.events.impl.MessageEventImpl; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.util.SystemInfo; +import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.externalSystemIntegration.output.LogMessageType; @@ -18,8 +20,17 @@ import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class BuildErrorNotification implements MavenLoggedEventParser { - private static final Pattern LINE_AND_COLUMN = Pattern.compile("[^\\d]*?(\\d+)[^\\d]*(\\d*)[^\\d]*"); +public abstract class BuildErrorNotification implements MavenLoggedEventParser { + private static final Pattern LINE_AND_COLUMN = Pattern.compile("[^\\d]*?(\\d+)[^\\d]*(\\d*)[])]"); + private final String myLanguage; + private final String myExtension; + private final String myMessageGroup; + + protected BuildErrorNotification(String language, String extension, String messageGroup) { + myLanguage = language; + myExtension = extension; + myMessageGroup = messageGroup; + } @Override public boolean supportsType(@Nullable LogMessageType type) { @@ -31,38 +42,61 @@ public class BuildErrorNotification implements MavenLoggedEventParser { @NotNull MavenLogEntryReader.MavenLogEntry logLine, @NotNull MavenLogEntryReader logEntryReader, @NotNull Consumer messageConsumer) { + String line = logLine.getLine(); - int fileNameIdx = line.indexOf(".java:"); + if (line.endsWith("java.lang.OutOfMemoryError")) { + messageConsumer.accept(new MessageEventImpl(id, MessageEvent.Kind.ERROR, myMessageGroup, + "Out of memory.", line)); + return true; + } + int fileNameIdx = line.indexOf("." + myExtension + ":"); if (fileNameIdx < 0) { - return notifyError(id, line, messageConsumer); + return false; } int fullFileNameIdx = line.indexOf(":", fileNameIdx); if (fullFileNameIdx < 0) { - return notifyError(id, line, messageConsumer); + return false; } - File parsedFile = new File(line.substring(0, fileNameIdx) + ".java"); - int messageIdx = line.indexOf(' ', fullFileNameIdx); - FilePosition position = withLineAndColumn(parsedFile, line.substring(fullFileNameIdx, messageIdx), messageIdx, fullFileNameIdx); + int start = SystemInfo.isWindows && line.charAt(0) == '/' ? 1 : 0; + String filename = FileUtil.toSystemDependentName(line.substring(start, fileNameIdx) + "." + myExtension); + + File parsedFile = new File(filename); + String lineWithPosition = line.substring(fullFileNameIdx); + Matcher matcher = LINE_AND_COLUMN.matcher(lineWithPosition); + String message; + FilePosition position; + if (matcher.find()) { + position = withLineAndColumn(parsedFile, matcher); + message = lineWithPosition.substring(matcher.end()); + } + else { + position = new FilePosition(parsedFile, 0, 0); + message = lineWithPosition; + } + + + String errorMessage = getErrorMessage(position, message); messageConsumer - .accept(new FileMessageEventImpl(id, MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, line.substring(messageIdx), line, + .accept(new FileMessageEventImpl(id, MessageEvent.Kind.ERROR, myMessageGroup, errorMessage, errorMessage, position)); return true; } - private static boolean notifyError(ExternalSystemTaskId id, - String line, - Consumer messageConsumer) { - messageConsumer - .accept(new MessageEventImpl(id, MessageEvent.Kind.ERROR, null, line, line)); - return true; + @NotNull + private String getErrorMessage(@NotNull FilePosition position, @NotNull String message) { + if (position.getStartLine() == 0) { + return "Error: " + myLanguage + ":" + message; + } + if (position.getStartColumn() == 0) { + return "Error:(" + (position.getStartLine() + 1) + ") " + myLanguage + ":" + message; + } + return "Error:(" + (position.getStartLine() + 1) + "," + (position.getStartColumn() + 1) + ") " + myLanguage + ":" + message; } @NotNull - private static FilePosition withLineAndColumn(File toTest, String line, int spaceAfterFileIdx, int fullFileNameIdx) { - if (spaceAfterFileIdx < 0) return new FilePosition(toTest, 0, 0); - Matcher matcher = LINE_AND_COLUMN.matcher(line); + private static FilePosition withLineAndColumn(File toTest, Matcher matcher) { try { - if (matcher.matches() && matcher.groupCount() == 2) { + if (matcher.groupCount() == 2) { if (matcher.start(2) < 0) { return new FilePosition(toTest, Integer.valueOf(matcher.group(1)) - 1, 0); } @@ -70,7 +104,6 @@ public class BuildErrorNotification implements MavenLoggedEventParser { return new FilePosition(toTest, Integer.valueOf(matcher.group(1)) - 1, Integer.valueOf(matcher.group(2)) - 1); } } - return new FilePosition(toTest, 0, 0); } catch (NumberFormatException ignore) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/OOMEventParser.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/CommonErrorParser.java similarity index 67% rename from plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/OOMEventParser.java rename to plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/CommonErrorParser.java index 8bc67a9fc211..066f6e99b947 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/OOMEventParser.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/CommonErrorParser.java @@ -1,10 +1,10 @@ -// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package org.jetbrains.idea.maven.externalSystemIntegration.output.events; import com.intellij.build.events.BuildEvent; import com.intellij.build.events.MessageEvent; import com.intellij.build.events.impl.MessageEventImpl; import com.intellij.openapi.externalSystem.model.task.ExternalSystemTaskId; +import com.intellij.openapi.util.text.StringUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.maven.externalSystemIntegration.output.LogMessageType; @@ -13,10 +13,10 @@ import org.jetbrains.idea.maven.externalSystemIntegration.output.MavenLoggedEven import java.util.function.Consumer; -public class OOMEventParser implements MavenLoggedEventParser { +public class CommonErrorParser implements MavenLoggedEventParser { @Override public boolean supportsType(@Nullable LogMessageType type) { - return true; + return type == LogMessageType.ERROR; } @Override @@ -24,12 +24,10 @@ public class OOMEventParser implements MavenLoggedEventParser { @NotNull MavenLogEntryReader.MavenLogEntry logLine, @NotNull MavenLogEntryReader logEntryReader, @NotNull Consumer messageConsumer) { - String line = logLine.getLine(); - if (line.endsWith("java.lang.OutOfMemoryError")) { - messageConsumer.accept(new MessageEventImpl(id, MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, - "Out of memory.", line)); - return true; - } - return false; + String line = logLine.getLine().trim(); + line = StringUtil.trimEnd(line, ":"); + messageConsumer + .accept(new MessageEventImpl(id, MessageEvent.Kind.ERROR, null, line, line)); + return true; } } diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/JavaBuildErrorNotification.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/JavaBuildErrorNotification.java new file mode 100644 index 000000000000..aed33a065e37 --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/JavaBuildErrorNotification.java @@ -0,0 +1,8 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.externalSystemIntegration.output.events; + +public class JavaBuildErrorNotification extends BuildErrorNotification { + public JavaBuildErrorNotification() { + super("java", "java", "Java compiler"); + } +} diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/KotlinBuildErrorNotification.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/KotlinBuildErrorNotification.java new file mode 100644 index 000000000000..a6c18fd28e6f --- /dev/null +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/KotlinBuildErrorNotification.java @@ -0,0 +1,8 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.externalSystemIntegration.output.events; + +public class KotlinBuildErrorNotification extends BuildErrorNotification { + public KotlinBuildErrorNotification() { + super("kotlin", "kt", "Kotlin compiler plugin"); + } +} diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenBuildToolLogTestUtils.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenBuildToolLogTestUtils.java index 62345f70e790..aebfc62851bb 100644 --- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenBuildToolLogTestUtils.java +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/MavenBuildToolLogTestUtils.java @@ -215,7 +215,7 @@ public abstract class MavenBuildToolLogTestUtils extends UsefulTestCase { @Override public void describeTo(@NotNull Description description) { - description.appendText("Expected FileEvent " + myMessage + "at " + myFileName + ":" + myLine + ":" + myColumn); + description.appendText("Expected FileMessageEventImpl \"" + myMessage + "\" at " + myFileName + ":" + myLine + ":" + myColumn); } } diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/TestBuildErrorNotification.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/TestBuildErrorNotification.java new file mode 100644 index 000000000000..c3e2679eec66 --- /dev/null +++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/externalSystemIntegration/output/events/TestBuildErrorNotification.java @@ -0,0 +1,30 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package org.jetbrains.idea.maven.externalSystemIntegration.output.events; + +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.idea.maven.externalSystemIntegration.output.MavenBuildToolLogTestUtils; + +public class TestBuildErrorNotification extends MavenBuildToolLogTestUtils { + + public void testParseJavaError() { + String expectedFileName = FileUtil.toSystemDependentName("C:/path/to/MyFile.java"); + String expectedMessage = "Error:(13,21) java: ';' expected"; + testCase("[INFO] -------------------------------------------------------------\n" + + "[ERROR] /C:/path/to/MyFile.java:[13,21] ';' expected\n" + + "[INFO] 1 error") + .withParsers(new JavaBuildErrorNotification()) + .expect(expectedMessage, new FileEventMatcher(expectedMessage, expectedFileName, 12, 20)) + .check(); + } + + public void testParseKotlinError() { + String expectedFileName = FileUtil.toSystemDependentName("C:\\path\\to\\MyFile.kt"); + String expectedMessage = "Error:(3,16) kotlin: Data class primary constructor must have only property (val / var) parameters"; + testCase("[INFO] --- kotlin-maven-plugin:1.3.21:compile (compile) @ test-11 ---\n" + + "[ERROR] C:\\path\\to\\MyFile.kt: (3, 16) Data class primary constructor must have only property (val / var) parameters\n" + + "[INFO] ------------------------------------------------------------------------") + .withParsers(new KotlinBuildErrorNotification()) + .expect(expectedMessage, new FileEventMatcher(expectedMessage, expectedFileName, 2, 15)) + .check(); + } +}