mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -117,7 +117,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
ApplicationManager.getApplication().executeOnPooledThread(command);
|
||||
}
|
||||
};
|
||||
private final SequentialTaskExecutor myEventsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor);
|
||||
private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor);
|
||||
private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>());
|
||||
|
||||
private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
|
||||
@@ -187,7 +187,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
|
||||
private void doNotify(final Collection<String> paths, final boolean notifyDeletion) {
|
||||
// ensure events processed in the order they arrived
|
||||
myEventsProcessor.submit(new Runnable() {
|
||||
myRequestsProcessor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (myProjectDataMap) {
|
||||
@@ -364,7 +364,7 @@ public class BuildManager implements ApplicationComponent{
|
||||
final Collection<String> modules,
|
||||
final Collection<String> artifacts,
|
||||
final Collection<String> paths,
|
||||
final Map<String, String> userData, DefaultMessageHandler handler) {
|
||||
final Map<String, String> userData, final DefaultMessageHandler handler) {
|
||||
|
||||
final String projectPath = getProjectPath(project);
|
||||
final UUID sessionId = UUID.randomUUID();
|
||||
@@ -375,127 +375,153 @@ public class BuildManager implements ApplicationComponent{
|
||||
myListenPort = startListening();
|
||||
}
|
||||
catch (Exception e) {
|
||||
myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
|
||||
handler.sessionTerminated();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final CmdlineRemoteProto.Message.ControllerMessage params;
|
||||
CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals;
|
||||
if (globals == null) {
|
||||
globals = buildGlobalSettings();
|
||||
myGlobals = globals;
|
||||
}
|
||||
|
||||
CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges = null;
|
||||
final SequentialTaskExecutor projectTaskQueue;
|
||||
synchronized (myProjectDataMap) {
|
||||
ProjectData data = myProjectDataMap.get(projectPath);
|
||||
if (data == null) {
|
||||
data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor));
|
||||
myProjectDataMap.put(projectPath, data);
|
||||
}
|
||||
if (isRebuild) {
|
||||
data.dropChanges();
|
||||
}
|
||||
if (IS_UNIT_TEST_MODE) {
|
||||
LOG.info("Scheduling build for " + projectPath + "; CHANGED: " + data.myChanged + "; DELETED: " + data.myDeleted);
|
||||
}
|
||||
currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
|
||||
projectTaskQueue = data.taskQueue;
|
||||
}
|
||||
|
||||
if (isRebuild) {
|
||||
params = CmdlineProtoUtil.createRebuildRequest(projectPath, userData, globals);
|
||||
}
|
||||
else {
|
||||
params = isMake ?
|
||||
CmdlineProtoUtil.createMakeRequest(projectPath, modules, artifacts, userData, globals, currentFSChanges) :
|
||||
CmdlineProtoUtil.createForceCompileRequest(projectPath, modules, artifacts, paths, userData, globals, currentFSChanges);
|
||||
}
|
||||
|
||||
myMessageDispatcher.registerBuildMessageHandler(sessionId, handler, params);
|
||||
|
||||
final RequestFuture<BuilderMessageHandler> future = new RequestFuture<BuilderMessageHandler>(handler, sessionId, new RequestFuture.CancelAction<BuilderMessageHandler>() {
|
||||
@Override
|
||||
public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
|
||||
myMessageDispatcher.cancelSession(future.getRequestID());
|
||||
}
|
||||
});
|
||||
|
||||
projectTaskQueue.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (project.isDisposed()) {
|
||||
future.cancel(false);
|
||||
try {
|
||||
final RequestFuture<BuilderMessageHandler> future = new RequestFuture<BuilderMessageHandler>(handler, sessionId, new RequestFuture.CancelAction<BuilderMessageHandler>() {
|
||||
@Override
|
||||
public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
|
||||
myMessageDispatcher.cancelSession(future.getRequestID());
|
||||
}
|
||||
});
|
||||
// by using the same queue that processes events we ensure that
|
||||
// the build will be aware of all events that have happened before this request
|
||||
myRequestsProcessor.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (future.isCancelled() || project.isDisposed()) {
|
||||
handler.sessionTerminated();
|
||||
future.setDone();
|
||||
return;
|
||||
}
|
||||
myBuildsInProgress.put(projectPath, future);
|
||||
final Process process = launchBuildProcess(project, myListenPort, sessionId);
|
||||
final OSProcessHandler processHandler = new OSProcessHandler(process, null) {
|
||||
@Override
|
||||
protected boolean shouldDestroyProcessRecursively() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final StringBuilder stdErrOutput = new StringBuilder();
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
final BuilderMessageHandler handler = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
if (handler != null) {
|
||||
handler.sessionTerminated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
// re-translate builder's output to idea.log
|
||||
final String text = event.getText();
|
||||
if (!StringUtil.isEmptyOrSpaces(text)) {
|
||||
LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim());
|
||||
if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) {
|
||||
stdErrOutput.append(text);
|
||||
}
|
||||
}
|
||||
CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals;
|
||||
if (globals == null) {
|
||||
globals = buildGlobalSettings();
|
||||
myGlobals = globals;
|
||||
}
|
||||
CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges = null;
|
||||
final SequentialTaskExecutor projectTaskQueue;
|
||||
synchronized (myProjectDataMap) {
|
||||
ProjectData data = myProjectDataMap.get(projectPath);
|
||||
if (data == null) {
|
||||
data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor));
|
||||
myProjectDataMap.put(projectPath, data);
|
||||
}
|
||||
});
|
||||
processHandler.startNotify();
|
||||
final boolean terminated = processHandler.waitFor();
|
||||
if (terminated) {
|
||||
final int exitValue = processHandler.getProcess().exitValue();
|
||||
if (exitValue != 0) {
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
msg.append("Abnormal build process termination: ");
|
||||
if (stdErrOutput.length() > 0) {
|
||||
msg.append("\n").append(stdErrOutput);
|
||||
}
|
||||
else {
|
||||
msg.append("unknown error");
|
||||
}
|
||||
future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
|
||||
if (isRebuild) {
|
||||
data.dropChanges();
|
||||
}
|
||||
if (IS_UNIT_TEST_MODE) {
|
||||
LOG.info("Scheduling build for " + projectPath + "; CHANGED: " + new HashSet<String>(data.myChanged) + "; DELETED: " + new HashSet<String>(data.myDeleted));
|
||||
}
|
||||
currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
|
||||
projectTaskQueue = data.taskQueue;
|
||||
}
|
||||
|
||||
final CmdlineRemoteProto.Message.ControllerMessage params;
|
||||
if (isRebuild) {
|
||||
params = CmdlineProtoUtil.createRebuildRequest(projectPath, userData, globals);
|
||||
}
|
||||
else {
|
||||
future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null));
|
||||
params = isMake ?
|
||||
CmdlineProtoUtil.createMakeRequest(projectPath, modules, artifacts, userData, globals, currentFSChanges) :
|
||||
CmdlineProtoUtil.createForceCompileRequest(projectPath, modules, artifacts, paths, userData, globals, currentFSChanges);
|
||||
}
|
||||
|
||||
myMessageDispatcher.registerBuildMessageHandler(sessionId, handler, params);
|
||||
|
||||
try {
|
||||
projectTaskQueue.submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (project.isDisposed()) {
|
||||
myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
handler.sessionTerminated();
|
||||
return;
|
||||
}
|
||||
myBuildsInProgress.put(projectPath, future);
|
||||
final Process process = launchBuildProcess(project, myListenPort, sessionId);
|
||||
final OSProcessHandler processHandler = new OSProcessHandler(process, null) {
|
||||
@Override
|
||||
protected boolean shouldDestroyProcessRecursively() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
final StringBuilder stdErrOutput = new StringBuilder();
|
||||
processHandler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
final BuilderMessageHandler handler = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
if (handler != null) {
|
||||
handler.sessionTerminated();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextAvailable(ProcessEvent event, Key outputType) {
|
||||
// re-translate builder's output to idea.log
|
||||
final String text = event.getText();
|
||||
if (!StringUtil.isEmptyOrSpaces(text)) {
|
||||
LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim());
|
||||
if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) {
|
||||
stdErrOutput.append(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
processHandler.startNotify();
|
||||
final boolean terminated = processHandler.waitFor();
|
||||
if (terminated) {
|
||||
final int exitValue = processHandler.getProcess().exitValue();
|
||||
if (exitValue != 0) {
|
||||
final StringBuilder msg = new StringBuilder();
|
||||
msg.append("Abnormal build process termination: ");
|
||||
if (stdErrOutput.length() > 0) {
|
||||
msg.append("\n").append(stdErrOutput);
|
||||
}
|
||||
else {
|
||||
msg.append("unknown error");
|
||||
}
|
||||
future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
|
||||
}
|
||||
}
|
||||
else {
|
||||
future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null));
|
||||
}
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
|
||||
handler.sessionTerminated();
|
||||
}
|
||||
finally {
|
||||
myBuildsInProgress.remove(projectPath);
|
||||
future.setDone();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (Throwable e) {
|
||||
myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
handler.sessionTerminated();
|
||||
future.setDone();
|
||||
}
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
|
||||
future.getMessageHandler().handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
|
||||
future.getMessageHandler().sessionTerminated();
|
||||
}
|
||||
finally {
|
||||
myBuildsInProgress.remove(projectPath);
|
||||
future.setDone();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return future;
|
||||
return future;
|
||||
}
|
||||
catch (Throwable e) {
|
||||
handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
|
||||
handler.sessionTerminated();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,6 +21,9 @@ import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.editor.SyntaxHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ColoredTreeCellRenderer;
|
||||
import com.intellij.ui.RowIcon;
|
||||
@@ -194,16 +197,30 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
|
||||
|
||||
valueLabel = DebuggerUtilsEx.truncateString(valueLabel);
|
||||
|
||||
final SimpleTextAttributes valueLabelAttribs;
|
||||
if (valueDescriptor.isDirty()) {
|
||||
valueLabelAttribs = XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES;
|
||||
}
|
||||
else {
|
||||
TextAttributes highlightingAttribs = null;
|
||||
if (valueDescriptor.isNull()){
|
||||
highlightingAttribs = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.KEYWORD);
|
||||
}
|
||||
else if (valueDescriptor.isString()) {
|
||||
highlightingAttribs = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.STRING);
|
||||
}
|
||||
valueLabelAttribs = highlightingAttribs != null? SimpleTextAttributes.fromTextAttributes(highlightingAttribs) : DEFAULT_ATTRIBUTES;
|
||||
}
|
||||
|
||||
final EvaluateException exception = descriptor.getEvaluateException();
|
||||
if(exception != null) {
|
||||
final String errorMessage = exception.getMessage();
|
||||
|
||||
if(valueLabel.endsWith(errorMessage)) {
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), DEFAULT_ATTRIBUTES);
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel.substring(0, valueLabel.length() - errorMessage.length()), valueLabelAttribs);
|
||||
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueLabelAttribs);
|
||||
descriptorText.append(errorMessage, XDebuggerUIConstants.EXCEPTION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
@@ -212,7 +229,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
|
||||
descriptorText.append(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueDescriptor.isDirty() ? XDebuggerUIConstants.CHANGED_VALUE_ATTRIBUTES : DEFAULT_ATTRIBUTES);
|
||||
appendValueTextWithEscapesRendering(descriptorText, valueLabel, valueLabelAttribs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +243,7 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
|
||||
}
|
||||
|
||||
private static void appendValueTextWithEscapesRendering(SimpleColoredText descriptorText, String valueText, final SimpleTextAttributes attribs) {
|
||||
final SimpleTextAttributes boldAttribs = attribs.derive(SimpleTextAttributes.STYLE_BOLD, null, Color.lightGray, null);
|
||||
SimpleTextAttributes escapeAttribs = null;
|
||||
final StringBuilder buf = new StringBuilder();
|
||||
boolean slashFound = false;
|
||||
for (int idx= 0; idx < valueText.length(); idx++) {
|
||||
@@ -238,10 +255,21 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer {
|
||||
descriptorText.append(buf.toString(), attribs);
|
||||
buf.setLength(0);
|
||||
}
|
||||
if (ch != '\\' && ch != '\"') {
|
||||
descriptorText.append("\\", boldAttribs);
|
||||
|
||||
if (escapeAttribs == null) { // lazy init
|
||||
final TextAttributes fromHighlighter = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(SyntaxHighlighterColors.VALID_STRING_ESCAPE);
|
||||
if (fromHighlighter != null) {
|
||||
escapeAttribs = SimpleTextAttributes.fromTextAttributes(fromHighlighter);
|
||||
}
|
||||
else {
|
||||
escapeAttribs = DEFAULT_ATTRIBUTES.derive(SimpleTextAttributes.STYLE_BOLD, Color.gray, null, null);
|
||||
}
|
||||
}
|
||||
descriptorText.append(String.valueOf(ch), boldAttribs);
|
||||
|
||||
if (ch != '\\' && ch != '\"') {
|
||||
descriptorText.append("\\", escapeAttribs);
|
||||
}
|
||||
descriptorText.append(String.valueOf(ch), escapeAttribs);
|
||||
}
|
||||
else {
|
||||
buf.append('\\').append(ch);
|
||||
|
||||
@@ -93,8 +93,13 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements
|
||||
public boolean isNull() {
|
||||
return myValue == null;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
|
||||
@Override
|
||||
public boolean isString() {
|
||||
return myValue instanceof StringReference;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return myValue instanceof PrimitiveValue;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ public interface ValueDescriptor extends NodeDescriptor{
|
||||
boolean isLvalue();
|
||||
boolean isNull();
|
||||
boolean isPrimitive();
|
||||
boolean isString();
|
||||
|
||||
@Nullable
|
||||
ValueMarkup getMarkup(final DebugProcess debugProcess);
|
||||
|
||||
@@ -53,6 +53,8 @@ public class BegTableUI extends BasicTableUI {
|
||||
public void installUI(JComponent c) {
|
||||
super.installUI(c);
|
||||
c.getActionMap().put(START_EDITING_ACTION_KEY, new StartEditingAction());
|
||||
// fix missing escape shortcut
|
||||
c.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke("pressed ESCAPE"), "cancel");
|
||||
}
|
||||
|
||||
protected KeyListener createKeyListener() {
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
<idea-plugin version="2">
|
||||
<name>Plugin name here</name>
|
||||
<description>short description of the plugin</description>
|
||||
<version>1.0</version>
|
||||
<vendor>YourCompany</vendor>
|
||||
|
||||
<description><![CDATA[
|
||||
Enter short description for your plugin here.<br>
|
||||
<small>most HTML tags may be used</small>
|
||||
]]></description>
|
||||
|
||||
<!-- please see http://confluence.jetbrains.net/display/IDEADEV/Build+Number+Ranges for description -->
|
||||
<idea-version since-build="107.105"/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user