mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Add a detail to MessageEventResult to show more information in BuildView
This CL adds the possibility to have a detailedd message shown when a node is clicked on BuildView Tree view. Test: N/A Bug: 72180932 Change-Id: I69ce91f40a3f90f8601ecd96c9c2863a4e016b0b
This commit is contained in:
committed by
Vladislav.Soroka
parent
8cb5818f4c
commit
bc54bf10d7
@@ -13,6 +13,7 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.IJSwingUtilities;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -27,9 +28,13 @@ public class BuildConsoleUtils {
|
||||
private static final String A_CLOSING = "</a>";
|
||||
private static final Set<String> NEW_LINES = ContainerUtil.set("<br>", "</br>", "<br/>", "<p>", "</p>", "<p/>", "<pre>", "</pre>");
|
||||
|
||||
public static boolean printFailure(ConsoleView consoleView, Failure failure) {
|
||||
String text = ObjectUtils.chooseNotNull(failure.getDescription(), failure.getMessage());
|
||||
if (text == null && failure.getError() != null) {
|
||||
public static boolean printDetails(ConsoleView consoleView, Failure failure) {
|
||||
return printDetails(consoleView, failure, null);
|
||||
}
|
||||
|
||||
public static boolean printDetails(ConsoleView consoleView, @Nullable Failure failure, @Nullable String details) {
|
||||
String text = failure == null ? details : ObjectUtils.chooseNotNull(failure.getDescription(), failure.getMessage());
|
||||
if (text == null && failure != null && failure.getError() != null) {
|
||||
text = failure.getError().getMessage();
|
||||
}
|
||||
if (text == null) return false;
|
||||
@@ -52,6 +57,9 @@ public class BuildConsoleUtils {
|
||||
consoleView.printHyperlink(linkText, new HyperlinkInfo() {
|
||||
@Override
|
||||
public void navigate(Project project) {
|
||||
if(failure == null) {
|
||||
return;
|
||||
}
|
||||
Notification notification = failure.getNotification();
|
||||
if (notification != null && notification.getListener() != null) {
|
||||
notification.getListener().hyperlinkUpdate(
|
||||
|
||||
@@ -33,6 +33,7 @@ import com.intellij.ui.treeStructure.treetable.TreeTable;
|
||||
import com.intellij.ui.treeStructure.treetable.TreeTableTree;
|
||||
import com.intellij.util.EditSourceOnDoubleClickHandler;
|
||||
import com.intellij.util.EditSourceOnEnterKeyHandler;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.TransferToEDTQueue;
|
||||
import com.intellij.util.text.DateFormatUtil;
|
||||
@@ -445,6 +446,12 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
public MessageEvent.Kind getKind() {
|
||||
return eventKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDetails() {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (messageEvent instanceof FileMessageEvent) {
|
||||
@@ -633,20 +640,39 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
|
||||
public boolean setNode(@NotNull ExecutionNode node) {
|
||||
EventResult eventResult = node.getResult();
|
||||
if (!(eventResult instanceof FailureResult)) return false;
|
||||
List<? extends Failure> failures = ((FailureResult)eventResult).getFailures();
|
||||
if (failures.isEmpty()) return false;
|
||||
myConsole.clear();
|
||||
|
||||
boolean hasChanged = false;
|
||||
for (Iterator<? extends Failure> iterator = failures.iterator(); iterator.hasNext(); ) {
|
||||
Failure failure = iterator.next();
|
||||
if (!printFailure(failure)) continue;
|
||||
hasChanged = true;
|
||||
if (iterator.hasNext()) {
|
||||
myConsole.print("\n\n", ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
|
||||
if (eventResult instanceof FailureResult) {
|
||||
myConsole.clear();
|
||||
List<? extends Failure> failures = ((FailureResult)eventResult).getFailures();
|
||||
if (failures.isEmpty()) return false;
|
||||
for (Iterator<? extends Failure> iterator = failures.iterator(); iterator.hasNext(); ) {
|
||||
Failure failure = iterator.next();
|
||||
String text = ObjectUtils.chooseNotNull(failure.getDescription(), failure.getMessage());
|
||||
if (text == null && failure.getError() != null) {
|
||||
text = failure.getError().getMessage();
|
||||
}
|
||||
if (text == null) continue;
|
||||
printDetails(failure, text);
|
||||
hasChanged = true;
|
||||
if (iterator.hasNext()) {
|
||||
myConsole.print("\n\n", ConsoleViewContentType.NORMAL_OUTPUT);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (eventResult instanceof MessageEventResult) {
|
||||
String details = ((MessageEventResult)eventResult).getDetails();
|
||||
if (details == null) {
|
||||
return false;
|
||||
}
|
||||
if (details.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
myConsole.clear();
|
||||
printDetails(null, details);
|
||||
hasChanged = true;
|
||||
}
|
||||
|
||||
if (!hasChanged) return false;
|
||||
|
||||
myConsole.scrollTo(0);
|
||||
@@ -661,8 +687,8 @@ public class BuildTreeConsoleView implements ConsoleView, DataProvider, BuildCon
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean printFailure(Failure failure) {
|
||||
return BuildConsoleUtils.printFailure(myConsole, failure);
|
||||
private boolean printDetails(Failure failure, @Nullable String details) {
|
||||
return BuildConsoleUtils.printDetails(myConsole, failure, details);
|
||||
}
|
||||
|
||||
public void setNode(@Nullable DefaultMutableTreeNode node) {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.build.events;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author Vladislav.Soroka
|
||||
@@ -9,4 +10,7 @@ import org.jetbrains.annotations.ApiStatus;
|
||||
@ApiStatus.Experimental
|
||||
public interface MessageEventResult extends EventResult {
|
||||
MessageEvent.Kind getKind();
|
||||
|
||||
@Nullable
|
||||
String getDetails();
|
||||
}
|
||||
|
||||
@@ -18,14 +18,17 @@ import java.util.Objects;
|
||||
public class FileMessageEventImpl extends MessageEventImpl implements FileMessageEvent {
|
||||
|
||||
private final FilePosition myFilePosition;
|
||||
private final String myDetailedMessage;
|
||||
|
||||
public FileMessageEventImpl(@NotNull Object parentId,
|
||||
@NotNull Kind kind,
|
||||
@Nullable String group,
|
||||
@NotNull String message,
|
||||
@Nullable String detailedMessage,
|
||||
@NotNull FilePosition filePosition) {
|
||||
super(parentId, kind, group, message);
|
||||
super(parentId, kind, group, message, detailedMessage);
|
||||
myFilePosition = filePosition;
|
||||
myDetailedMessage = detailedMessage;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -40,6 +43,12 @@ public class FileMessageEventImpl extends MessageEventImpl implements FileMessag
|
||||
public Kind getKind() {
|
||||
return FileMessageEventImpl.this.getKind();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public String getDetails() {
|
||||
return myDetailedMessage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,15 @@ import java.util.Objects;
|
||||
*/
|
||||
public class MessageEventImpl extends AbstractBuildEvent implements MessageEvent {
|
||||
|
||||
private final Kind myKind;
|
||||
private final String myGroup;
|
||||
@NotNull private final Kind myKind;
|
||||
@NotNull private final String myGroup;
|
||||
@Nullable private final String myDetailedMessage;
|
||||
|
||||
public MessageEventImpl(@NotNull Object parentId, @NotNull Kind kind, @Nullable String group, @NotNull String message) {
|
||||
public MessageEventImpl(@NotNull Object parentId, @NotNull Kind kind, @Nullable String group, @NotNull String message, @Nullable String detailedMessage) {
|
||||
super(new Object(), parentId, System.currentTimeMillis(), message);
|
||||
myKind = kind;
|
||||
myGroup = group == null ? "Other messages" : group;
|
||||
myDetailedMessage = detailedMessage;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -49,6 +51,11 @@ public class MessageEventImpl extends AbstractBuildEvent implements MessageEvent
|
||||
public Kind getKind() {
|
||||
return myKind;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getDetails() {
|
||||
return myDetailedMessage;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
package com.intellij.build.output;
|
||||
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
@@ -16,5 +17,19 @@ public interface BuildOutputInstantReader {
|
||||
|
||||
void pushBack();
|
||||
|
||||
/***
|
||||
* Push back the given number of lines.
|
||||
* @param numberOfLines
|
||||
*/
|
||||
void pushBack(int numberOfLines);
|
||||
|
||||
String getCurrentLine();
|
||||
|
||||
/***
|
||||
* Read lines until a given line is found or there are no more lines. The match is done by {@link String#equals(Object)} if endLine is not null.
|
||||
* @param endLine
|
||||
* @return All lines read until endLine is found or no more lines exist
|
||||
*/
|
||||
@NotNull
|
||||
String readUntil(@Nullable String endLine);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,13 @@ package com.intellij.build.output;
|
||||
import com.intellij.build.BuildProgressListener;
|
||||
import com.intellij.build.events.MessageEvent;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.SystemProperties;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@@ -160,8 +163,35 @@ public class BuildOutputInstantReaderImpl implements Appendable, Closeable, Buil
|
||||
myCurrentIndex--;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pushBack(int numberOfLines) {
|
||||
myCurrentIndex -= numberOfLines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentLine() {
|
||||
return myLinesBuffer.size() > myCurrentIndex ? myLinesBuffer.get(myCurrentIndex) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String readUntil(@Nullable String endString) {
|
||||
List<String> lineList = new ArrayList<>();
|
||||
int readLines = 0;
|
||||
while (true) {
|
||||
String currentLine = readLine();
|
||||
if (currentLine == null) {
|
||||
break;
|
||||
}
|
||||
readLines++;
|
||||
if (currentLine.equals(endString)) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
lineList.add(currentLine);
|
||||
}
|
||||
}
|
||||
pushBack(readLines);
|
||||
return StringUtil.join(lineList, SystemProperties.getLineSeparator());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,9 @@ public class JavacOutputParser implements BuildOutputParser {
|
||||
private static final char COLON = ':';
|
||||
private static final String WARNING_PREFIX = "warning:"; // default value
|
||||
|
||||
private static final String END_DETAIL = "* Try:";
|
||||
|
||||
@Override
|
||||
public boolean parse(@NotNull String line, @NotNull BuildOutputInstantReader reader, @NotNull Consumer<MessageEvent> messageConsumer) {
|
||||
int colonIndex1 = line.indexOf(COLON);
|
||||
if (colonIndex1 == 1) { // drive letter
|
||||
@@ -37,17 +40,20 @@ public class JavacOutputParser implements BuildOutputParser {
|
||||
if (part1.equalsIgnoreCase("error") /* jikes */ || part1.equalsIgnoreCase("Caused by")) {
|
||||
// +1 so we don't include the colon
|
||||
String text = line.substring(colonIndex1 + 1).trim();
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, text));
|
||||
String detailMessage = getDetailMessage(line, reader);
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, text, detailMessage));
|
||||
return true;
|
||||
}
|
||||
if (part1.equalsIgnoreCase("warning")) {
|
||||
// +1 so we don't include the colon
|
||||
String text = line.substring(colonIndex1 + 1).trim();
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.WARNING, COMPILER_MESSAGES_GROUP, text));
|
||||
String detailMessage = getDetailMessage(line, reader);
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.WARNING, COMPILER_MESSAGES_GROUP, text, detailMessage));
|
||||
return true;
|
||||
}
|
||||
if (part1.equalsIgnoreCase("javac")) {
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, line));
|
||||
String detailMessage = getDetailMessage(line, reader);
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, line, detailMessage));
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -74,6 +80,7 @@ public class JavacOutputParser implements BuildOutputParser {
|
||||
return false;
|
||||
}
|
||||
|
||||
String detailMessage = getDetailMessage(line, reader);
|
||||
List<String> messageList = ContainerUtil.newArrayList();
|
||||
messageList.add(text);
|
||||
int column; // 0-based.
|
||||
@@ -107,7 +114,7 @@ public class JavacOutputParser implements BuildOutputParser {
|
||||
if (column >= 0) {
|
||||
messageList = convertMessages(messageList);
|
||||
String msgText = StringUtil.join(messageList, SystemProperties.getLineSeparator());
|
||||
messageConsumer.accept(new FileMessageEventImpl(reader.getBuildId(), kind, COMPILER_MESSAGES_GROUP, msgText,
|
||||
messageConsumer.accept(new FileMessageEventImpl(reader.getBuildId(), kind, COMPILER_MESSAGES_GROUP, msgText, detailMessage,
|
||||
new FilePosition(file, lineNumber - 1, column)));
|
||||
return true;
|
||||
}
|
||||
@@ -118,13 +125,19 @@ public class JavacOutputParser implements BuildOutputParser {
|
||||
}
|
||||
|
||||
if (line.endsWith("java.lang.OutOfMemoryError")) {
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, "Out of memory."));
|
||||
String detailMessage = reader.readUntil(null);
|
||||
messageConsumer.accept(new MessageEventImpl(reader.getBuildId(), MessageEvent.Kind.ERROR, COMPILER_MESSAGES_GROUP, "Out of memory.", detailMessage));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String getDetailMessage(@NotNull String line, @NotNull BuildOutputInstantReader reader) {
|
||||
return line + SystemProperties.getLineSeparator() + reader.readUntil(END_DETAIL);
|
||||
}
|
||||
|
||||
private static void addMessage(@NotNull MessageEvent message, @NotNull List<MessageEvent> messages) {
|
||||
boolean duplicatesPrevious = false;
|
||||
int messageCount = messages.size();
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.build.events.MessageEvent
|
||||
import com.intellij.build.events.impl.FileMessageEventImpl
|
||||
import com.intellij.build.events.impl.MessageEventImpl
|
||||
import com.intellij.openapi.util.text.StringUtil
|
||||
import com.intellij.util.SystemProperties
|
||||
import java.io.File
|
||||
import java.lang.IllegalStateException
|
||||
import java.util.function.Consumer
|
||||
@@ -21,6 +22,7 @@ class KotlincOutputParser : BuildOutputParser {
|
||||
|
||||
companion object {
|
||||
private val COMPILER_MESSAGES_GROUP = "Kotlin compiler"
|
||||
private val END_DETAIL = "* Try:"
|
||||
}
|
||||
|
||||
override fun parse(line: String, reader: BuildOutputInstantReader, consumer: Consumer<MessageEvent>): Boolean {
|
||||
@@ -35,9 +37,11 @@ class KotlincOutputParser : BuildOutputParser {
|
||||
val path = lineWoSeverity.substringBeforeAndTrim(colonIndex2)
|
||||
val file = File(path)
|
||||
|
||||
val detail = "$line${SystemProperties.getLineSeparator()}${reader.readUntil(END_DETAIL)}"
|
||||
|
||||
val fileExtension = file.extension.toLowerCase()
|
||||
if (!file.isFile || (fileExtension != "kt" && fileExtension != "java")) {
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), lineWoSeverity.amendNextLinesIfNeeded(reader)), consumer)
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), lineWoSeverity.amendNextLinesIfNeeded(reader), detail), consumer)
|
||||
}
|
||||
|
||||
val lineWoPath = lineWoSeverity.substringAfterAndTrim(colonIndex2)
|
||||
@@ -54,14 +58,14 @@ class KotlincOutputParser : BuildOutputParser {
|
||||
if (lineNumber != null) {
|
||||
val symbolNumberText = symbolNumber.toInt()
|
||||
return addMessage(createMessageWithLocation(
|
||||
reader.buildId, getMessageKind(severity), message, path, lineNumber.toInt(), symbolNumberText), consumer)
|
||||
reader.buildId, getMessageKind(severity), message, path, lineNumber.toInt(), symbolNumberText, detail), consumer)
|
||||
}
|
||||
}
|
||||
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), message), consumer)
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), message, detail), consumer)
|
||||
}
|
||||
else {
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), lineWoSeverity.amendNextLinesIfNeeded(reader)), consumer)
|
||||
return addMessage(createMessage(reader.buildId, getMessageKind(severity), lineWoSeverity.amendNextLinesIfNeeded(reader), detail), consumer)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,8 +146,8 @@ class KotlincOutputParser : BuildOutputParser {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun createMessage(buildId: Any, messageKind: MessageEvent.Kind, text: String): MessageEvent {
|
||||
return MessageEventImpl(buildId, messageKind, COMPILER_MESSAGES_GROUP, text.trim())
|
||||
private fun createMessage(buildId: Any, messageKind: MessageEvent.Kind, text: String, detail: String): MessageEvent {
|
||||
return MessageEventImpl(buildId, messageKind, COMPILER_MESSAGES_GROUP, text.trim(), detail)
|
||||
}
|
||||
|
||||
private fun createMessageWithLocation(
|
||||
@@ -152,9 +156,10 @@ class KotlincOutputParser : BuildOutputParser {
|
||||
text: String,
|
||||
file: String,
|
||||
lineNumber: Int,
|
||||
columnIndex: Int
|
||||
columnIndex: Int,
|
||||
detail: String
|
||||
): FileMessageEventImpl {
|
||||
return FileMessageEventImpl(buildId, messageKind, COMPILER_MESSAGES_GROUP, text.trim(),
|
||||
return FileMessageEventImpl(buildId, messageKind, COMPILER_MESSAGES_GROUP, text.trim(), detail,
|
||||
FilePosition(File(file), lineNumber - 1, columnIndex - 1))
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -632,7 +632,7 @@ public class ExternalSystemUtil {
|
||||
ExternalSystemProcessHandler processHandler) {
|
||||
if (consoleView instanceof ConsoleView) {
|
||||
for (com.intellij.build.events.Failure failure : failureResult.getFailures()) {
|
||||
BuildConsoleUtils.printFailure((ConsoleView)consoleView, failure);
|
||||
BuildConsoleUtils.printDetails((ConsoleView)consoleView, failure);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
Reference in New Issue
Block a user