mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 15:15:45 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
-58
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class AbstractSteppingActionHandler extends DebuggerActionHandler {
|
||||
|
||||
@Nullable
|
||||
protected static DebuggerSession getSession(@NotNull Project project) {
|
||||
final DebuggerContextImpl context = getContext(project);
|
||||
return context != null ? context.getDebuggerSession() : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static DebuggerContextImpl getContext(@NotNull Project project) {
|
||||
return (DebuggerManagerEx.getInstanceEx(project)).getContext();
|
||||
}
|
||||
|
||||
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
|
||||
final DebuggerContextImpl context = getContext(project);
|
||||
if (context == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DebuggerSession debuggerSession = context.getDebuggerSession();
|
||||
|
||||
final boolean isPaused = debuggerSession != null && debuggerSession.isPaused();
|
||||
final SuspendContextImpl suspendContext = context.getSuspendContext();
|
||||
final boolean hasCurrentThread = suspendContext != null && suspendContext.getThread() != null;
|
||||
return isPaused && hasCurrentThread;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,179 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class AddToWatchActionHandler
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.DebuggerPanelsManager;
|
||||
import com.intellij.debugger.ui.impl.*;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class AddToWatchActionHandler extends DebuggerActionHandler {
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
|
||||
DataContext context = event.getDataContext();
|
||||
DebuggerTreeNodeImpl[] selectedNodes = DebuggerAction.getSelectedNodes(context);
|
||||
boolean enabled = false;
|
||||
if (selectedNodes != null && selectedNodes.length > 0) {
|
||||
DebuggerTreePanel panel = DebuggerAction.getPanel(context);
|
||||
if (panel instanceof VariablesPanel || panel instanceof WatchPanel
|
||||
|| (panel == null && DebuggerAction.getTree(context) instanceof InspectDebuggerTree)) {
|
||||
enabled = true;
|
||||
for (DebuggerTreeNodeImpl node : selectedNodes) {
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (!(descriptor instanceof ValueDescriptorImpl)) {
|
||||
enabled = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
final Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
enabled = DebuggerUtilsEx.getEditorText(editor) != null;
|
||||
}
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void perform(@NotNull Project project, AnActionEvent event) {
|
||||
final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(event.getDataContext());
|
||||
|
||||
if(debuggerContext == null) return;
|
||||
|
||||
final DebuggerSession session = debuggerContext.getDebuggerSession();
|
||||
if(session == null) {
|
||||
return;
|
||||
}
|
||||
final MainWatchPanel watchPanel = null;// DebuggerPanelsManager.getInstance(debuggerContext.getProject()).getWatchPanel();
|
||||
|
||||
if(watchPanel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DebuggerTreeNodeImpl[] selectedNodes = DebuggerAction.getSelectedNodes(event.getDataContext());
|
||||
|
||||
if(selectedNodes != null && selectedNodes.length > 0) {
|
||||
addFromNodes(debuggerContext, watchPanel, selectedNodes);
|
||||
}
|
||||
else {
|
||||
final Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
if (editor != null) {
|
||||
final TextWithImports editorText = DebuggerUtilsEx.getEditorText(editor);
|
||||
if (editorText != null) {
|
||||
doAddWatch(watchPanel, editorText, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void addFromNodes(final DebuggerContextImpl debuggerContext, final MainWatchPanel watchPanel, final DebuggerTreeNodeImpl[] selectedNodes) {
|
||||
debuggerContext.getDebugProcess().getManagerThread().schedule(new AddToWatchesCommand(debuggerContext, selectedNodes, watchPanel));
|
||||
}
|
||||
|
||||
public static void doAddWatch(final MainWatchPanel watchPanel, final TextWithImports expression, final NodeDescriptorImpl descriptor) {
|
||||
final WatchDebuggerTree watchTree = watchPanel.getWatchTree();
|
||||
final DebuggerTreeNodeImpl node = watchTree.addWatch(expression, null);
|
||||
if (descriptor != null) {
|
||||
node.getDescriptor().displayAs(descriptor);
|
||||
}
|
||||
node.calcValue();
|
||||
}
|
||||
|
||||
private static class AddToWatchesCommand extends DebuggerContextCommandImpl {
|
||||
|
||||
private final DebuggerContextImpl myDebuggerContext;
|
||||
private final DebuggerTreeNodeImpl[] mySelectedNodes;
|
||||
private final MainWatchPanel myWatchPanel;
|
||||
|
||||
public AddToWatchesCommand(DebuggerContextImpl debuggerContext, DebuggerTreeNodeImpl[] selectedNodes, MainWatchPanel watchPanel) {
|
||||
super(debuggerContext);
|
||||
myDebuggerContext = debuggerContext;
|
||||
mySelectedNodes = selectedNodes;
|
||||
myWatchPanel = watchPanel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadAction() {
|
||||
final DebuggerSession session = myDebuggerContext.getDebuggerSession();
|
||||
if (session == null) {
|
||||
return;
|
||||
}
|
||||
final Project project = session.getProject();
|
||||
for (final DebuggerTreeNodeImpl node : mySelectedNodes) {
|
||||
final NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
try {
|
||||
final TextWithImports expression = DebuggerTreeNodeExpression.createEvaluationText(node, myDebuggerContext);
|
||||
if (expression != null) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
doAddWatch(myWatchPanel, expression, descriptor);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (final EvaluateException e) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Messages.showErrorDialog(project, e.getMessage(), ActionsBundle.actionText(XDebuggerActions.ADD_TO_WATCH));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commandCancelled() {
|
||||
DebuggerInvocationUtil.swingInvokeLater(myDebuggerContext.getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
for (DebuggerTreeNodeImpl node : mySelectedNodes) {
|
||||
final NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (descriptor instanceof WatchItemDescriptor) {
|
||||
final TextWithImports expression = ((WatchItemDescriptor)descriptor).getEvaluationText();
|
||||
if (expression != null) {
|
||||
doAddWatch(myWatchPanel, expression, descriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @author max
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.progress.util.ProgressWindowWithNotification;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.sun.jdi.Value;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* @author Jeka
|
||||
*/
|
||||
public abstract class BaseValueAction extends DebuggerAction {
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final DataContext actionContext = e.getDataContext();
|
||||
final Project project = CommonDataKeys.PROJECT.getData(actionContext);
|
||||
final DebuggerTreeNodeImpl node = getSelectedNode(actionContext);
|
||||
final String text = getValueText(node);
|
||||
if (text != null) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
public void run() {
|
||||
processText(project, DebuggerUtilsEx.prepareValueText(text, project), node, null);
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
final Value value = getValue(node);
|
||||
if (value == null) {
|
||||
return;
|
||||
}
|
||||
final DebuggerManagerEx debuggerManager = DebuggerManagerEx.getInstanceEx(project);
|
||||
if(debuggerManager == null) {
|
||||
return;
|
||||
}
|
||||
final DebuggerContextImpl debuggerContext = debuggerManager.getContext();
|
||||
if (debuggerContext == null || debuggerContext.getDebuggerSession() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, project);
|
||||
SuspendContextCommandImpl getTextCommand = new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) {
|
||||
public Priority getPriority() {
|
||||
return Priority.HIGH;
|
||||
}
|
||||
|
||||
public void contextAction() throws Exception {
|
||||
//noinspection HardCodedStringLiteral
|
||||
progressWindow.setText(DebuggerBundle.message("progress.evaluating", "toString()"));
|
||||
|
||||
final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(debuggerContext.createEvaluationContext(), value);
|
||||
|
||||
if (progressWindow.isCanceled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
public void run() {
|
||||
String text = valueAsString;
|
||||
if (text == null) {
|
||||
text = "";
|
||||
}
|
||||
processText(project, text, node, debuggerContext);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
progressWindow.setTitle(DebuggerBundle.message("title.evaluating"));
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(getTextCommand, progressWindow);
|
||||
}
|
||||
|
||||
protected abstract void processText(final Project project, String text, DebuggerTreeNodeImpl node, DebuggerContextImpl debuggerContext);
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
Presentation presentation = e.getPresentation();
|
||||
Value value = getValue(getSelectedNode(e.getDataContext()));
|
||||
presentation.setEnabled(value != null);
|
||||
presentation.setVisible(value != null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getValueText(final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (descriptor instanceof ValueDescriptorImpl) {
|
||||
return ((ValueDescriptorImpl)descriptor).getValueText();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Value getValue(final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (!(descriptor instanceof ValueDescriptor)) {
|
||||
return null;
|
||||
}
|
||||
return ((ValueDescriptor)descriptor).getValue();
|
||||
}
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Sep 12, 2006
|
||||
*/
|
||||
public class ForceRunToCursorActionHandler extends RunToCursorActionHandler {
|
||||
public ForceRunToCursorActionHandler() {
|
||||
super(true);
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ForceStepIntoActionHandler extends AbstractSteppingActionHandler {
|
||||
public void perform(@NotNull final Project project, AnActionEvent e) {
|
||||
final DebuggerSession session = getSession(project);
|
||||
if (session != null) {
|
||||
session.stepInto(true, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ForceStepOverActionHandler extends AbstractSteppingActionHandler {
|
||||
public void perform(@NotNull final Project project, AnActionEvent e) {
|
||||
final DebuggerSession session = getSession(project);
|
||||
if (session != null) {
|
||||
session.stepOver(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import com.sun.jdi.request.EventRequest;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class PauseActionHandler extends DebuggerActionHandler {
|
||||
public void perform(@NotNull final Project project, final AnActionEvent event) {
|
||||
final DebuggerSession session = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession();
|
||||
if (session != null) {
|
||||
session.pause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(@NotNull Project project, AnActionEvent event) {
|
||||
return DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession() == null;
|
||||
}
|
||||
|
||||
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
|
||||
final DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
|
||||
return debuggerSession != null && !debuggerSession.getProcess().isPausePressed() &&
|
||||
(debuggerSession.isEvaluating() ||
|
||||
debuggerSession.isRunning() || isSingleThreadSuspended(debuggerSession)
|
||||
);
|
||||
}
|
||||
|
||||
private static boolean isSingleThreadSuspended(final DebuggerSession debuggerSession) {
|
||||
final SuspendContextImpl suspendContext = debuggerSession.getContextManager().getContext().getSuspendContext();
|
||||
return suspendContext != null && !suspendContext.isResumed() && suspendContext.getSuspendPolicy() == EventRequest.SUSPEND_EVENT_THREAD;
|
||||
}
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ResumeActionHandler extends DebuggerActionHandler {
|
||||
public void perform(@NotNull final Project project, final AnActionEvent event) {
|
||||
final DebuggerSession session = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession();
|
||||
if (session != null) {
|
||||
session.resume();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
|
||||
DebuggerSession debuggerSession = (DebuggerManagerEx.getInstanceEx(project)).getContext().getDebuggerSession();
|
||||
return debuggerSession != null && debuggerSession.isPaused();
|
||||
}
|
||||
}
|
||||
@@ -1,85 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* class RunToCursorAction
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RunToCursorActionHandler extends DebuggerActionHandler {
|
||||
private final boolean myIgnoreBreakpoints;
|
||||
|
||||
public RunToCursorActionHandler() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
protected RunToCursorActionHandler(boolean ignoreBreakpoints) {
|
||||
myIgnoreBreakpoints = ignoreBreakpoints;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(final @NotNull Project project, final AnActionEvent event) {
|
||||
Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
if (editor == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (DebuggerUtils.isDebugActionAware(file)) {
|
||||
DebuggerSession debuggerSession = DebuggerManagerEx.getInstanceEx(project).getContext().getDebuggerSession();
|
||||
return debuggerSession != null && debuggerSession.isPaused();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void perform(@NotNull final Project project, final AnActionEvent event) {
|
||||
Editor editor = event.getData(CommonDataKeys.EDITOR);
|
||||
if (editor == null) {
|
||||
return;
|
||||
}
|
||||
DebuggerContextImpl context = DebuggerManagerEx.getInstanceEx(project).getContext();
|
||||
DebugProcessImpl debugProcess = context.getDebugProcess();
|
||||
if (debugProcess == null) {
|
||||
return;
|
||||
}
|
||||
final DebuggerSession session = context.getDebuggerSession();
|
||||
if (session != null) {
|
||||
session.runToCursor(editor.getDocument(), editor.getCaretModel().getLogicalPosition().line, myIgnoreBreakpoints);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StepIntoActionHandler extends AbstractSteppingActionHandler {
|
||||
public void perform(@NotNull final Project project, AnActionEvent e) {
|
||||
final DebuggerSession session = getSession(project);
|
||||
if (session != null) {
|
||||
session.stepInto(false, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StepOverActionHandler extends AbstractSteppingActionHandler {
|
||||
public void perform(@NotNull final Project project, AnActionEvent e) {
|
||||
final DebuggerSession session = getSession(project);
|
||||
if (session != null) {
|
||||
session.stepOver(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -415,166 +415,166 @@ public class JavaValueModifier extends XValueModifier {
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(askSetAction, progressWindow);
|
||||
}
|
||||
|
||||
private void showEditor(final TextWithImports initialString,
|
||||
final DebuggerTreeNodeImpl node,
|
||||
final DebuggerContextImpl debuggerContext,
|
||||
final SetValueRunnable setValueRunnable) {
|
||||
final JPanel editorPanel = new JPanel();
|
||||
editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.X_AXIS));
|
||||
SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
label.setIcon(node.getIcon());
|
||||
DebuggerTreeRenderer.getDescriptorTitle(debuggerContext, node.getDescriptor()).appendToComponent(label);
|
||||
editorPanel.add(label);
|
||||
|
||||
final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(
|
||||
debuggerContext.getProject(),
|
||||
PositionUtil.getContextElement(debuggerContext),
|
||||
"setValue", DefaultCodeFragmentFactory.getInstance());
|
||||
comboBox.setText(initialString);
|
||||
comboBox.selectAll();
|
||||
editorPanel.add(comboBox);
|
||||
|
||||
final DebuggerTreeInplaceEditor editor = new DebuggerTreeInplaceEditor(node) {
|
||||
public JComponent createInplaceEditorComponent() {
|
||||
return editorPanel;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
public Editor getEditor() {
|
||||
return comboBox.getEditor();
|
||||
}
|
||||
|
||||
public JComponent getEditorComponent() {
|
||||
return comboBox.getEditorComponent();
|
||||
}
|
||||
|
||||
private void flushValue() {
|
||||
if (comboBox.isPopupVisible()) {
|
||||
comboBox.selectPopupValue();
|
||||
}
|
||||
|
||||
Editor editor = getEditor();
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final TextWithImports text = comboBox.getText();
|
||||
|
||||
PsiFile psiFile = PsiDocumentManager.getInstance(debuggerContext.getProject()).getPsiFile(editor.getDocument());
|
||||
|
||||
final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, getProject());
|
||||
EditorEvaluationCommand evaluationCommand = new EditorEvaluationCommand(getEditor(), psiFile, debuggerContext, progressWindow) {
|
||||
public void threadAction() {
|
||||
try {
|
||||
evaluate();
|
||||
}
|
||||
catch(EvaluateException e) {
|
||||
progressWindow.cancel();
|
||||
}
|
||||
catch(ProcessCanceledException e) {
|
||||
progressWindow.cancel();
|
||||
}
|
||||
finally{
|
||||
if (!progressWindow.isCanceled()) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(debuggerContext.getProject(), new Runnable() {
|
||||
public void run() {
|
||||
comboBox.addRecent(text);
|
||||
cancelEditing();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable<ExpressionEvaluator>() {
|
||||
public ExpressionEvaluator compute() throws EvaluateException {
|
||||
return EvaluatorBuilderImpl.build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
|
||||
}
|
||||
});
|
||||
|
||||
setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() {
|
||||
public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException,
|
||||
InvalidTypeException,
|
||||
EvaluateException,
|
||||
IncompatibleThreadStateException {
|
||||
if (!progressWindow.isCanceled()) {
|
||||
setValueRunnable.setValue(evaluationContext, newValue);
|
||||
node.calcValue();
|
||||
}
|
||||
}
|
||||
|
||||
public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws
|
||||
InvocationException,
|
||||
ClassNotLoadedException,
|
||||
EvaluateException,
|
||||
IncompatibleThreadStateException,
|
||||
InvalidTypeException {
|
||||
return setValueRunnable.loadClass(evaluationContext, className);
|
||||
}
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
progressWindow.addListener(new ProgressIndicatorListenerAdapter() {
|
||||
//should return whether to stop processing
|
||||
public void stopped() {
|
||||
if(!progressWindow.isCanceled()) {
|
||||
IJSwingUtilities.invoke(new Runnable() {
|
||||
public void run() {
|
||||
cancelEditing();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
|
||||
progressWindow.setTitle(DebuggerBundle.message("progress.set.value"));
|
||||
debuggerContext.getDebugProcess().getManagerThread().startProgress(evaluationCommand, progressWindow);
|
||||
}
|
||||
|
||||
public void cancelEditing() {
|
||||
try {
|
||||
super.cancelEditing();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void doOKAction() {
|
||||
try {
|
||||
flushValue();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
final DebuggerStateManager stateManager = DebuggerManagerEx.getInstanceEx(debuggerContext.getProject()).getContextManager();
|
||||
|
||||
stateManager.addListener(new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
stateManager.removeListener(this);
|
||||
editor.cancelEditing();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
node.getTree().hideTooltip();
|
||||
|
||||
editor.show();
|
||||
}
|
||||
//private void showEditor(final TextWithImports initialString,
|
||||
// final DebuggerTreeNodeImpl node,
|
||||
// final DebuggerContextImpl debuggerContext,
|
||||
// final SetValueRunnable setValueRunnable) {
|
||||
// final JPanel editorPanel = new JPanel();
|
||||
// editorPanel.setLayout(new BoxLayout(editorPanel, BoxLayout.X_AXIS));
|
||||
// SimpleColoredComponent label = new SimpleColoredComponent();
|
||||
// label.setIcon(node.getIcon());
|
||||
// DebuggerTreeRenderer.getDescriptorTitle(debuggerContext, node.getDescriptor()).appendToComponent(label);
|
||||
// editorPanel.add(label);
|
||||
//
|
||||
// final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(
|
||||
// debuggerContext.getProject(),
|
||||
// PositionUtil.getContextElement(debuggerContext),
|
||||
// "setValue", DefaultCodeFragmentFactory.getInstance());
|
||||
// comboBox.setText(initialString);
|
||||
// comboBox.selectAll();
|
||||
// editorPanel.add(comboBox);
|
||||
//
|
||||
// final DebuggerTreeInplaceEditor editor = new DebuggerTreeInplaceEditor(node) {
|
||||
// public JComponent createInplaceEditorComponent() {
|
||||
// return editorPanel;
|
||||
// }
|
||||
//
|
||||
// public JComponent getPreferredFocusedComponent() {
|
||||
// return comboBox;
|
||||
// }
|
||||
//
|
||||
// public Editor getEditor() {
|
||||
// return comboBox.getEditor();
|
||||
// }
|
||||
//
|
||||
// public JComponent getEditorComponent() {
|
||||
// return comboBox.getEditorComponent();
|
||||
// }
|
||||
//
|
||||
// private void flushValue() {
|
||||
// if (comboBox.isPopupVisible()) {
|
||||
// comboBox.selectPopupValue();
|
||||
// }
|
||||
//
|
||||
// Editor editor = getEditor();
|
||||
// if(editor == null) {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// final TextWithImports text = comboBox.getText();
|
||||
//
|
||||
// PsiFile psiFile = PsiDocumentManager.getInstance(debuggerContext.getProject()).getPsiFile(editor.getDocument());
|
||||
//
|
||||
// final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, getProject());
|
||||
// EditorEvaluationCommand evaluationCommand = new EditorEvaluationCommand(getEditor(), psiFile, debuggerContext, progressWindow) {
|
||||
// public void threadAction() {
|
||||
// try {
|
||||
// evaluate();
|
||||
// }
|
||||
// catch(EvaluateException e) {
|
||||
// progressWindow.cancel();
|
||||
// }
|
||||
// catch(ProcessCanceledException e) {
|
||||
// progressWindow.cancel();
|
||||
// }
|
||||
// finally{
|
||||
// if (!progressWindow.isCanceled()) {
|
||||
// DebuggerInvocationUtil.swingInvokeLater(debuggerContext.getProject(), new Runnable() {
|
||||
// public void run() {
|
||||
// comboBox.addRecent(text);
|
||||
// cancelEditing();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// protected Object evaluate(final EvaluationContextImpl evaluationContext) throws EvaluateException {
|
||||
// ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable<ExpressionEvaluator>() {
|
||||
// public ExpressionEvaluator compute() throws EvaluateException {
|
||||
// return EvaluatorBuilderImpl.build(text, ContextUtil.getContextElement(evaluationContext), ContextUtil.getSourcePosition(evaluationContext));
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() {
|
||||
// public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException,
|
||||
// InvalidTypeException,
|
||||
// EvaluateException,
|
||||
// IncompatibleThreadStateException {
|
||||
// if (!progressWindow.isCanceled()) {
|
||||
// setValueRunnable.setValue(evaluationContext, newValue);
|
||||
// node.calcValue();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws
|
||||
// InvocationException,
|
||||
// ClassNotLoadedException,
|
||||
// EvaluateException,
|
||||
// IncompatibleThreadStateException,
|
||||
// InvalidTypeException {
|
||||
// return setValueRunnable.loadClass(evaluationContext, className);
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// progressWindow.addListener(new ProgressIndicatorListenerAdapter() {
|
||||
// //should return whether to stop processing
|
||||
// public void stopped() {
|
||||
// if(!progressWindow.isCanceled()) {
|
||||
// IJSwingUtilities.invoke(new Runnable() {
|
||||
// public void run() {
|
||||
// cancelEditing();
|
||||
// }
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// });
|
||||
//
|
||||
// progressWindow.setTitle(DebuggerBundle.message("progress.set.value"));
|
||||
// debuggerContext.getDebugProcess().getManagerThread().startProgress(evaluationCommand, progressWindow);
|
||||
// }
|
||||
//
|
||||
// public void cancelEditing() {
|
||||
// try {
|
||||
// super.cancelEditing();
|
||||
// }
|
||||
// finally {
|
||||
// comboBox.dispose();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public void doOKAction() {
|
||||
// try {
|
||||
// flushValue();
|
||||
// }
|
||||
// finally {
|
||||
// comboBox.dispose();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// };
|
||||
//
|
||||
// final DebuggerStateManager stateManager = DebuggerManagerEx.getInstanceEx(debuggerContext.getProject()).getContextManager();
|
||||
//
|
||||
// stateManager.addListener(new DebuggerContextListener() {
|
||||
// public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
// if (event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
// stateManager.removeListener(this);
|
||||
// editor.cancelEditing();
|
||||
// }
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// node.getTree().hideTooltip();
|
||||
//
|
||||
// editor.show();
|
||||
//}
|
||||
|
||||
@SuppressWarnings({"HardCodedStringLiteral"})
|
||||
private static String getDisplayableString(PrimitiveValue value, boolean showAsHex) {
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: Jul 15, 2003
|
||||
* Time: 6:38:23 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public interface VMEventListener {
|
||||
//aware! called in DebuggerEventThread
|
||||
void vmEvent(com.sun.jdi.event.Event event);
|
||||
}
|
||||
-29
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.sun.jdi.Field;
|
||||
import com.sun.jdi.ObjectReference;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Oct 15, 2003
|
||||
* Time: 11:38:25 PM
|
||||
*/
|
||||
public interface InspectField extends InspectEntity{
|
||||
ObjectReference getObject();
|
||||
Field getField ();
|
||||
}
|
||||
-31
@@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.engine.evaluation.expression;
|
||||
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.sun.jdi.LocalVariable;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Oct 15, 2003
|
||||
* Time: 11:39:04 PM
|
||||
*
|
||||
* todo [lex] does this interface really required?
|
||||
*/
|
||||
public interface InspectLocal extends InspectEntity{
|
||||
StackFrameProxyImpl getStackFrame();
|
||||
LocalVariable getLocal ();
|
||||
}
|
||||
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
/**
|
||||
* User: lex
|
||||
* Date: Sep 16, 2003
|
||||
* Time: 6:43:46 PM
|
||||
*/
|
||||
public class CompletedInputDialog extends DialogWrapper {
|
||||
JPanel myPanel;
|
||||
DebuggerExpressionComboBox myCombo;
|
||||
PsiElement myContext;
|
||||
Project myProject;
|
||||
private JLabel myLabel;
|
||||
|
||||
public CompletedInputDialog(String title, String okText, Project project) {
|
||||
super(project, false);
|
||||
setTitle(title);
|
||||
setOKButtonText(okText);
|
||||
myProject = project;
|
||||
setModal(false);
|
||||
DebuggerContextImpl debuggerContext = (DebuggerManagerEx.getInstanceEx(project)).getContext();
|
||||
myContext = PositionUtil.getContextElement(debuggerContext);
|
||||
this.init();
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myCombo.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
myPanel = new JPanel(new GridBagLayout());
|
||||
myLabel = new JLabel(DebuggerBundle.message("label.complete.input.dialog.expression"));
|
||||
myPanel.add(myLabel, new GridBagConstraints(0, 0, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.NONE,
|
||||
new Insets(0, 1, 0, 1), 0, 0));
|
||||
|
||||
myCombo = new DebuggerExpressionComboBox(myProject, myContext, "evaluation", DefaultCodeFragmentFactory.getInstance());
|
||||
myCombo.selectAll();
|
||||
|
||||
myPanel.add(myCombo, new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 1, 0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(0, 1, 0, 1), 0, 0));
|
||||
myPanel.setPreferredSize(JBUI.size(200, 50));
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public TextWithImports getExpressionText() {
|
||||
return myCombo.getText();
|
||||
}
|
||||
|
||||
public DebuggerExpressionComboBox getCombo() {
|
||||
return myCombo;
|
||||
}
|
||||
|
||||
public void setExpressionLabel(String text) {
|
||||
myLabel.setText(text);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
myCombo.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Lex
|
||||
*/
|
||||
public class DebuggerRecents {
|
||||
private final Map<Object, LinkedList<TextWithImports>> myRecentExpressions = new HashMap<Object, LinkedList<TextWithImports>>();
|
||||
|
||||
public static DebuggerRecents getInstance(Project project) {
|
||||
return ServiceManager.getService(project, DebuggerRecents.class);
|
||||
}
|
||||
|
||||
public LinkedList<TextWithImports> getRecents(Object id) {
|
||||
LinkedList<TextWithImports> result = myRecentExpressions.get(id);
|
||||
if(result == null){
|
||||
result = new LinkedList<TextWithImports>();
|
||||
myRecentExpressions.put(id, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void addRecent(Object id, TextWithImports recent) {
|
||||
LinkedList<TextWithImports> recents = getRecents(id);
|
||||
if(recents.size() >= DebuggerExpressionComboBox.MAX_ROWS) {
|
||||
recents.removeLast();
|
||||
}
|
||||
recents.remove(recent);
|
||||
recents.addFirst(recent);
|
||||
}
|
||||
}
|
||||
@@ -1,538 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebugUIEnvironment;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextListener;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.debugger.ui.impl.MainWatchPanel;
|
||||
import com.intellij.debugger.ui.impl.ThreadsPanel;
|
||||
import com.intellij.debugger.ui.impl.VariablesPanel;
|
||||
import com.intellij.debugger.ui.impl.WatchDebuggerTree;
|
||||
import com.intellij.debugger.ui.impl.watch.*;
|
||||
import com.intellij.execution.DefaultExecutionResult;
|
||||
import com.intellij.execution.ExecutionManager;
|
||||
import com.intellij.execution.ExecutionResult;
|
||||
import com.intellij.execution.configurations.RunProfile;
|
||||
import com.intellij.execution.executors.DefaultDebugExecutor;
|
||||
import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ExecutionConsoleEx;
|
||||
import com.intellij.execution.ui.layout.PlaceInGrid;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.content.AlertIcon;
|
||||
import com.intellij.ui.content.Content;
|
||||
import com.intellij.ui.content.ContentManagerAdapter;
|
||||
import com.intellij.ui.content.ContentManagerEvent;
|
||||
import com.intellij.ui.content.tabs.PinToolwindowTabAction;
|
||||
import com.intellij.xdebugger.XDebuggerBundle;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager;
|
||||
import com.intellij.xdebugger.impl.ui.DebuggerSessionTabBase;
|
||||
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreePath;
|
||||
|
||||
public class DebuggerSessionTab extends DebuggerSessionTabBase implements Disposable {
|
||||
private static final Logger LOG = Logger.getInstance(DebuggerSessionTab.class);
|
||||
|
||||
private final VariablesPanel myVariablesPanel;
|
||||
private final MainWatchPanel myWatchPanel;
|
||||
|
||||
private volatile DebuggerSession myDebuggerSession;
|
||||
|
||||
private final MyDebuggerStateManager myStateManager = new MyDebuggerStateManager();
|
||||
|
||||
private final FramesPanel myFramesPanel;
|
||||
private final DebugUIEnvironment myDebugUIEnvironment;
|
||||
|
||||
private final ThreadsPanel myThreadsPanel;
|
||||
|
||||
public DebuggerSessionTab(final Project project, final String sessionName, @NotNull final DebugUIEnvironment environment,
|
||||
@NotNull DebuggerSession debuggerSession) {
|
||||
super(project, "JavaDebugger", sessionName, debuggerSession.getSearchScope());
|
||||
|
||||
myDebuggerSession = debuggerSession;
|
||||
myDebugUIEnvironment = environment;
|
||||
|
||||
final DefaultActionGroup focus = new DefaultActionGroup();
|
||||
focus.add(ActionManager.getInstance().getAction("Debugger.FocusOnBreakpoint"));
|
||||
myUi.getOptions().setAdditionalFocusActions(focus);
|
||||
|
||||
final DebuggerSettings debuggerSettings = DebuggerSettings.getInstance();
|
||||
if (!ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
getContextManager().addListener(new DebuggerContextListener() {
|
||||
@Override
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
switch (event) {
|
||||
case DebuggerSession.EVENT_DETACHED:
|
||||
myUi.updateActionsNow();
|
||||
|
||||
if (XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isHideDebuggerOnProcessTermination()) {
|
||||
try {
|
||||
ExecutionManager.getInstance(project).getContentManager().hideRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor);
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
//if we can get closeProcess after the project have been closed
|
||||
LOG.debug(e);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DefaultActionGroup topToolbar = new DefaultActionGroup();
|
||||
ActionManager actionManager = ActionManager.getInstance();
|
||||
topToolbar.addAll(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_TOP_TOOLBAR_GROUP));
|
||||
topToolbar.add(actionManager.getAction(DebuggerActions.POP_FRAME), new Constraints(Anchor.AFTER, XDebuggerActions.STEP_OUT));
|
||||
topToolbar.add(Separator.getInstance(), new Constraints(Anchor.BEFORE, DebuggerActions.POP_FRAME));
|
||||
topToolbar.add(Separator.getInstance(), new Constraints(Anchor.AFTER, DebuggerActions.POP_FRAME));
|
||||
myUi.getOptions().setTopToolbar(topToolbar, ActionPlaces.DEBUGGER_TOOLBAR);
|
||||
|
||||
myWatchPanel = new MainWatchPanel(project, getContextManager());
|
||||
myFramesPanel = new FramesPanel(project, getContextManager());
|
||||
|
||||
final AlertIcon breakpointAlert = new AlertIcon(AllIcons.Debugger.BreakpointAlert);
|
||||
|
||||
// watches
|
||||
Content watches = myUi.createContent(DebuggerContentInfo.WATCHES_CONTENT, myWatchPanel, XDebuggerBundle.message("debugger.session.tab.watches.title"),
|
||||
AllIcons.Debugger.Watches, null);
|
||||
watches.setCloseable(false);
|
||||
watches.setAlertIcon(breakpointAlert);
|
||||
myUi.addContent(watches, 0, PlaceInGrid.right, false);
|
||||
|
||||
// frames
|
||||
Content framesContent = myUi.createContent(DebuggerContentInfo.FRAME_CONTENT, myFramesPanel, XDebuggerBundle.message("debugger.session.tab.frames.title"),
|
||||
AllIcons.Debugger.Frame, myFramesPanel.getFramesList());
|
||||
framesContent.setCloseable(false);
|
||||
framesContent.setAlertIcon(breakpointAlert);
|
||||
|
||||
myUi.addContent(framesContent, 0, PlaceInGrid.left, false);
|
||||
|
||||
// variables
|
||||
myVariablesPanel = new VariablesPanel(project, myStateManager, this);
|
||||
myVariablesPanel.getFrameTree().setAutoVariablesMode(debuggerSettings.AUTO_VARIABLES_MODE);
|
||||
Content vars = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, myVariablesPanel, XDebuggerBundle.message("debugger.session.tab.variables.title"),
|
||||
AllIcons.Debugger.Value, null);
|
||||
vars.setCloseable(false);
|
||||
vars.setAlertIcon(breakpointAlert);
|
||||
myUi.addContent(vars, 0, PlaceInGrid.center, false);
|
||||
|
||||
// threads
|
||||
myThreadsPanel = new ThreadsPanel(project, getContextManager());
|
||||
Content threadsContent = myUi.createContent(DebuggerContentInfo.THREADS_CONTENT, myThreadsPanel, XDebuggerBundle.message("debugger.session.tab.threads.title"),
|
||||
AllIcons.Debugger.Threads, null);
|
||||
threadsContent.setCloseable(false);
|
||||
//threadsContent.setAlertIcon(breakpointAlert);
|
||||
|
||||
//final DefaultActionGroup threadsGroup = new DefaultActionGroup();
|
||||
//threadsContent.setActions(threadsGroup, ActionPlaces.DEBUGGER_TOOLBAR, threadsPanel.getThreadsTree());
|
||||
|
||||
myUi.addContent(threadsContent, 0, PlaceInGrid.left, true);
|
||||
|
||||
for (Content each : myUi.getContents()) {
|
||||
updateStatus(each);
|
||||
}
|
||||
|
||||
myUi.addListener(new ContentManagerAdapter() {
|
||||
@Override
|
||||
public void selectionChanged(ContentManagerEvent event) {
|
||||
updateStatus(event.getContent());
|
||||
}
|
||||
}, this);
|
||||
|
||||
debuggerSession.getContextManager().addListener(new DebuggerContextListener() {
|
||||
@Override
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (!myUi.isDisposed()) {
|
||||
attractFramesOnPause(event);
|
||||
myStateManager.fireStateChanged(newContext, event);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myUi.isDisposed()) {
|
||||
myUi.updateActionsNow();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// ExecutionResult executionResult = debuggerSession.getProcess().getExecutionResult();
|
||||
// myConsole = executionResult.getExecutionConsole();
|
||||
// myRunContentDescriptor = new RunContentDescriptor(myConsole, executionResult.getProcessHandler(), myUi.getComponent(), getSessionName(),
|
||||
// environment.getIcon());
|
||||
// initUI(executionResult);
|
||||
}
|
||||
|
||||
private static void updateStatus(final Content content) {
|
||||
if (content.getComponent() instanceof DebuggerView) {
|
||||
final DebuggerView view = (DebuggerView)content.getComponent();
|
||||
if (content.isSelected()) {
|
||||
view.setUpdateEnabled(true);
|
||||
if (view.isRefreshNeeded()) {
|
||||
view.rebuildIfVisible(DebuggerSession.EVENT_CONTEXT);
|
||||
}
|
||||
}
|
||||
else {
|
||||
view.setUpdateEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MainWatchPanel getWatchPanel() {
|
||||
return myWatchPanel;
|
||||
}
|
||||
|
||||
private void initUI(ExecutionResult executionResult) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
myUi.removeContent(myUi.findContent(DebuggerContentInfo.CONSOLE_CONTENT), true);
|
||||
|
||||
Content console = null;
|
||||
if (myConsole instanceof ExecutionConsoleEx) {
|
||||
((ExecutionConsoleEx)myConsole).buildUi(myUi);
|
||||
console = myUi.findContent(DebuggerContentInfo.CONSOLE_CONTENT);
|
||||
if (console == null) {
|
||||
LOG.debug("Reuse console created with non-debug runner");
|
||||
}
|
||||
}
|
||||
if (console == null) {
|
||||
console = myUi.createContent(DebuggerContentInfo.CONSOLE_CONTENT, myConsole.getComponent(),
|
||||
XDebuggerBundle.message("debugger.session.tab.console.content.name"),
|
||||
AllIcons.Debugger.Console, myConsole.getPreferredFocusableComponent());
|
||||
|
||||
console.setCloseable(false);
|
||||
myUi.addContent(console, 1, PlaceInGrid.bottom, false);
|
||||
}
|
||||
attachNotificationTo(console);
|
||||
|
||||
if (myConsole != null) {
|
||||
Disposer.register(this, myConsole);
|
||||
}
|
||||
|
||||
final DefaultActionGroup consoleActions = new DefaultActionGroup();
|
||||
if (myConsole instanceof ConsoleView) {
|
||||
AnAction[] actions = ((ConsoleView)myConsole).createConsoleActions();
|
||||
for (AnAction goAction : actions) {
|
||||
consoleActions.add(goAction);
|
||||
}
|
||||
}
|
||||
console.setActions(consoleActions, ActionPlaces.DEBUGGER_TOOLBAR, myConsole.getPreferredFocusableComponent());
|
||||
|
||||
// myDebugUIEnvironment.initLogs(myRunContentDescriptor, myManager);
|
||||
|
||||
DefaultActionGroup leftToolbar = new DefaultActionGroup();
|
||||
|
||||
if (executionResult instanceof DefaultExecutionResult) {
|
||||
final AnAction[] actions = ((DefaultExecutionResult)executionResult).getRestartActions();
|
||||
leftToolbar.addAll(actions);
|
||||
if (actions.length > 0) {
|
||||
leftToolbar.addSeparator();
|
||||
}
|
||||
}
|
||||
final AnAction[] profileActions = executionResult.getActions();
|
||||
leftToolbar.addAll(profileActions);
|
||||
|
||||
leftToolbar.add(getCustomizedActionGroup(XDebuggerActions.TOOL_WINDOW_LEFT_TOOLBAR_GROUP));
|
||||
if (executionResult instanceof DefaultExecutionResult) {
|
||||
AnAction[] actions = ((DefaultExecutionResult)executionResult).getAdditionalStopActions();
|
||||
for (AnAction action : actions) {
|
||||
leftToolbar.add(action, new Constraints(Anchor.AFTER, IdeActions.ACTION_STOP_PROGRAM));
|
||||
}
|
||||
}
|
||||
|
||||
leftToolbar.addSeparator();
|
||||
addAction(leftToolbar, DebuggerActions.DUMP_THREADS);
|
||||
leftToolbar.addSeparator();
|
||||
|
||||
leftToolbar.add(myUi.getOptions().getLayoutActions());
|
||||
|
||||
final AnAction[] commonSettings = myUi.getOptions().getSettingsActionsList();
|
||||
final AnAction commonSettingsList = myUi.getOptions().getSettingsActions();
|
||||
|
||||
final DefaultActionGroup settings = new DefaultActionGroup("DebuggerSettings", true) {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setText(ActionsBundle.message("group.XDebugger.settings.text"));
|
||||
e.getPresentation().setIcon(commonSettingsList.getTemplatePresentation().getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDumbAware() {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
for (AnAction each : commonSettings) {
|
||||
settings.add(each);
|
||||
}
|
||||
if (commonSettings.length > 0) {
|
||||
settings.addSeparator();
|
||||
}
|
||||
settings.add(new WatchLastMethodReturnValueAction());
|
||||
settings.add(new AutoVarsSwitchAction());
|
||||
settings.addSeparator();
|
||||
addActionToGroup(settings, XDebuggerActions.INLINE_DEBUGGER);
|
||||
addActionToGroup(settings, XDebuggerActions.AUTO_TOOLTIP);
|
||||
addActionToGroup(settings, XDebuggerActions.AUTO_TOOLTIP_ON_SELECTION);
|
||||
|
||||
leftToolbar.add(settings);
|
||||
|
||||
leftToolbar.addSeparator();
|
||||
|
||||
addActionToGroup(leftToolbar, PinToolwindowTabAction.ACTION_NAME);
|
||||
|
||||
myDebugUIEnvironment.initActions(myRunContentDescriptor, leftToolbar);
|
||||
|
||||
myUi.getOptions().setLeftToolbar(leftToolbar, ActionPlaces.DEBUGGER_TOOLBAR);
|
||||
}
|
||||
|
||||
private static void addAction(DefaultActionGroup group, String actionId) {
|
||||
group.add(ActionManager.getInstance().getAction(actionId));
|
||||
}
|
||||
|
||||
private static void addActionToGroup(final DefaultActionGroup group, final String actionId) {
|
||||
AnAction action = ActionManager.getInstance().getAction(actionId);
|
||||
if (action != null) group.add(action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
disposeSession();
|
||||
myFramesPanel.dispose();
|
||||
myVariablesPanel.dispose();
|
||||
myWatchPanel.dispose();
|
||||
myThreadsPanel.dispose();
|
||||
myConsole = null;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private void disposeSession() {
|
||||
final DebuggerSession session = myDebuggerSession;
|
||||
myDebuggerSession = null;
|
||||
if (session != null) {
|
||||
session.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private DebugProcessImpl getDebugProcess() {
|
||||
final DebuggerSession session = myDebuggerSession;
|
||||
return session != null ? session.getProcess() : null;
|
||||
}
|
||||
|
||||
public void reuse(DebuggerSessionTab reuseSession) {
|
||||
DebuggerTreeNodeImpl[] watches = reuseSession.getWatchPanel().getWatchTree().getWatches();
|
||||
|
||||
final WatchDebuggerTree watchTree = getWatchPanel().getWatchTree();
|
||||
for (DebuggerTreeNodeImpl watch : watches) {
|
||||
watchTree.addWatch((WatchItemDescriptor)watch.getDescriptor());
|
||||
}
|
||||
|
||||
DebugProcessImpl process = getDebugProcess();
|
||||
DebugProcessImpl reuseProcess = reuseSession.getDebugProcess();
|
||||
if (process != null && reuseProcess != null) {
|
||||
//process.setBreakpointsMuted(reuseProcess.areBreakpointsMuted());
|
||||
}
|
||||
}
|
||||
|
||||
public String getSessionName() {
|
||||
return myDebugUIEnvironment.getEnvironment().getSessionName();
|
||||
}
|
||||
|
||||
public DebuggerStateManager getContextManager() {
|
||||
return myStateManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TextWithImports getSelectedExpression() {
|
||||
final DebuggerSession session = myDebuggerSession;
|
||||
if (session == null || session.getState() != DebuggerSession.STATE_PAUSED) {
|
||||
return null;
|
||||
}
|
||||
JTree tree = myVariablesPanel.getFrameTree();
|
||||
if (tree == null || !tree.hasFocus()) {
|
||||
tree = myWatchPanel.getWatchTree();
|
||||
if (tree == null || !tree.hasFocus()) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
TreePath path = tree.getSelectionPath();
|
||||
if (path == null) {
|
||||
return null;
|
||||
}
|
||||
DebuggerTreeNodeImpl node = (DebuggerTreeNodeImpl)path.getLastPathComponent();
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (!(descriptor instanceof ValueDescriptorImpl)) {
|
||||
return null;
|
||||
}
|
||||
if (descriptor instanceof WatchItemDescriptor) {
|
||||
return ((WatchItemDescriptor)descriptor).getEvaluationText();
|
||||
}
|
||||
try {
|
||||
return DebuggerTreeNodeExpression.createEvaluationText(node, getContextManager().getContext());
|
||||
}
|
||||
catch (EvaluateException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected RunProfile getRunProfile() {
|
||||
return myDebugUIEnvironment.getRunProfile();
|
||||
}
|
||||
|
||||
private void attractFramesOnPause(final int event) {
|
||||
if (DebuggerSession.EVENT_PAUSE == event) {
|
||||
myUi.attractBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
|
||||
}
|
||||
else if (DebuggerSession.EVENT_RESUME == event) {
|
||||
myUi.clearAttractionBy(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION);
|
||||
}
|
||||
}
|
||||
|
||||
public DebuggerSession getSession() {
|
||||
return myDebuggerSession;
|
||||
}
|
||||
|
||||
public void showFramePanel() {
|
||||
myUi.selectAndFocus(myUi.findContent(DebuggerContentInfo.FRAME_CONTENT), true, false);
|
||||
}
|
||||
|
||||
private class MyDebuggerStateManager extends DebuggerStateManager {
|
||||
@Override
|
||||
public void fireStateChanged(DebuggerContextImpl newContext, int event) {
|
||||
super.fireStateChanged(newContext, event);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebuggerContextImpl getContext() {
|
||||
final DebuggerSession session = myDebuggerSession;
|
||||
return session != null ? session.getContextManager().getContext() : DebuggerContextImpl.EMPTY_CONTEXT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setState(DebuggerContextImpl context, int state, int event, String description) {
|
||||
final DebuggerSession session = myDebuggerSession;
|
||||
if (session != null) {
|
||||
session.getContextManager().setState(context, state, event, description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class AutoVarsSwitchAction extends ToggleAction {
|
||||
private volatile boolean myAutoModeEnabled;
|
||||
|
||||
public AutoVarsSwitchAction() {
|
||||
super("", "", AllIcons.Debugger.AutoVariablesMode);
|
||||
myAutoModeEnabled = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
final boolean autoModeEnabled = Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY));
|
||||
presentation.setText(autoModeEnabled ? "All-Variables Mode" : "Auto-Variables Mode");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myAutoModeEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean enabled) {
|
||||
myAutoModeEnabled = enabled;
|
||||
DebuggerSettings.getInstance().AUTO_VARIABLES_MODE = enabled;
|
||||
myVariablesPanel.getFrameTree().setAutoVariablesMode(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private class WatchLastMethodReturnValueAction extends ToggleAction {
|
||||
private volatile boolean myWatchesReturnValues;
|
||||
private final String myTextEnable;
|
||||
private final String myTextUnavailable;
|
||||
private final String myMyTextDisable;
|
||||
|
||||
public WatchLastMethodReturnValueAction() {
|
||||
super("", DebuggerBundle.message("action.watch.method.return.value.description"), null);
|
||||
myWatchesReturnValues = DebuggerSettings.getInstance().WATCH_RETURN_VALUES;
|
||||
myTextEnable = DebuggerBundle.message("action.watches.method.return.value.enable");
|
||||
myMyTextDisable = DebuggerBundle.message("action.watches.method.return.value.disable");
|
||||
myTextUnavailable = DebuggerBundle.message("action.watches.method.return.value.unavailable.reason");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
final boolean watchValues = Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY));
|
||||
final DebugProcessImpl process = getDebugProcess();
|
||||
final String actionText = watchValues ? myMyTextDisable : myTextEnable;
|
||||
if (process != null && process.canGetMethodReturnValue()) {
|
||||
presentation.setEnabled(true);
|
||||
presentation.setText(actionText);
|
||||
}
|
||||
else {
|
||||
presentation.setEnabled(false);
|
||||
presentation.setText(process == null ? actionText : myTextUnavailable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myWatchesReturnValues;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean watch) {
|
||||
myWatchesReturnValues = watch;
|
||||
DebuggerSettings.getInstance().WATCH_RETURN_VALUES = watch;
|
||||
final DebugProcessImpl process = getDebugProcess();
|
||||
if (process != null) {
|
||||
process.setWatchMethodReturnValuesEnabled(watch);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.ex.EditorEx;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
|
||||
/**
|
||||
* @author lex
|
||||
*/
|
||||
public class DebuggerStatementEditor extends DebuggerEditorImpl {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerStatementEditor");
|
||||
|
||||
private final EditorTextField myEditor;
|
||||
|
||||
private int myRecentIdx;
|
||||
|
||||
public DebuggerStatementEditor(Project project, PsiElement context, @NonNls String recentsId, final CodeFragmentFactory factory) {
|
||||
super(project, context, recentsId, factory);
|
||||
myRecentIdx = getRecentItemsCount();
|
||||
final Document document = EditorFactory.getInstance().createDocument("");
|
||||
myEditor = new EditorTextField(document, project, factory.getFileType(), false, false) {
|
||||
protected EditorEx createEditor() {
|
||||
EditorEx editor = super.createEditor();
|
||||
editor.setVerticalScrollbarVisible(true);
|
||||
editor.setHorizontalScrollbarVisible(true);
|
||||
return editor;
|
||||
}
|
||||
};
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
add(addChooseFactoryLabel(myEditor, true));
|
||||
|
||||
DefaultActionGroup actionGroup = new DefaultActionGroup(null, false);
|
||||
actionGroup.add(new ItemAction(IdeActions.ACTION_PREVIOUS_OCCURENCE, this){
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
LOG.assertTrue(myRecentIdx >= 0);
|
||||
// since recents are stored in a stack, previous item is at currentIndex + 1
|
||||
myRecentIdx += 1;
|
||||
updateTextFromRecents();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myRecentIdx < getRecentItemsCount());
|
||||
}
|
||||
});
|
||||
actionGroup.add(new ItemAction(IdeActions.ACTION_NEXT_OCCURENCE, this){
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if(LOG.isDebugEnabled()) {
|
||||
LOG.assertTrue(myRecentIdx < getRecentItemsCount());
|
||||
}
|
||||
// since recents are stored in a stack, next item is at currentIndex - 1
|
||||
myRecentIdx -= 1;
|
||||
updateTextFromRecents();
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
e.getPresentation().setEnabled(myRecentIdx > 0);
|
||||
}
|
||||
});
|
||||
|
||||
add(ActionManager.getInstance().createActionToolbar(ActionPlaces.COMBO_PAGER, actionGroup, false).getComponent(),
|
||||
BorderLayout.EAST);
|
||||
|
||||
setText(new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, ""));
|
||||
}
|
||||
|
||||
private void updateTextFromRecents() {
|
||||
List<TextWithImports> recents = getRecents();
|
||||
LOG.assertTrue(myRecentIdx <= recents.size());
|
||||
setText(myRecentIdx < recents.size() ? recents.get(myRecentIdx) : new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""));
|
||||
}
|
||||
|
||||
private List<TextWithImports> getRecents() {
|
||||
final LinkedList<TextWithImports> recents = DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId());
|
||||
final ArrayList<TextWithImports> reversed = new ArrayList<TextWithImports>(recents.size());
|
||||
for (final ListIterator<TextWithImports> it = recents.listIterator(recents.size()); it.hasPrevious();) {
|
||||
reversed.add(it.previous());
|
||||
}
|
||||
return reversed;
|
||||
}
|
||||
|
||||
private int getRecentItemsCount() {
|
||||
return DebuggerRecents.getInstance(getProject()).getRecents(getRecentsId()).size();
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
final Editor editor = myEditor.getEditor();
|
||||
return editor != null? editor.getContentComponent() : myEditor;
|
||||
}
|
||||
|
||||
public TextWithImports getText() {
|
||||
return createItem(myEditor.getDocument(), getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doSetText(TextWithImports text) {
|
||||
restoreFactory(text);
|
||||
myEditor.setNewDocumentAndFileType(getCurrentFactory().getFileType(), createDocument(text));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateEditorUi() {
|
||||
final Editor editor = myEditor.getEditor();
|
||||
if (editor != null) {
|
||||
DaemonCodeAnalyzer.getInstance(getProject()).updateVisibleHighlighters(editor);
|
||||
}
|
||||
}
|
||||
|
||||
public TextWithImports createText(String text, String importsString) {
|
||||
return new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, text, importsString, getCurrentFactory().getFileType());
|
||||
}
|
||||
|
||||
private static abstract class ItemAction extends AnAction {
|
||||
public ItemAction(String sourceActionName, JComponent component) {
|
||||
copyFrom(ActionManager.getInstance().getAction(sourceActionName));
|
||||
registerCustomShortcutSet(getShortcutSet(), component);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.CommonBundle;
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextListener;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.debugger.ui.impl.ValueNodeDnD;
|
||||
import com.intellij.debugger.ui.impl.WatchDebuggerTree;
|
||||
import com.intellij.debugger.ui.impl.WatchPanel;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.xdebugger.XDebuggerBundle;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.tree.TreeModel;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class EvaluationDialog extends DialogWrapper {
|
||||
private final MyEvaluationPanel myEvaluationPanel;
|
||||
private final Project myProject;
|
||||
private final DebuggerContextListener myContextListener;
|
||||
private final DebuggerEditorImpl myEditor;
|
||||
private final List<Runnable> myDisposeRunnables = new ArrayList<Runnable>();
|
||||
|
||||
public EvaluationDialog(Project project, TextWithImports text) {
|
||||
super(project, true);
|
||||
myProject = project;
|
||||
setModal(false);
|
||||
setCancelButtonText(CommonBundle.message("button.close"));
|
||||
setOKButtonText(DebuggerBundle.message("button.evaluate"));
|
||||
|
||||
myEvaluationPanel = new MyEvaluationPanel(myProject);
|
||||
|
||||
myEditor = createEditor(DefaultCodeFragmentFactory.getInstance());
|
||||
|
||||
setDebuggerContext(getDebuggerContext());
|
||||
initDialogData(text);
|
||||
|
||||
myContextListener = new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
boolean close = true;
|
||||
for (DebuggerSession session : DebuggerManagerEx.getInstanceEx(myProject).getSessions()) {
|
||||
if (!session.isStopped()) {
|
||||
close = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(close) {
|
||||
close(CANCEL_EXIT_CODE);
|
||||
}
|
||||
else {
|
||||
setDebuggerContext(newContext);
|
||||
}
|
||||
}
|
||||
};
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getContextManager().addListener(myContextListener);
|
||||
|
||||
setHorizontalStretch(1f);
|
||||
setVerticalStretch(1f);
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
if (isOKActionEnabled()) {
|
||||
doEvaluate();
|
||||
}
|
||||
}
|
||||
|
||||
protected void doEvaluate() {
|
||||
if (myEditor == null || myEvaluationPanel == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
myEvaluationPanel.clear();
|
||||
TextWithImports codeToEvaluate = getCodeToEvaluate();
|
||||
if (codeToEvaluate == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
setOKActionEnabled(false);
|
||||
NodeDescriptorImpl descriptor = myEvaluationPanel.getWatchTree().addWatch(codeToEvaluate, "result").getDescriptor();
|
||||
//if (descriptor instanceof EvaluationDescriptor) {
|
||||
// final EvaluationDescriptor evalDescriptor = (EvaluationDescriptor)descriptor;
|
||||
// evalDescriptor.setCodeFragmentFactory(myEditor.getCurrentFactory());
|
||||
//}
|
||||
myEvaluationPanel.getWatchTree().rebuild(getDebuggerContext());
|
||||
descriptor.myIsExpanded = true;
|
||||
}
|
||||
finally {
|
||||
setOKActionEnabled(true);
|
||||
}
|
||||
getEditor().addRecent(getCodeToEvaluate());
|
||||
|
||||
final DebuggerSession session = myEvaluationPanel.getContextManager().getContext().getDebuggerSession();
|
||||
if (session != null) {
|
||||
session.refresh(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected TextWithImports getCodeToEvaluate() {
|
||||
TextWithImports text = getEditor().getText();
|
||||
String s = text.getText();
|
||||
if (s != null) {
|
||||
s = s.trim();
|
||||
}
|
||||
if ("".equals(s)) {
|
||||
return null;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myEditor.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey() {
|
||||
return "#com.intellij.debugger.ui.EvaluationDialog2";
|
||||
}
|
||||
|
||||
protected void addDisposeRunnable (Runnable runnable) {
|
||||
myDisposeRunnables.add(runnable);
|
||||
}
|
||||
|
||||
public void dispose() {
|
||||
for (Runnable runnable : myDisposeRunnables) {
|
||||
runnable.run();
|
||||
}
|
||||
myDisposeRunnables.clear();
|
||||
myEditor.dispose();
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getContextManager().removeListener(myContextListener);
|
||||
myEvaluationPanel.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
protected class MyEvaluationPanel extends WatchPanel {
|
||||
public MyEvaluationPanel(final Project project) {
|
||||
super(project, (DebuggerManagerEx.getInstanceEx(project)).getContextManager());
|
||||
final WatchDebuggerTree watchTree = getWatchTree();
|
||||
final AnAction setValueAction = ActionManager.getInstance().getAction(DebuggerActions.SET_VALUE);
|
||||
setValueAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), watchTree);
|
||||
registerDisposable(new Disposable() {
|
||||
public void dispose() {
|
||||
setValueAction.unregisterCustomShortcutSet(watchTree);
|
||||
}
|
||||
});
|
||||
setUpdateEnabled(true);
|
||||
getTree().getEmptyText().setText(XDebuggerBundle.message("debugger.no.results"));
|
||||
new ValueNodeDnD(myTree, project);
|
||||
}
|
||||
|
||||
protected ActionPopupMenu createPopupMenu() {
|
||||
ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.EVALUATION_DIALOG_POPUP);
|
||||
return ActionManager.getInstance().createActionPopupMenu(DebuggerActions.EVALUATION_DIALOG_POPUP, group);
|
||||
}
|
||||
|
||||
protected void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event == DebuggerSession.EVENT_REFRESH || event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY) {
|
||||
// in order not to spoil the evaluation result do not re-evaluate the tree
|
||||
final TreeModel treeModel = getTree().getModel();
|
||||
updateTree(treeModel, (DebuggerTreeNodeImpl)treeModel.getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTree(final TreeModel model, final DebuggerTreeNodeImpl node) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
if (node.getDescriptor().myIsExpanded) {
|
||||
final int count = model.getChildCount(node);
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
final DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl)model.getChild(node, idx);
|
||||
updateTree(model, child);
|
||||
}
|
||||
}
|
||||
node.labelChanged();
|
||||
}
|
||||
}
|
||||
|
||||
protected void setDebuggerContext(DebuggerContextImpl context) {
|
||||
final PsiElement contextElement = PositionUtil.getContextElement(context);
|
||||
myEditor.setContext(contextElement);
|
||||
}
|
||||
|
||||
protected PsiElement getContext() {
|
||||
return myEditor.getContext();
|
||||
}
|
||||
|
||||
protected void initDialogData(TextWithImports text) {
|
||||
getEditor().setText(text);
|
||||
myEvaluationPanel.clear();
|
||||
}
|
||||
|
||||
public DebuggerContextImpl getDebuggerContext() {
|
||||
return DebuggerManagerEx.getInstanceEx(myProject).getContext();
|
||||
}
|
||||
|
||||
public DebuggerEditorImpl getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
protected abstract DebuggerEditorImpl createEditor(final CodeFragmentFactory factory);
|
||||
|
||||
protected MyEvaluationPanel getEvaluationPanel() {
|
||||
return myEvaluationPanel;
|
||||
}
|
||||
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: May 28, 2003
|
||||
* Time: 1:59:27 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public interface EvaluatorRunnable extends Runnable{
|
||||
Object getValue();
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Dec 14, 2001
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.HelpID;
|
||||
import com.intellij.debugger.actions.ThreadDumpAction;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.jdi.VirtualMachineProxyImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.MessageDescriptor;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
import com.intellij.openapi.help.HelpManager;
|
||||
import com.intellij.openapi.ide.CopyPasteManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.util.ui.JBUI;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class ExportDialog extends DialogWrapper {
|
||||
private final JTextArea myTextArea = new JTextArea();
|
||||
private TextFieldWithBrowseButton myTfFilePath;
|
||||
private final Project myProject;
|
||||
private final DebugProcessImpl myDebugProcess;
|
||||
private final CopyToClipboardAction myCopyToClipboardAction = new CopyToClipboardAction();
|
||||
private static final @NonNls String DEFAULT_REPORT_FILE_NAME = "threads_report.txt";
|
||||
|
||||
public ExportDialog(DebugProcessImpl debugProcess, String destinationDirectory) {
|
||||
super(debugProcess.getProject(), true);
|
||||
myDebugProcess = debugProcess;
|
||||
myProject = debugProcess.getProject();
|
||||
setTitle(DebuggerBundle.message("threads.export.dialog.title"));
|
||||
setOKButtonText(DebuggerBundle.message("button.save"));
|
||||
|
||||
init();
|
||||
|
||||
setOKActionEnabled(false);
|
||||
myCopyToClipboardAction.setEnabled(false);
|
||||
|
||||
myTextArea.setText(MessageDescriptor.EVALUATING.getLabel());
|
||||
debugProcess.getManagerThread().invoke(new ExportThreadsCommand(ApplicationManager.getApplication().getModalityStateForComponent(myTextArea)));
|
||||
|
||||
myTfFilePath.setText(destinationDirectory + File.separator + DEFAULT_REPORT_FILE_NAME);
|
||||
setHorizontalStretch(1.5f);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected Action[] createActions(){
|
||||
return new Action[]{getOKAction(), myCopyToClipboardAction, getCancelAction(), getHelpAction()};
|
||||
}
|
||||
|
||||
protected void doHelpAction() {
|
||||
HelpManager.getInstance().invokeHelp(HelpID.EXPORT_THREADS);
|
||||
}
|
||||
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel box = new JPanel(new BorderLayout());
|
||||
box.add(new JLabel(DebuggerBundle.message("label.threads.export.dialog.file")), BorderLayout.WEST);
|
||||
myTfFilePath = new TextFieldWithBrowseButton();
|
||||
myTfFilePath.addBrowseFolderListener(null, null, myProject, FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor());
|
||||
box.add(myTfFilePath, BorderLayout.CENTER);
|
||||
JPanel panel = new JPanel(new BorderLayout());
|
||||
panel.add(box, BorderLayout.CENTER);
|
||||
panel.add(Box.createVerticalStrut(7), BorderLayout.SOUTH);
|
||||
return panel;
|
||||
}
|
||||
|
||||
protected JComponent createCenterPanel() {
|
||||
myTextArea.setEditable(false);
|
||||
JScrollPane pane = ScrollPaneFactory.createScrollPane(myTextArea);
|
||||
pane.setPreferredSize(JBUI.size(400, 300));
|
||||
return pane;
|
||||
}
|
||||
|
||||
protected void doOKAction() {
|
||||
String path = myTfFilePath.getText();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory()) {
|
||||
Messages.showMessageDialog(
|
||||
myProject,
|
||||
DebuggerBundle.message("error.threads.export.dialog.file.is.directory"),
|
||||
DebuggerBundle.message("threads.export.dialog.title"),
|
||||
Messages.getErrorIcon()
|
||||
);
|
||||
}
|
||||
else if (file.exists()) {
|
||||
int answer = Messages.showYesNoDialog(
|
||||
myProject,
|
||||
DebuggerBundle.message("error.threads.export.dialog.file.already.exists", path),
|
||||
DebuggerBundle.message("threads.export.dialog.title"),
|
||||
Messages.getQuestionIcon()
|
||||
);
|
||||
if (answer == Messages.YES) {
|
||||
super.doOKAction();
|
||||
}
|
||||
}
|
||||
else {
|
||||
super.doOKAction();
|
||||
}
|
||||
}
|
||||
|
||||
public String getFilePath() {
|
||||
return myTfFilePath.getText();
|
||||
}
|
||||
|
||||
public String getTextToSave() {
|
||||
return myTextArea.getText();
|
||||
}
|
||||
|
||||
protected String getDimensionServiceKey(){
|
||||
return "#com.intellij.debugger.ui.ExportDialog";
|
||||
}
|
||||
|
||||
public static String getExportThreadsText(VirtualMachineProxyImpl vmProxy) {
|
||||
final StringBuffer buffer = new StringBuffer(512);
|
||||
List<ThreadReference> threads = vmProxy.getVirtualMachine().allThreads();
|
||||
for (ThreadReference threadReference : threads) {
|
||||
final String name = threadName(threadReference);
|
||||
if (name == null) {
|
||||
continue;
|
||||
}
|
||||
buffer.append(name);
|
||||
ReferenceType referenceType = threadReference.referenceType();
|
||||
if (referenceType != null) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
Field daemon = referenceType.fieldByName("daemon");
|
||||
if (daemon != null) {
|
||||
Value value = threadReference.getValue(daemon);
|
||||
if (value instanceof BooleanValue && ((BooleanValue)value).booleanValue()) {
|
||||
buffer.append(" ").append(DebuggerBundle.message("threads.export.attribute.label.daemon"));
|
||||
}
|
||||
}
|
||||
|
||||
//noinspection HardCodedStringLiteral
|
||||
Field priority = referenceType.fieldByName("priority");
|
||||
if (priority != null) {
|
||||
Value value = threadReference.getValue(priority);
|
||||
if (value instanceof IntegerValue) {
|
||||
buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.priority", ((IntegerValue)value).intValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadGroupReference groupReference = threadReference.threadGroup();
|
||||
if (groupReference != null) {
|
||||
buffer.append(", ").append(DebuggerBundle.message("threads.export.attribute.label.group", groupReference.name()));
|
||||
}
|
||||
buffer.append(", ").append(
|
||||
DebuggerBundle.message("threads.export.attribute.label.status", DebuggerUtilsEx.getThreadStatusText(threadReference.status())));
|
||||
|
||||
try {
|
||||
if (vmProxy.canGetOwnedMonitorInfo() && vmProxy.canGetMonitorInfo()) {
|
||||
List<ObjectReference> list = threadReference.ownedMonitors();
|
||||
for (ObjectReference reference : list) {
|
||||
final List<ThreadReference> waiting = reference.waitingThreads();
|
||||
for (ThreadReference thread : waiting) {
|
||||
final String waitingThreadName = threadName(thread);
|
||||
if (waitingThreadName != null) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", waitingThreadName));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ObjectReference waitedMonitor = vmProxy.canGetCurrentContendedMonitor() ? threadReference.currentContendedMonitor() : null;
|
||||
if (waitedMonitor != null) {
|
||||
if (vmProxy.canGetMonitorInfo()) {
|
||||
ThreadReference waitedThread = waitedMonitor.owningThread();
|
||||
if (waitedThread != null) {
|
||||
final String waitedThreadName = threadName(waitedThread);
|
||||
if (waitedThreadName != null) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", waitedThreadName,
|
||||
ThreadDumpAction.renderObject(waitedMonitor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final List<StackFrame> frames = threadReference.frames();
|
||||
for (StackFrame stackFrame : frames) {
|
||||
final Location location = stackFrame.location();
|
||||
buffer.append("\n\t ").append(renderLocation(location));
|
||||
}
|
||||
}
|
||||
catch (IncompatibleThreadStateException e) {
|
||||
buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.error.incompatible.state"));
|
||||
}
|
||||
buffer.append("\n\n");
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private static String renderLocation(final Location location) {
|
||||
String sourceName;
|
||||
try {
|
||||
sourceName = location.sourceName();
|
||||
}
|
||||
catch (AbsentInformationException e) {
|
||||
sourceName = "Unknown Source";
|
||||
}
|
||||
return DebuggerBundle.message(
|
||||
"export.threads.stackframe.format",
|
||||
DebuggerUtilsEx.getLocationMethodQName(location),
|
||||
sourceName,
|
||||
location.lineNumber()
|
||||
);
|
||||
}
|
||||
|
||||
private static String threadName(ThreadReference threadReference) {
|
||||
try {
|
||||
return threadReference.name() + "@" + threadReference.uniqueID();
|
||||
}
|
||||
catch (ObjectCollectedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private class CopyToClipboardAction extends AbstractAction {
|
||||
public CopyToClipboardAction() {
|
||||
super(DebuggerBundle.message("button.copy"));
|
||||
putValue(Action.SHORT_DESCRIPTION, DebuggerBundle.message("export.dialog.copy.action.description"));
|
||||
}
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
String s = StringUtil.convertLineSeparators(myTextArea.getText());
|
||||
CopyPasteManager.getInstance().setContents(new StringSelection(s));
|
||||
}
|
||||
}
|
||||
|
||||
private class ExportThreadsCommand extends DebuggerCommandImpl {
|
||||
protected ModalityState myModalityState;
|
||||
|
||||
public ExportThreadsCommand(ModalityState modalityState) {
|
||||
myModalityState = modalityState;
|
||||
}
|
||||
|
||||
private void setText(final String text) {
|
||||
DebuggerInvocationUtil.invokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTextArea.setText(text);
|
||||
setOKActionEnabled(true);
|
||||
myCopyToClipboardAction.setEnabled(true);
|
||||
}
|
||||
}, myModalityState);
|
||||
}
|
||||
|
||||
protected void action() {
|
||||
setText(getExportThreadsText(myDebugProcess.getVirtualMachineProxy()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,732 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerManagerThreadImpl;
|
||||
import com.intellij.debugger.engine.SuspendContextImpl;
|
||||
import com.intellij.debugger.engine.SuspendManagerUtil;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.engine.events.SuspendContextCommandImpl;
|
||||
import com.intellij.debugger.engine.jdi.StackFrameProxy;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextUtil;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.settings.DebuggerSettings;
|
||||
import com.intellij.debugger.ui.impl.DebuggerComboBoxRenderer;
|
||||
import com.intellij.debugger.ui.impl.FramesList;
|
||||
import com.intellij.debugger.ui.impl.UpdatableDebuggerView;
|
||||
import com.intellij.debugger.ui.impl.watch.MethodsTracker;
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.render.DescriptorLabelListener;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.CommonActionsManager;
|
||||
import com.intellij.ide.OccurenceNavigator;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.ComboBoxWithWidePopup;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.ui.CaptionPanel;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import com.intellij.ui.border.CustomLineBorder;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.sun.jdi.ObjectCollectedException;
|
||||
import com.sun.jdi.VMDisconnectedException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
import javax.swing.event.ListSelectionEvent;
|
||||
import javax.swing.event.ListSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class FramesPanel extends UpdatableDebuggerView implements DataProvider {
|
||||
private static final Icon FILTER_STACK_FRAMES_ICON = AllIcons.Debugger.Class_filter;
|
||||
|
||||
private final JComboBox myThreadsCombo;
|
||||
private final FramesList myFramesList;
|
||||
private final ThreadsListener myThreadsListener;
|
||||
private final FramesListener myFramesListener;
|
||||
private final DebuggerStateManager myStateManager;
|
||||
private boolean myShowLibraryFrames = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
|
||||
private final Alarm myRebuildAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
|
||||
|
||||
public FramesPanel(Project project, DebuggerStateManager stateManager) {
|
||||
super(project, stateManager);
|
||||
myStateManager = stateManager;
|
||||
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
myThreadsCombo = new ComboBoxWithWidePopup();
|
||||
myThreadsCombo.setRenderer(new DebuggerComboBoxRenderer(myThreadsCombo.getRenderer()));
|
||||
myThreadsListener = new ThreadsListener();
|
||||
myThreadsCombo.addItemListener(myThreadsListener);
|
||||
|
||||
myFramesList = new FramesList(project);
|
||||
myFramesListener = new FramesListener();
|
||||
myFramesList.addListSelectionListener(myFramesListener);
|
||||
|
||||
myFramesList.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mousePressed(final MouseEvent e) {
|
||||
int index = myFramesList.locationToIndex(e.getPoint());
|
||||
if (index >= 0 && myFramesList.isSelectedIndex(index)) {
|
||||
processListValue(myFramesList.getModel().getElementAt(index));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerThreadsPopupMenu(myFramesList);
|
||||
|
||||
setBorder(null);
|
||||
|
||||
final ActionToolbar toolbar = createToolbar();
|
||||
Wrapper threads = new Wrapper();
|
||||
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR, 0, 0, 1, 0);
|
||||
threads.setBorder(border);
|
||||
threads.add(toolbar.getComponent(), BorderLayout.EAST);
|
||||
threads.add(myThreadsCombo, BorderLayout.CENTER);
|
||||
add(threads, BorderLayout.NORTH);
|
||||
add(ScrollPaneFactory.createScrollPane(myFramesList), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
private ActionToolbar createToolbar() {
|
||||
final DefaultActionGroup framesGroup = new DefaultActionGroup();
|
||||
framesGroup.addSeparator();
|
||||
|
||||
CommonActionsManager actionsManager = CommonActionsManager.getInstance();
|
||||
framesGroup.add(actionsManager.createPrevOccurenceAction(getOccurenceNavigator()));
|
||||
framesGroup.add(actionsManager.createNextOccurenceAction(getOccurenceNavigator()));
|
||||
framesGroup.add(new ShowLibraryFramesAction());
|
||||
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.DEBUGGER_TOOLBAR, framesGroup, true);
|
||||
toolbar.setReservePlaceAutoPopupIcon(false);
|
||||
((ActionToolbarImpl)toolbar).setAddSeparatorFirst(true);
|
||||
toolbar.getComponent().setBorder(new EmptyBorder(1, 0, 0, 0));
|
||||
return toolbar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DebuggerStateManager getContextManager() {
|
||||
return myStateManager;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object getData(@NonNls String dataId) {
|
||||
if (CommonDataKeys.PSI_FILE.is(dataId)) {
|
||||
DebuggerContextImpl context = myStateManager.getContext();
|
||||
if (context != null) {
|
||||
SourcePosition position = context.getSourcePosition();
|
||||
if (position != null) {
|
||||
return position.getFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private class FramesListener implements ListSelectionListener {
|
||||
boolean myIsEnabled = true;
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
myIsEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void valueChanged(ListSelectionEvent e) {
|
||||
if (!myIsEnabled || e.getValueIsAdjusting()) {
|
||||
return;
|
||||
}
|
||||
final JList list = (JList)e.getSource();
|
||||
processListValue(list.getSelectedValue());
|
||||
}
|
||||
|
||||
}
|
||||
private void processListValue(final Object selected) {
|
||||
if (selected instanceof StackFrameDescriptorImpl) {
|
||||
DebuggerContextUtil.setStackFrame(getContextManager(), ((StackFrameDescriptorImpl)selected).getFrameProxy());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void registerThreadsPopupMenu(final JList framesList) {
|
||||
final PopupHandler popupHandler = new PopupHandler() {
|
||||
@Override
|
||||
public void invokePopup(Component comp, int x, int y) {
|
||||
DefaultActionGroup group = (DefaultActionGroup)ActionManager.getInstance().getAction(DebuggerActions.THREADS_PANEL_POPUP);
|
||||
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.THREADS_PANEL_POPUP, group);
|
||||
popupMenu.getComponent().show(comp, x, y);
|
||||
}
|
||||
};
|
||||
framesList.addMouseListener(popupHandler);
|
||||
registerDisposable(new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
myThreadsCombo.removeItemListener(myThreadsListener);
|
||||
framesList.removeMouseListener(popupHandler);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class ThreadsListener implements ItemListener {
|
||||
boolean myIsEnabled = true;
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
myIsEnabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (!myIsEnabled) return;
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
ThreadDescriptorImpl item = (ThreadDescriptorImpl)e.getItem();
|
||||
DebuggerContextUtil.setThread(getContextManager(), item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final AtomicBoolean myPerformFullRebuild = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
protected void rebuild(int event) {
|
||||
myRebuildAlarm.cancelAllRequests();
|
||||
final boolean isRefresh = event == DebuggerSession.EVENT_REFRESH ||
|
||||
event == DebuggerSession.EVENT_REFRESH_VIEWS_ONLY ||
|
||||
event == DebuggerSession.EVENT_THREADS_REFRESH;
|
||||
if (!isRefresh) {
|
||||
myPerformFullRebuild.set(true);
|
||||
}
|
||||
myRebuildAlarm.addRequest(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
doRebuild(!myPerformFullRebuild.getAndSet(false));
|
||||
}
|
||||
catch (VMDisconnectedException ignored) {
|
||||
}
|
||||
}
|
||||
}, 100, ModalityState.NON_MODAL);
|
||||
}
|
||||
|
||||
private void doRebuild(boolean refreshOnly) {
|
||||
final DebuggerContextImpl context = getContext();
|
||||
final DebuggerSession session = context.getDebuggerSession();
|
||||
final boolean paused = session != null && session.isPaused();
|
||||
if (!paused || !refreshOnly) {
|
||||
myThreadsCombo.removeAllItems();
|
||||
synchronized (myFramesList) {
|
||||
myFramesLastUpdateTime = getNextStamp();
|
||||
myFramesList.getModel().clear();
|
||||
}
|
||||
}
|
||||
|
||||
if (paused) {
|
||||
final DebugProcessImpl process = context.getDebugProcess();
|
||||
if (process != null) {
|
||||
process.getManagerThread().schedule(new RefreshFramePanelCommand(refreshOnly && myThreadsCombo.getItemCount() != 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
Disposer.dispose(myRebuildAlarm);
|
||||
}
|
||||
finally {
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowLibraryFrames() {
|
||||
return myShowLibraryFrames;
|
||||
}
|
||||
|
||||
public void setShowLibraryFrames(boolean showLibraryFrames) {
|
||||
if (myShowLibraryFrames != showLibraryFrames) {
|
||||
myShowLibraryFrames = showLibraryFrames;
|
||||
rebuild(DebuggerSession.EVENT_CONTEXT);
|
||||
}
|
||||
}
|
||||
|
||||
private class RefreshFramePanelCommand extends DebuggerContextCommandImpl {
|
||||
private final boolean myRefreshOnly;
|
||||
private final ThreadDescriptorImpl[] myThreadDescriptorsToUpdate;
|
||||
|
||||
public RefreshFramePanelCommand(final boolean refreshOnly) {
|
||||
super(getContext());
|
||||
myRefreshOnly = refreshOnly;
|
||||
if (refreshOnly) {
|
||||
final int size = myThreadsCombo.getItemCount();
|
||||
myThreadDescriptorsToUpdate = new ThreadDescriptorImpl[size];
|
||||
for (int idx = 0; idx < size; idx++) {
|
||||
myThreadDescriptorsToUpdate[idx] = (ThreadDescriptorImpl)myThreadsCombo.getItemAt(idx);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myThreadDescriptorsToUpdate = null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<ThreadDescriptorImpl> createThreadDescriptorsList() {
|
||||
final List<ThreadReferenceProxyImpl> threads = new ArrayList<ThreadReferenceProxyImpl>(getSuspendContext().getDebugProcess().getVirtualMachineProxy().allThreads());
|
||||
Collections.sort(threads, ThreadReferenceProxyImpl.ourComparator);
|
||||
|
||||
final List<ThreadDescriptorImpl> descriptors = new ArrayList<ThreadDescriptorImpl>(threads.size());
|
||||
EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext();
|
||||
|
||||
for (ThreadReferenceProxyImpl thread : threads) {
|
||||
ThreadDescriptorImpl threadDescriptor = new ThreadDescriptorImpl(thread);
|
||||
threadDescriptor.setContext(evaluationContext);
|
||||
threadDescriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
descriptors.add(threadDescriptor);
|
||||
}
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void threadAction() {
|
||||
if (myRefreshOnly && myThreadDescriptorsToUpdate.length != myThreadsCombo.getItemCount()) {
|
||||
// there is no sense in refreshing combobox if thread list has changed since creation of this command
|
||||
return;
|
||||
}
|
||||
|
||||
final DebuggerContextImpl context = getDebuggerContext();
|
||||
|
||||
final ThreadReferenceProxyImpl threadToSelect = context.getThreadProxy();
|
||||
if(threadToSelect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(context.getSuspendContext(), threadToSelect);
|
||||
final ThreadDescriptorImpl currentThreadDescriptor = (ThreadDescriptorImpl)myThreadsCombo.getSelectedItem();
|
||||
final ThreadReferenceProxyImpl currentThread = currentThreadDescriptor != null? currentThreadDescriptor.getThreadReference() : null;
|
||||
|
||||
if (myRefreshOnly && threadToSelect.equals(currentThread)) {
|
||||
context.getDebugProcess().getManagerThread().schedule(new UpdateFramesListCommand(context, threadContext));
|
||||
}
|
||||
else {
|
||||
context.getDebugProcess().getManagerThread().schedule(new RebuildFramesListCommand(context, threadContext));
|
||||
}
|
||||
|
||||
if (myRefreshOnly) {
|
||||
final EvaluationContextImpl evaluationContext = context.createEvaluationContext();
|
||||
for (ThreadDescriptorImpl descriptor : myThreadDescriptorsToUpdate) {
|
||||
descriptor.setContext(evaluationContext);
|
||||
descriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
}
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myThreadsListener.setEnabled(false);
|
||||
selectThread(threadToSelect);
|
||||
myFramesList.repaint();
|
||||
}
|
||||
finally {
|
||||
myThreadsListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
else { // full rebuild
|
||||
refillThreadsCombo(threadToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void commandCancelled() {
|
||||
if (!DebuggerManagerThreadImpl.isManagerThread()) {
|
||||
return;
|
||||
}
|
||||
// context thread is not suspended
|
||||
final DebuggerContextImpl context = getDebuggerContext();
|
||||
|
||||
final SuspendContextImpl suspendContext = context.getSuspendContext();
|
||||
if (suspendContext == null) {
|
||||
return;
|
||||
}
|
||||
final ThreadReferenceProxyImpl threadToSelect = context.getThreadProxy();
|
||||
if(threadToSelect == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!suspendContext.isResumed()) {
|
||||
final SuspendContextImpl threadContext = SuspendManagerUtil.getSuspendContextForThread(suspendContext, threadToSelect);
|
||||
context.getDebugProcess().getManagerThread().schedule(new RebuildFramesListCommand(context, threadContext));
|
||||
refillThreadsCombo(threadToSelect);
|
||||
}
|
||||
}
|
||||
|
||||
private void refillThreadsCombo(final ThreadReferenceProxyImpl threadToSelect) {
|
||||
final List<ThreadDescriptorImpl> threadItems = createThreadDescriptorsList();
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myThreadsListener.setEnabled(false);
|
||||
|
||||
myThreadsCombo.removeAllItems();
|
||||
for (final ThreadDescriptorImpl threadItem : threadItems) {
|
||||
myThreadsCombo.addItem(threadItem);
|
||||
}
|
||||
|
||||
selectThread(threadToSelect);
|
||||
}
|
||||
finally {
|
||||
myThreadsListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class UpdateFramesListCommand extends SuspendContextCommandImpl {
|
||||
private final DebuggerContextImpl myDebuggerContext;
|
||||
|
||||
public UpdateFramesListCommand(DebuggerContextImpl debuggerContext, SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
myDebuggerContext = debuggerContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
updateFrameList(myDebuggerContext.getThreadProxy());
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
final StackFrameProxyImpl contextFrame = getDebuggerContext().getFrameProxy();
|
||||
if(contextFrame != null) {
|
||||
selectFrame(contextFrame);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void updateFrameList(ThreadReferenceProxyImpl thread) {
|
||||
try {
|
||||
if(!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ObjectCollectedException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
final EvaluationContextImpl evaluationContext = getDebuggerContext().createEvaluationContext();
|
||||
final List<StackFrameDescriptorImpl> descriptors = new ArrayList<StackFrameDescriptorImpl>();
|
||||
|
||||
synchronized (myFramesList) {
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
final int size = model.getSize();
|
||||
for (int i = 0; i < size; i++) {
|
||||
final Object elem = model.getElementAt(i);
|
||||
if (elem instanceof StackFrameDescriptorImpl) {
|
||||
descriptors.add((StackFrameDescriptorImpl)elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (StackFrameDescriptorImpl descriptor : descriptors) {
|
||||
descriptor.setContext(evaluationContext);
|
||||
descriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
public DebuggerContextImpl getDebuggerContext() {
|
||||
return myDebuggerContext;
|
||||
}
|
||||
}
|
||||
|
||||
private class RebuildFramesListCommand extends SuspendContextCommandImpl {
|
||||
private final DebuggerContextImpl myDebuggerContext;
|
||||
|
||||
public RebuildFramesListCommand(DebuggerContextImpl debuggerContext, SuspendContextImpl suspendContext) {
|
||||
super(suspendContext);
|
||||
myDebuggerContext = debuggerContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
final ThreadReferenceProxyImpl thread = myDebuggerContext.getThreadProxy();
|
||||
try {
|
||||
if(!getSuspendContext().getDebugProcess().getSuspendManager().isSuspended(thread)) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(getProject(), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
synchronized (myFramesList) {
|
||||
myFramesLastUpdateTime = getNextStamp();
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
model.clear();
|
||||
model.addElement(new Object() {
|
||||
public String toString() {
|
||||
return DebuggerBundle.message("frame.panel.frames.not.available");
|
||||
}
|
||||
});
|
||||
myFramesList.setSelectedIndex(0);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
catch (ObjectCollectedException ignored) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<StackFrameProxyImpl> frames;
|
||||
try {
|
||||
frames = thread.frames();
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
frames = Collections.emptyList();
|
||||
}
|
||||
|
||||
final StackFrameProxyImpl contextFrame = myDebuggerContext.getFrameProxy();
|
||||
final EvaluationContextImpl evaluationContext = myDebuggerContext.createEvaluationContext();
|
||||
final DebuggerManagerThreadImpl managerThread = myDebuggerContext.getDebugProcess().getManagerThread();
|
||||
final MethodsTracker tracker = new MethodsTracker();
|
||||
final int totalFramesCount = frames.size();
|
||||
int index = 0;
|
||||
final IndexCounter indexCounter = new IndexCounter(totalFramesCount);
|
||||
final long timestamp = getNextStamp();
|
||||
for (StackFrameProxyImpl stackFrameProxy : frames) {
|
||||
managerThread.schedule(
|
||||
new AppendFrameCommand(
|
||||
getSuspendContext(),
|
||||
stackFrameProxy,
|
||||
evaluationContext,
|
||||
tracker,
|
||||
index++,
|
||||
stackFrameProxy.equals(contextFrame),
|
||||
timestamp,
|
||||
indexCounter
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void selectThread(ThreadReferenceProxyImpl toSelect) {
|
||||
int count = myThreadsCombo.getItemCount();
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
ThreadDescriptorImpl item = (ThreadDescriptorImpl)myThreadsCombo.getItemAt(idx);
|
||||
if (toSelect.equals(item.getThreadReference())) {
|
||||
if (!item.equals(myThreadsCombo.getSelectedItem())) {
|
||||
myThreadsCombo.setSelectedIndex(idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*invoked in swing thread*/
|
||||
private void selectFrame(StackFrameProxy frame) {
|
||||
synchronized (myFramesList) {
|
||||
final int count = myFramesList.getElementCount();
|
||||
final Object selectedValue = myFramesList.getSelectedValue();
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
final Object elem = model.getElementAt(idx);
|
||||
if (elem instanceof StackFrameDescriptorImpl) {
|
||||
final StackFrameDescriptorImpl item = (StackFrameDescriptorImpl)elem;
|
||||
if (frame.equals(item.getFrameProxy())) {
|
||||
if (!item.equals(selectedValue)) {
|
||||
myFramesList.setSelectedIndex(idx);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class IndexCounter {
|
||||
private final int[] myData;
|
||||
|
||||
private IndexCounter(int totalSize) {
|
||||
myData = new int[totalSize];
|
||||
for (int idx = 0; idx < totalSize; idx++) {
|
||||
myData[idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void markCalculated(int idx){
|
||||
myData[idx] = 1;
|
||||
}
|
||||
|
||||
public int getActualIndex(final int index) {
|
||||
int result = 0;
|
||||
for (int idx = 0; idx < index; idx++) {
|
||||
result += myData[idx];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private final AtomicLong myTimeCounter = new AtomicLong(0L);
|
||||
private long getNextStamp() {
|
||||
return myTimeCounter.incrementAndGet();
|
||||
}
|
||||
|
||||
private long myFramesLastUpdateTime = 0L;
|
||||
|
||||
private class AppendFrameCommand extends SuspendContextCommandImpl {
|
||||
private final StackFrameProxyImpl myFrame;
|
||||
private final EvaluationContextImpl myEvaluationContext;
|
||||
private final MethodsTracker myTracker;
|
||||
private final int myIndexToInsert;
|
||||
private final boolean myIsContextFrame;
|
||||
private final long myTimestamp;
|
||||
private final IndexCounter myCounter;
|
||||
|
||||
public AppendFrameCommand(@NotNull SuspendContextImpl suspendContext, @NotNull StackFrameProxyImpl frame, EvaluationContextImpl evaluationContext,
|
||||
MethodsTracker tracker, int indexToInsert, final boolean isContextFrame, final long timestamp, IndexCounter counter) {
|
||||
super(suspendContext);
|
||||
myFrame = frame;
|
||||
myEvaluationContext = evaluationContext;
|
||||
myTracker = tracker;
|
||||
myIndexToInsert = indexToInsert;
|
||||
myIsContextFrame = isContextFrame;
|
||||
myTimestamp = timestamp;
|
||||
myCounter = counter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextAction() throws Exception {
|
||||
final StackFrameDescriptorImpl descriptor = new StackFrameDescriptorImpl(myFrame, myTracker);
|
||||
descriptor.setContext(myEvaluationContext);
|
||||
descriptor.updateRepresentation(myEvaluationContext, DescriptorLabelListener.DUMMY_LISTENER);
|
||||
final Project project = getProject();
|
||||
DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
myFramesListener.setEnabled(false);
|
||||
synchronized (myFramesList) {
|
||||
final DefaultListModel model = myFramesList.getModel();
|
||||
if (myFramesLastUpdateTime < myTimestamp) {
|
||||
myFramesLastUpdateTime = myTimestamp;
|
||||
model.clear();
|
||||
}
|
||||
if (myTimestamp != myFramesLastUpdateTime) {
|
||||
return; // the command has expired
|
||||
}
|
||||
final boolean shouldHide = !myShowLibraryFrames && !myIsContextFrame && myIndexToInsert != 0 && (descriptor.isSynthetic() || descriptor.isInLibraryContent());
|
||||
if (!shouldHide) {
|
||||
myCounter.markCalculated(myIndexToInsert);
|
||||
final int actualIndex = myCounter.getActualIndex(myIndexToInsert);
|
||||
model.insertElementAt(descriptor, actualIndex);
|
||||
if (myIsContextFrame) {
|
||||
myFramesList.setSelectedIndex(actualIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally {
|
||||
myFramesListener.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void requestFocus() {
|
||||
myFramesList.requestFocus();
|
||||
}
|
||||
|
||||
public OccurenceNavigator getOccurenceNavigator() {
|
||||
return myFramesList;
|
||||
}
|
||||
|
||||
public FramesList getFramesList() {
|
||||
return myFramesList;
|
||||
}
|
||||
|
||||
private class ShowLibraryFramesAction extends ToggleAction {
|
||||
private volatile boolean myShouldShow;
|
||||
private static final String ourTextWhenShowIsOn = "Hide Frames from Libraries";
|
||||
private static final String ourTextWhenShowIsOff = "Show All Frames";
|
||||
|
||||
public ShowLibraryFramesAction() {
|
||||
super("", "", FILTER_STACK_FRAMES_ICON);
|
||||
myShouldShow = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull final AnActionEvent e) {
|
||||
super.update(e);
|
||||
final Presentation presentation = e.getPresentation();
|
||||
final boolean shouldShow = !Boolean.TRUE.equals(presentation.getClientProperty(SELECTED_PROPERTY));
|
||||
presentation.setText(shouldShow ? ourTextWhenShowIsOn : ourTextWhenShowIsOff);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return !myShouldShow;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean enabled) {
|
||||
myShouldShow = !enabled;
|
||||
DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES = myShouldShow;
|
||||
setShowLibraryFrames(myShouldShow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -50,20 +50,8 @@ import java.util.Collection;
|
||||
*/
|
||||
public class JavaDebuggerSupport extends DebuggerSupport {
|
||||
private final JavaBreakpointPanelProvider myBreakpointPanelProvider = new JavaBreakpointPanelProvider();
|
||||
//private final StepOverActionHandler myStepOverActionHandler = new StepOverActionHandler();
|
||||
//private final StepIntoActionHandler myStepIntoActionHandler = new StepIntoActionHandler();
|
||||
//private final StepOutActionHandler myStepOutActionHandler = new StepOutActionHandler();
|
||||
//private final ForceStepOverActionHandler myForceStepOverActionHandler = new ForceStepOverActionHandler();
|
||||
//private final ForceStepIntoActionHandler myForceStepIntoActionHandler = new ForceStepIntoActionHandler();
|
||||
//private final RunToCursorActionHandler myRunToCursorActionHandler = new RunToCursorActionHandler();
|
||||
//private final ForceRunToCursorActionHandler myForceRunToCursorActionHandler = new ForceRunToCursorActionHandler();
|
||||
//private final ResumeActionHandler myResumeActionHandler = new ResumeActionHandler();
|
||||
//private final PauseActionHandler myPauseActionHandler = new PauseActionHandler();
|
||||
//private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler();
|
||||
//private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler();
|
||||
//private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler();
|
||||
private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler();
|
||||
//private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
|
||||
private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,459 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.DebuggerInvocationUtil;
|
||||
import com.intellij.debugger.DebuggerManagerEx;
|
||||
import com.intellij.debugger.SourcePosition;
|
||||
import com.intellij.debugger.engine.DebugProcessEvents;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.evaluation.EvaluateException;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
import com.intellij.debugger.impl.*;
|
||||
import com.intellij.debugger.jdi.StackFrameProxyImpl;
|
||||
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
|
||||
import com.intellij.debugger.ui.breakpoints.*;
|
||||
import com.intellij.openapi.actionSystem.ActionGroup;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.impl.EditorImpl;
|
||||
import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.event.Event;
|
||||
import com.sun.jdi.event.LocatableEvent;
|
||||
import com.sun.jdi.event.MethodEntryEvent;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: lex
|
||||
* Date: Jul 9, 2003
|
||||
* Time: 6:24:35 PM
|
||||
* To change this template use Options | File Templates.
|
||||
*/
|
||||
public class PositionHighlighter {
|
||||
private static final Key<Boolean> HIGHLIGHTER_USERDATA_KEY = new Key<Boolean>("HIGHLIGHTER_USERDATA_KEY");
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.PositionHighlighter");
|
||||
private final Project myProject;
|
||||
private DebuggerContextImpl myContext = DebuggerContextImpl.EMPTY_CONTEXT;
|
||||
private SelectionDescription mySelectionDescription = null;
|
||||
private ExecutionPointDescription myExecutionPointDescription = null;
|
||||
|
||||
public PositionHighlighter(Project project, DebuggerStateManager stateManager) {
|
||||
myProject = project;
|
||||
|
||||
stateManager.addListener(new DebuggerContextListener() {
|
||||
public void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
myContext = newContext;
|
||||
if (event != DebuggerSession.EVENT_REFRESH_VIEWS_ONLY && event != DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void showLocationInEditor() {
|
||||
myContext.getDebugProcess().getManagerThread().schedule(new ShowLocationCommand(myContext));
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
clearSelections();
|
||||
final DebuggerSession session = myContext.getDebuggerSession();
|
||||
if(session != null) {
|
||||
switch(session.getState()) {
|
||||
case DebuggerSession.STATE_PAUSED:
|
||||
if(myContext.getFrameProxy() != null) {
|
||||
showLocationInEditor();
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class ExecutionPointDescription extends SelectionDescription {
|
||||
private RangeHighlighter myHighlighter;
|
||||
private final int myLineIndex;
|
||||
|
||||
protected ExecutionPointDescription(Editor editor, int lineIndex) {
|
||||
super(editor);
|
||||
myLineIndex = lineIndex;
|
||||
}
|
||||
|
||||
public void select() {
|
||||
if(myIsActive) return;
|
||||
myIsActive = true;
|
||||
EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
myHighlighter = myEditor.getMarkupModel().addLineHighlighter(
|
||||
myLineIndex,
|
||||
DebuggerColors.EXECUTION_LINE_HIGHLIGHTERLAYER,
|
||||
scheme.getAttributes(DebuggerColors.EXECUTIONPOINT_ATTRIBUTES)
|
||||
);
|
||||
adjustCounter(myEditor, 1);
|
||||
myHighlighter.setErrorStripeTooltip(DebuggerBundle.message("position.highlighter.stripe.tooltip"));
|
||||
myHighlighter.putUserData(HIGHLIGHTER_USERDATA_KEY, Boolean.TRUE);
|
||||
}
|
||||
|
||||
private static void adjustCounter(@NotNull Editor editor, int increment) {
|
||||
JComponent component = editor.getComponent();
|
||||
Object o = component.getClientProperty(EditorImpl.IGNORE_MOUSE_TRACKING);
|
||||
Integer value = ((o instanceof Integer) ? (Integer)o : 0) + increment;
|
||||
component.putClientProperty(EditorImpl.IGNORE_MOUSE_TRACKING, value > 0 ? value : null);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if(!myIsActive) return;
|
||||
myIsActive = false;
|
||||
adjustCounter(myEditor, -1);
|
||||
if (myHighlighter != null) {
|
||||
myHighlighter.dispose();
|
||||
myHighlighter = null;
|
||||
}
|
||||
}
|
||||
|
||||
public RangeHighlighter getHighlighter() {
|
||||
return myHighlighter;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract static class SelectionDescription {
|
||||
protected Editor myEditor;
|
||||
protected boolean myIsActive;
|
||||
|
||||
public SelectionDescription(Editor editor) {
|
||||
myEditor = editor;
|
||||
}
|
||||
|
||||
public abstract void select();
|
||||
public abstract void remove();
|
||||
|
||||
public static ExecutionPointDescription createExecutionPoint(final Editor editor,
|
||||
final int lineIndex) {
|
||||
return new ExecutionPointDescription(editor, lineIndex);
|
||||
}
|
||||
|
||||
public static SelectionDescription createSelection(final Editor editor, final int lineIndex) {
|
||||
return new SelectionDescription(editor) {
|
||||
public void select() {
|
||||
if(myIsActive) return;
|
||||
myIsActive = true;
|
||||
DocumentEx doc = (DocumentEx)editor.getDocument();
|
||||
editor.getSelectionModel().setSelection(
|
||||
doc.getLineStartOffset(lineIndex),
|
||||
doc.getLineEndOffset(lineIndex) + doc.getLineSeparatorLength(lineIndex)
|
||||
);
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
if(!myIsActive) return;
|
||||
myIsActive = false;
|
||||
myEditor.getSelectionModel().removeSelection();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private void showSelection(SourcePosition position) {
|
||||
Editor editor = getEditor(position);
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
if (mySelectionDescription != null) {
|
||||
mySelectionDescription.remove();
|
||||
}
|
||||
mySelectionDescription = SelectionDescription.createSelection(editor, position.getLine());
|
||||
mySelectionDescription.select();
|
||||
}
|
||||
|
||||
private void showExecutionPoint(final SourcePosition position, List<Pair<Breakpoint, Event>> events) {
|
||||
if (myExecutionPointDescription != null) {
|
||||
myExecutionPointDescription.remove();
|
||||
}
|
||||
int lineIndex = position.getLine();
|
||||
Editor editor = getEditor(position);
|
||||
if(editor == null) {
|
||||
return;
|
||||
}
|
||||
myExecutionPointDescription = SelectionDescription.createExecutionPoint(editor, lineIndex);
|
||||
myExecutionPointDescription.select();
|
||||
|
||||
RangeHighlighter highlighter = myExecutionPointDescription.getHighlighter();
|
||||
|
||||
if(highlighter != null) {
|
||||
final List<Pair<Breakpoint, Event>> eventsOutOfLine = new ArrayList<Pair<Breakpoint, Event>>();
|
||||
|
||||
for (final Pair<Breakpoint, Event> eventDescriptor : events) {
|
||||
final Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
// filter breakpoints that do not match the event
|
||||
if (breakpoint instanceof MethodBreakpoint) {
|
||||
try {
|
||||
if (!((MethodBreakpoint)breakpoint).matchesEvent((LocatableEvent)eventDescriptor.getSecond(), myContext.getDebugProcess())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
}
|
||||
else if (breakpoint instanceof WildcardMethodBreakpoint) {
|
||||
if (!((WildcardMethodBreakpoint)breakpoint).matchesEvent((LocatableEvent)eventDescriptor.getSecond())) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (breakpoint instanceof BreakpointWithHighlighter) {
|
||||
if (((BreakpointWithHighlighter)breakpoint).isVisible() && breakpoint.isValid()) {
|
||||
breakpoint.reload();
|
||||
int bptLine = ((BreakpointWithHighlighter)breakpoint).getLineIndex();
|
||||
if (bptLine < 0 || bptLine != lineIndex) {
|
||||
eventsOutOfLine.add(eventDescriptor);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
eventsOutOfLine.add(eventDescriptor);
|
||||
}
|
||||
}
|
||||
|
||||
if(!eventsOutOfLine.isEmpty()) {
|
||||
highlighter.setGutterIconRenderer(new MyGutterIconRenderer(eventsOutOfLine));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Editor getEditor(SourcePosition position) {
|
||||
final PsiFile psiFile = position.getFile();
|
||||
Document doc = PsiDocumentManager.getInstance(myProject).getDocument(psiFile);
|
||||
if (!psiFile.isValid()) {
|
||||
return null;
|
||||
}
|
||||
final int lineIndex = position.getLine();
|
||||
if (lineIndex < 0 || lineIndex > doc.getLineCount()) {
|
||||
//LOG.assertTrue(false, "Incorrect lineIndex " + lineIndex + " in file " + psiFile.getName());
|
||||
return null;
|
||||
}
|
||||
return position.openEditor(false);
|
||||
}
|
||||
|
||||
private void clearSelections() {
|
||||
if (mySelectionDescription != null || myExecutionPointDescription != null) {
|
||||
ApplicationManager.getApplication().runReadAction(new Runnable() {
|
||||
public void run() {
|
||||
if (mySelectionDescription != null) {
|
||||
mySelectionDescription.remove();
|
||||
mySelectionDescription = null;
|
||||
}
|
||||
if (myExecutionPointDescription != null) {
|
||||
myExecutionPointDescription.remove();
|
||||
myExecutionPointDescription = null;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void updateContextPointDescription() {
|
||||
if(myContext.getDebuggerSession() == null) return;
|
||||
|
||||
showLocationInEditor();
|
||||
}
|
||||
|
||||
private class ShowLocationCommand extends DebuggerContextCommandImpl {
|
||||
private final DebuggerContextImpl myContext;
|
||||
|
||||
public ShowLocationCommand(DebuggerContextImpl context) {
|
||||
super(context);
|
||||
myContext = context;
|
||||
}
|
||||
|
||||
public void threadAction() {
|
||||
final SourcePosition contextPosition = myContext.getSourcePosition();
|
||||
if (contextPosition == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean isExecutionPoint = false;
|
||||
try {
|
||||
StackFrameProxyImpl frameProxy = myContext.getFrameProxy();
|
||||
final ThreadReferenceProxyImpl thread = getSuspendContext().getThread();
|
||||
isExecutionPoint = thread != null && frameProxy != null && frameProxy.equals(thread.frame(0));
|
||||
}
|
||||
catch(Throwable th) {
|
||||
LOG.debug(th);
|
||||
}
|
||||
|
||||
final List<Pair<Breakpoint, Event>> events = DebuggerUtilsEx.getEventDescriptors(getSuspendContext());
|
||||
|
||||
final SourcePosition position = ApplicationManager.getApplication().runReadAction(new Computable<SourcePosition>() {
|
||||
public SourcePosition compute() {
|
||||
Document document = PsiDocumentManager.getInstance(myProject).getDocument(contextPosition.getFile());
|
||||
if(document != null) {
|
||||
if(contextPosition.getLine() < 0 || contextPosition.getLine() >= document.getLineCount()) {
|
||||
return SourcePosition.createFromLine(contextPosition.getFile(), 0);
|
||||
}
|
||||
}
|
||||
return contextPosition;
|
||||
}
|
||||
});
|
||||
|
||||
if(isExecutionPoint) {
|
||||
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
final SourcePosition highlightPosition = getHighlightPosition(events, position);
|
||||
showExecutionPoint(highlightPosition, events);
|
||||
}
|
||||
});
|
||||
}
|
||||
else {
|
||||
DebuggerInvocationUtil.swingInvokeLater(myProject, new Runnable() {
|
||||
public void run() {
|
||||
showSelection(position);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private SourcePosition getHighlightPosition(final List<Pair<Breakpoint, Event>> events, SourcePosition position) {
|
||||
for (Iterator<Pair<Breakpoint, Event>> iterator = events.iterator(); iterator.hasNext();) {
|
||||
final Pair<Breakpoint, Event> eventDescriptor = iterator.next();
|
||||
final Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
if(breakpoint instanceof LineBreakpoint) {
|
||||
breakpoint.reload();
|
||||
final SourcePosition breakPosition = ((BreakpointWithHighlighter)breakpoint).getSourcePosition();
|
||||
if(breakPosition != null && breakPosition.getLine() != position.getLine()) {
|
||||
position = SourcePosition.createFromLine(position.getFile(), breakPosition.getLine());
|
||||
}
|
||||
}
|
||||
else if(breakpoint instanceof MethodBreakpoint) {
|
||||
final MethodBreakpoint methodBreakpoint = (MethodBreakpoint)breakpoint;
|
||||
methodBreakpoint.reload();
|
||||
final SourcePosition breakPosition = methodBreakpoint.getSourcePosition();
|
||||
final LocatableEvent event = (LocatableEvent)eventDescriptor.getSecond();
|
||||
if(breakPosition != null && breakPosition.getFile().equals(position.getFile()) && breakPosition.getLine() != position.getLine() && event instanceof MethodEntryEvent) {
|
||||
try {
|
||||
if (methodBreakpoint.matchesEvent(event, myContext.getDebugProcess())) {
|
||||
position = SourcePosition.createFromLine(position.getFile(), breakPosition.getLine());
|
||||
}
|
||||
}
|
||||
catch (EvaluateException ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return position;
|
||||
}
|
||||
}
|
||||
|
||||
private class MyGutterIconRenderer extends GutterIconRenderer {
|
||||
private final List<Pair<Breakpoint, Event>> myEventsOutOfLine;
|
||||
|
||||
public MyGutterIconRenderer(List<Pair<Breakpoint, Event>> eventsOutOfLine) {
|
||||
myEventsOutOfLine = eventsOutOfLine;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Icon getIcon() {
|
||||
return myEventsOutOfLine.get(0).getFirst().getIcon();
|
||||
}
|
||||
|
||||
public String getTooltipText() {
|
||||
DebugProcessImpl debugProcess = myContext.getDebugProcess();
|
||||
if (debugProcess == null) {
|
||||
return null;
|
||||
}
|
||||
final StringBuilder buf = StringBuilderSpinAllocator.alloc();
|
||||
try {
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("<html><body>");
|
||||
for (Iterator<Pair<Breakpoint, Event>> iterator = myEventsOutOfLine.iterator(); iterator.hasNext();) {
|
||||
Pair<Breakpoint, Event> eventDescriptor = iterator.next();
|
||||
buf.append(((DebugProcessEvents)debugProcess).getEventText(eventDescriptor));
|
||||
if(iterator.hasNext()) {
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("<br>");
|
||||
}
|
||||
}
|
||||
//noinspection HardCodedStringLiteral
|
||||
buf.append("</body></html>");
|
||||
return buf.toString();
|
||||
}
|
||||
finally {
|
||||
StringBuilderSpinAllocator.dispose(buf);
|
||||
}
|
||||
}
|
||||
|
||||
public ActionGroup getPopupMenuActions() {
|
||||
DefaultActionGroup group = new DefaultActionGroup();
|
||||
for (Pair<Breakpoint, Event> eventDescriptor : myEventsOutOfLine) {
|
||||
Breakpoint breakpoint = eventDescriptor.getFirst();
|
||||
AnAction viewBreakpointsAction = new ViewBreakpointsAction(breakpoint.getDisplayName(), breakpoint.getXBreakpoint());
|
||||
group.add(viewBreakpointsAction);
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnAction getMiddleButtonClickAction() {
|
||||
return new AnAction() {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (myEventsOutOfLine.size() == 1) {
|
||||
Breakpoint breakpoint = myEventsOutOfLine.get(0).getFirst();
|
||||
breakpoint.setEnabled(!breakpoint.isEnabled());
|
||||
DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().fireBreakpointChanged(breakpoint);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return obj instanceof MyGutterIconRenderer &&
|
||||
Comparing.equal(getTooltipText(), ((MyGutterIconRenderer)obj).getTooltipText()) &&
|
||||
Comparing.equal(getIcon(), ((MyGutterIconRenderer)obj).getIcon());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return getIcon().hashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.util.WeakListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseListener;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 25, 2004
|
||||
*/
|
||||
public class WeakMouseListener extends WeakListener<JComponent, MouseListener> {
|
||||
public WeakMouseListener(JComponent source, MouseListener listenerImpl) {
|
||||
super(source, MouseListener.class, listenerImpl);
|
||||
}
|
||||
public void addListener(JComponent source, MouseListener listener) {
|
||||
source.addMouseListener(listener);
|
||||
}
|
||||
public void removeListener(JComponent source, MouseListener listener) {
|
||||
source.removeMouseListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui;
|
||||
|
||||
import com.intellij.util.WeakListener;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.MouseMotionListener;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 25, 2004
|
||||
*/
|
||||
public class WeakMouseMotionListener extends WeakListener<JComponent, MouseMotionListener> {
|
||||
public WeakMouseMotionListener(JComponent source, MouseMotionListener listenerImpl) {
|
||||
super(source, MouseMotionListener.class, listenerImpl);
|
||||
}
|
||||
public void addListener(JComponent source, MouseMotionListener listener) {
|
||||
source.addMouseMotionListener(listener);
|
||||
}
|
||||
public void removeListener(JComponent source, MouseMotionListener listener) {
|
||||
source.removeMouseMotionListener(listener);
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl;
|
||||
import com.intellij.ui.ListCellRendererWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class DebuggerComboBoxRenderer extends ListCellRendererWrapper {
|
||||
public DebuggerComboBoxRenderer(final ListCellRenderer listCellRenderer) {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void customize(JList list, Object value, int index, boolean selected, boolean hasFocus) {
|
||||
if (list.getComponentCount() > 0) {
|
||||
Icon icon = getIcon(value);
|
||||
if (icon != null) {
|
||||
setIcon(icon);
|
||||
}
|
||||
}
|
||||
else {
|
||||
setIcon(null);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Icon getIcon(Object item) {
|
||||
if (item instanceof ThreadDescriptorImpl) {
|
||||
return ((ThreadDescriptorImpl)item).getIcon();
|
||||
}
|
||||
if (item instanceof StackFrameDescriptorImpl) {
|
||||
return ((StackFrameDescriptorImpl)item).getIcon();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.xdebugger.impl.frame.DebuggerFramesList;
|
||||
import com.sun.jdi.Method;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Dec 7, 2006
|
||||
*/
|
||||
public class FramesList extends DebuggerFramesList {
|
||||
private volatile Method mySelectedMethod = null;
|
||||
|
||||
public FramesList(Project project) {
|
||||
super(project);
|
||||
doInit();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FramesListRenderer createListRenderer() {
|
||||
return new FramesListRenderer();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFrameChanged(final Object selectedValue) {
|
||||
final StackFrameDescriptorImpl descriptor = selectedValue instanceof StackFrameDescriptorImpl? (StackFrameDescriptorImpl)selectedValue : null;
|
||||
final Method newMethod = descriptor != null? descriptor.getMethod() : null;
|
||||
if (!Comparing.equal(mySelectedMethod, newMethod)) {
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
repaint();
|
||||
}
|
||||
});
|
||||
}
|
||||
mySelectedMethod = newMethod;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsScheme;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.ui.ColoredListCellRenderer;
|
||||
import com.intellij.ui.JBColor;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.ui.DebuggerColors;
|
||||
import com.sun.jdi.Method;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.MatteBorder;
|
||||
import java.awt.*;
|
||||
|
||||
class FramesListRenderer extends ColoredListCellRenderer {
|
||||
private final EditorColorsScheme myColorScheme;
|
||||
|
||||
public FramesListRenderer() {
|
||||
myColorScheme = EditorColorsManager.getInstance().getGlobalScheme();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void customizeCellRenderer(final JList list, final Object item, final int index, final boolean selected, final boolean hasFocus) {
|
||||
if (!(item instanceof StackFrameDescriptorImpl)) {
|
||||
append(item.toString(), SimpleTextAttributes.GRAYED_ATTRIBUTES);
|
||||
}
|
||||
else {
|
||||
final StackFrameDescriptorImpl descriptor = (StackFrameDescriptorImpl)item;
|
||||
setIcon(descriptor.getIcon());
|
||||
final Object selectedValue = list.getSelectedValue();
|
||||
final boolean shouldHighlightAsRecursive = (selectedValue instanceof StackFrameDescriptorImpl) &&
|
||||
isOccurrenceOfSelectedFrame((StackFrameDescriptorImpl)selectedValue, descriptor);
|
||||
|
||||
final ValueMarkup markup = descriptor.getValueMarkup();
|
||||
if (markup != null) {
|
||||
append("["+ markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor()));
|
||||
}
|
||||
|
||||
boolean needSeparator = false;
|
||||
if (index > 0) {
|
||||
final int currentFrameIndex = descriptor.getUiIndex();
|
||||
final Object elementAt = list.getModel().getElementAt(index - 1);
|
||||
if (elementAt instanceof StackFrameDescriptorImpl) {
|
||||
StackFrameDescriptorImpl previousDescriptor = (StackFrameDescriptorImpl)elementAt;
|
||||
final int previousFrameIndex = previousDescriptor.getUiIndex();
|
||||
needSeparator = (currentFrameIndex - previousFrameIndex != 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
setBackground(UIUtil.getListSelectionBackground());
|
||||
}
|
||||
else {
|
||||
Color bg = descriptor.getBackgroundColor();
|
||||
if (bg == null) bg = UIUtil.getListBackground();
|
||||
if (shouldHighlightAsRecursive) bg = myColorScheme.getColor(DebuggerColors.RECURSIVE_CALL_ATTRIBUTES);
|
||||
setBackground(bg);
|
||||
}
|
||||
|
||||
if (needSeparator) {
|
||||
final MatteBorder border = BorderFactory.createMatteBorder(1, 0, 0, 0, JBColor.GRAY);
|
||||
setBorder(border);
|
||||
}
|
||||
else {
|
||||
setBorder(null);
|
||||
}
|
||||
|
||||
final String label = descriptor.getLabel();
|
||||
final int openingBrace = label.indexOf("{");
|
||||
final int closingBrace = (openingBrace < 0) ? -1 : label.indexOf("}");
|
||||
final SimpleTextAttributes attributes = getAttributes(descriptor);
|
||||
if (openingBrace < 0 || closingBrace < 0) {
|
||||
append(label, attributes);
|
||||
}
|
||||
else {
|
||||
append(label.substring(0, openingBrace - 1), attributes);
|
||||
append(" (" + label.substring(openingBrace + 1, closingBrace) + ")", SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES);
|
||||
|
||||
append(label.substring(closingBrace + 1, label.length()), attributes);
|
||||
if (shouldHighlightAsRecursive && descriptor.isRecursiveCall()) {
|
||||
append(" [" + descriptor.getOccurrenceIndex() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOccurrenceOfSelectedFrame(final StackFrameDescriptorImpl selectedDescriptor, StackFrameDescriptorImpl descriptor) {
|
||||
final Method currentMethod = descriptor.getMethod();
|
||||
if (currentMethod != null) {
|
||||
if (selectedDescriptor != null) {
|
||||
final Method selectedMethod = selectedDescriptor.getMethod();
|
||||
if (selectedMethod != null) {
|
||||
if (Comparing.equal(selectedMethod, currentMethod)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static SimpleTextAttributes getAttributes(final StackFrameDescriptorImpl descriptor) {
|
||||
if (descriptor.isSynthetic() || descriptor.isInLibraryContent()) {
|
||||
return SimpleTextAttributes.GRAYED_ATTRIBUTES;
|
||||
}
|
||||
return SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES;
|
||||
}
|
||||
}
|
||||
@@ -1,321 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* created at Dec 17, 2001
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.actions.AddToWatchActionHandler;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.engine.evaluation.CodeFragmentKind;
|
||||
import com.intellij.debugger.engine.evaluation.DefaultCodeFragmentFactory;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImports;
|
||||
import com.intellij.debugger.engine.evaluation.TextWithImportsImpl;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.impl.PositionUtil;
|
||||
import com.intellij.debugger.ui.DebuggerExpressionComboBox;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeInplaceEditor;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.dnd.DnDEvent;
|
||||
import com.intellij.ide.dnd.DnDManager;
|
||||
import com.intellij.ide.dnd.DnDNativeTarget;
|
||||
import com.intellij.ide.dnd.DropActionHandler;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.EmptyRunnable;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.ui.*;
|
||||
import com.intellij.ui.border.CustomLineBorder;
|
||||
import com.intellij.util.Alarm;
|
||||
import com.intellij.util.ui.UIUtil;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.TreeSelectionEvent;
|
||||
import javax.swing.event.TreeSelectionListener;
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class MainWatchPanel extends WatchPanel implements DataProvider {
|
||||
|
||||
public MainWatchPanel(Project project, DebuggerStateManager stateManager) {
|
||||
super(project,stateManager);
|
||||
final WatchDebuggerTree watchTree = getWatchTree();
|
||||
|
||||
final AnAction removeWatchesAction = ActionManager.getInstance().getAction(DebuggerActions.REMOVE_WATCH);
|
||||
removeWatchesAction.registerCustomShortcutSet(CommonShortcuts.getDelete(), watchTree);
|
||||
|
||||
final AnAction newWatchAction = ActionManager.getInstance().getAction(DebuggerActions.NEW_WATCH);
|
||||
newWatchAction.registerCustomShortcutSet(CommonShortcuts.INSERT, watchTree);
|
||||
|
||||
final Alarm quitePeriod = new Alarm();
|
||||
final Alarm editAlarm = new Alarm();
|
||||
final ClickListener mouseListener = new ClickListener() {
|
||||
@Override
|
||||
public boolean onClick(@NotNull MouseEvent event, int clickCount) {
|
||||
if (!SwingUtilities.isLeftMouseButton(event) ||
|
||||
((event.getModifiers() & (InputEvent.SHIFT_MASK | InputEvent.ALT_MASK | InputEvent.CTRL_MASK | InputEvent.META_MASK)) !=0) ) {
|
||||
return false;
|
||||
}
|
||||
boolean sameRow = isAboveSelectedItem(event, watchTree);
|
||||
final AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH);
|
||||
Presentation presentation = editWatchAction.getTemplatePresentation().clone();
|
||||
DataContext context = DataManager.getInstance().getDataContext(watchTree);
|
||||
final AnActionEvent actionEvent = new AnActionEvent(null, context, "WATCH_TREE", presentation, ActionManager.getInstance(), 0);
|
||||
Runnable runnable = new Runnable() {
|
||||
public void run() {
|
||||
editWatchAction.actionPerformed(actionEvent);
|
||||
}
|
||||
};
|
||||
if (sameRow && editAlarm.isEmpty() && quitePeriod.isEmpty()) {
|
||||
editAlarm.addRequest(runnable, UIUtil.getMultiClickInterval());
|
||||
} else {
|
||||
editAlarm.cancelAllRequests();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
final ClickListener mouseEmptySpaceListener = new DoubleClickListener() {
|
||||
@Override
|
||||
protected boolean onDoubleClick(MouseEvent event) {
|
||||
if (!isAboveSelectedItem(event, watchTree)) {
|
||||
newWatch();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
ListenerUtil.addClickListener(watchTree, mouseListener);
|
||||
ListenerUtil.addClickListener(watchTree, mouseEmptySpaceListener);
|
||||
|
||||
final FocusListener focusListener = new FocusListener() {
|
||||
@Override
|
||||
public void focusGained(FocusEvent e) {
|
||||
quitePeriod.addRequest(EmptyRunnable.getInstance(), UIUtil.getMultiClickInterval());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusLost(FocusEvent e) {
|
||||
editAlarm.cancelAllRequests();
|
||||
}
|
||||
};
|
||||
ListenerUtil.addFocusListener(watchTree, focusListener);
|
||||
|
||||
final TreeSelectionListener selectionListener = new TreeSelectionListener() {
|
||||
@Override
|
||||
public void valueChanged(TreeSelectionEvent e) {
|
||||
quitePeriod.addRequest(EmptyRunnable.getInstance(), UIUtil.getMultiClickInterval());
|
||||
}
|
||||
};
|
||||
watchTree.addTreeSelectionListener(selectionListener);
|
||||
|
||||
final AnAction editWatchAction = ActionManager.getInstance().getAction(DebuggerActions.EDIT_WATCH);
|
||||
editWatchAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), watchTree);
|
||||
registerDisposable(new Disposable() {
|
||||
public void dispose() {
|
||||
ListenerUtil.removeClickListener(watchTree, mouseListener);
|
||||
ListenerUtil.removeFocusListener(watchTree, focusListener);
|
||||
watchTree.removeTreeSelectionListener(selectionListener);
|
||||
removeWatchesAction.unregisterCustomShortcutSet(watchTree);
|
||||
newWatchAction.unregisterCustomShortcutSet(watchTree);
|
||||
editWatchAction.unregisterCustomShortcutSet(watchTree);
|
||||
}
|
||||
});
|
||||
|
||||
DnDManager.getInstance().registerTarget(new DnDNativeTarget() {
|
||||
public boolean update(final DnDEvent aEvent) {
|
||||
Object object = aEvent.getAttachedObject();
|
||||
if (object == null) return true;
|
||||
|
||||
String add = DebuggerBundle.message("watchs.add.text");
|
||||
|
||||
if (object.getClass().isArray()) {
|
||||
Class<?> type = object.getClass().getComponentType();
|
||||
if (DebuggerTreeNodeImpl.class.isAssignableFrom(type)) {
|
||||
aEvent.setHighlighting(myTree, DnDEvent.DropTargetHighlightingType.RECTANGLE | DnDEvent.DropTargetHighlightingType.TEXT);
|
||||
aEvent.setDropPossible(add, new DropActionHandler() {
|
||||
public void performDrop(final DnDEvent aEvent) {
|
||||
addWatchesFrom((DebuggerTreeNodeImpl[])aEvent.getAttachedObject());
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (object instanceof EventInfo) {
|
||||
EventInfo info = (EventInfo)object;
|
||||
final String text = info.getTextForFlavor(DataFlavor.stringFlavor);
|
||||
if (text != null) {
|
||||
aEvent.setHighlighting(myTree, DnDEvent.DropTargetHighlightingType.RECTANGLE | DnDEvent.DropTargetHighlightingType.TEXT);
|
||||
aEvent.setDropPossible(add, new DropActionHandler() {
|
||||
public void performDrop(final DnDEvent aEvent) {
|
||||
addWatchesFrom(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void drop(final DnDEvent aEvent) {
|
||||
}
|
||||
|
||||
public void cleanUpOnLeave() {
|
||||
}
|
||||
|
||||
public void updateDraggedImage(final Image image, final Point dropPoint, final Point imageOffset) {
|
||||
}
|
||||
}, myTree);
|
||||
}
|
||||
|
||||
private static boolean isAboveSelectedItem(MouseEvent event, WatchDebuggerTree watchTree) {
|
||||
Rectangle bounds = watchTree.getRowBounds(watchTree.getLeadSelectionRow());
|
||||
if (bounds != null) {
|
||||
bounds.width = watchTree.getWidth();
|
||||
if (bounds.contains(event.getPoint())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addWatchesFrom(final DebuggerTreeNodeImpl[] nodes) {
|
||||
AddToWatchActionHandler.addFromNodes(getContext(), this, nodes);
|
||||
}
|
||||
|
||||
private void addWatchesFrom(String text) {
|
||||
AddToWatchActionHandler.doAddWatch(this, new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, text), null);
|
||||
}
|
||||
|
||||
protected ActionPopupMenu createPopupMenu() {
|
||||
ActionGroup group = (ActionGroup)ActionManager.getInstance().getAction(DebuggerActions.WATCH_PANEL_POPUP);
|
||||
ActionPopupMenu popupMenu = ActionManager.getInstance().createActionPopupMenu(DebuggerActions.WATCH_PANEL_POPUP, group);
|
||||
return popupMenu;
|
||||
}
|
||||
|
||||
public void newWatch() {
|
||||
final DebuggerTreeNodeImpl node = getWatchTree().addWatch(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, ""), null);
|
||||
editNode(node);
|
||||
}
|
||||
|
||||
public void editNode(final DebuggerTreeNodeImpl node) {
|
||||
final DebuggerContextImpl context = getContext();
|
||||
final DebuggerExpressionComboBox comboBox = new DebuggerExpressionComboBox(getProject(), PositionUtil.getContextElement(context), "evaluation",
|
||||
DefaultCodeFragmentFactory.getInstance());
|
||||
comboBox.setText(((WatchItemDescriptor)node.getDescriptor()).getEvaluationText());
|
||||
comboBox.selectAll();
|
||||
|
||||
DebuggerTreeInplaceEditor editor = new DebuggerTreeInplaceEditor(node) {
|
||||
public JComponent createInplaceEditorComponent() {
|
||||
return comboBox;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return comboBox.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
public Editor getEditor() {
|
||||
return comboBox.getEditor();
|
||||
}
|
||||
|
||||
public JComponent getEditorComponent() {
|
||||
return comboBox.getEditorComponent();
|
||||
}
|
||||
|
||||
public void doOKAction() {
|
||||
if (comboBox.isPopupVisible()) {
|
||||
comboBox.selectPopupValue();
|
||||
}
|
||||
|
||||
TextWithImports text = comboBox.getText();
|
||||
if (!text.isEmpty()) {
|
||||
WatchDebuggerTree.setWatchNodeText(node, text);
|
||||
comboBox.addRecent(text);
|
||||
}
|
||||
else {
|
||||
getWatchTree().removeWatch(node);
|
||||
}
|
||||
try {
|
||||
super.doOKAction();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public void cancelEditing() {
|
||||
comboBox.setPopupVisible(false);
|
||||
if (((WatchItemDescriptor)node.getDescriptor()).getEvaluationText().isEmpty()) {
|
||||
getWatchTree().removeWatch(node);
|
||||
}
|
||||
|
||||
try {
|
||||
super.cancelEditing();
|
||||
}
|
||||
finally {
|
||||
comboBox.dispose();
|
||||
}
|
||||
}
|
||||
};
|
||||
editor.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createTreePanel(final WatchDebuggerTree tree) {
|
||||
final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(tree);
|
||||
decorator.setAddAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
executeAction(DebuggerActions.NEW_WATCH, tree);
|
||||
}
|
||||
});
|
||||
// TODO[den]: add "Add to watches action" on Mac
|
||||
if (!SystemInfo.isMac) {
|
||||
decorator.addExtraAction(AnActionButton.fromAction(ActionManager.getInstance().getAction(XDebuggerActions.ADD_TO_WATCH)));
|
||||
}
|
||||
decorator.setRemoveAction(new AnActionButtonRunnable() {
|
||||
@Override
|
||||
public void run(AnActionButton button) {
|
||||
executeAction(DebuggerActions.REMOVE_WATCH, tree);
|
||||
}
|
||||
});
|
||||
CustomLineBorder border = new CustomLineBorder(CaptionPanel.CNT_ACTIVE_BORDER_COLOR,
|
||||
SystemInfo.isMac ? 1 : 0, 0,
|
||||
SystemInfo.isMac ? 0 : 1, 0);
|
||||
decorator.setToolbarBorder(border);
|
||||
final JPanel panel = decorator.createPanel();
|
||||
panel.setBorder(null);
|
||||
return panel;
|
||||
}
|
||||
|
||||
private static void executeAction(final String watch, final WatchDebuggerTree tree) {
|
||||
AnAction action = ActionManager.getInstance().getAction(watch);
|
||||
Presentation presentation = action.getTemplatePresentation().clone();
|
||||
DataContext context = DataManager.getInstance().getDataContext(tree);
|
||||
|
||||
AnActionEvent actionEvent =
|
||||
new AnActionEvent(null, context, ActionPlaces.DEBUGGER_TOOLBAR, presentation, ActionManager.getInstance(), 0);
|
||||
action.actionPerformed(actionEvent);
|
||||
}
|
||||
}
|
||||
@@ -1,95 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Class WatchPanel
|
||||
* @author Jeka
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.actions.DebuggerAction;
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.impl.DebuggerContextImpl;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTree;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor;
|
||||
import com.intellij.openapi.actionSystem.ActionPopupMenu;
|
||||
import com.intellij.openapi.actionSystem.CommonShortcuts;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.ui.ScrollPaneFactory;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Enumeration;
|
||||
|
||||
public abstract class WatchPanel extends DebuggerTreePanel {
|
||||
@NonNls private static final String HELP_ID = "debugging.debugWatches";
|
||||
|
||||
public WatchPanel(Project project, DebuggerStateManager stateManager) {
|
||||
super(project, stateManager);
|
||||
add(createTreePanel(getWatchTree()), BorderLayout.CENTER);
|
||||
registerDisposable(DebuggerAction.installEditAction(getWatchTree(), DebuggerActions.EDIT_NODE_SOURCE));
|
||||
overrideShortcut(getWatchTree(), DebuggerActions.COPY_VALUE, CommonShortcuts.getCopy());
|
||||
}
|
||||
|
||||
protected JComponent createTreePanel(final WatchDebuggerTree tree) {
|
||||
return ScrollPaneFactory.createScrollPane(tree);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DebuggerTree createTreeView() {
|
||||
return new WatchDebuggerTree(getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void changeEvent(DebuggerContextImpl newContext, int event) {
|
||||
if (event == DebuggerSession.EVENT_THREADS_REFRESH) {
|
||||
return;
|
||||
}
|
||||
if(event == DebuggerSession.EVENT_ATTACHED) {
|
||||
DebuggerTreeNodeImpl root = (DebuggerTreeNodeImpl) getWatchTree().getModel().getRoot();
|
||||
if(root != null) {
|
||||
for(Enumeration e = root.rawChildren(); e.hasMoreElements();) {
|
||||
DebuggerTreeNodeImpl child = (DebuggerTreeNodeImpl) e.nextElement();
|
||||
((WatchItemDescriptor) child.getDescriptor()).setNew();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rebuildIfVisible(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ActionPopupMenu createPopupMenu() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(String dataId) {
|
||||
if (PlatformDataKeys.HELP_ID.is(dataId)) {
|
||||
return HELP_ID;
|
||||
}
|
||||
return super.getData(dataId);
|
||||
}
|
||||
|
||||
public WatchDebuggerTree getWatchTree() {
|
||||
return (WatchDebuggerTree) getTree();
|
||||
}
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.tree.render;
|
||||
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.UnnamedConfigurable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class CompoundNodeConfigurable implements UnnamedConfigurable {
|
||||
private final CompoundNodeRenderer myRenderer;
|
||||
|
||||
private final UnnamedConfigurable myLabelConfigurable;
|
||||
private final UnnamedConfigurable myChildrenConfigurable;
|
||||
|
||||
private final static UnnamedConfigurable NULL_CONFIGURABLE = new UnnamedConfigurable() {
|
||||
public JComponent createComponent() {
|
||||
return new JPanel();
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void apply() {}
|
||||
public void reset() {}
|
||||
public void disposeUIResources() {}
|
||||
};
|
||||
|
||||
public CompoundNodeConfigurable(CompoundNodeRenderer renderer,
|
||||
UnnamedConfigurable labelConfigurable,
|
||||
UnnamedConfigurable childrenConfigurable) {
|
||||
myRenderer = renderer;
|
||||
myLabelConfigurable = labelConfigurable != null ? labelConfigurable : NULL_CONFIGURABLE;
|
||||
myChildrenConfigurable = childrenConfigurable != null ? childrenConfigurable : NULL_CONFIGURABLE;
|
||||
}
|
||||
|
||||
public CompoundNodeRenderer getRenderer() {
|
||||
return myRenderer;
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints c = new GridBagConstraints();
|
||||
c.fill = GridBagConstraints.BOTH;
|
||||
c.weightx = 1.0;
|
||||
c.insets = new Insets(0, 0, 5, 0);
|
||||
c.gridwidth = GridBagConstraints.REMAINDER;
|
||||
|
||||
panel.add(myLabelConfigurable.createComponent(), c);
|
||||
|
||||
c.ipady = 1;
|
||||
panel.add(new JSeparator(JSeparator.HORIZONTAL), c);
|
||||
|
||||
c.ipady = 0;
|
||||
c.weighty = 1.0;
|
||||
panel.add(myChildrenConfigurable.createComponent(), c);
|
||||
return panel;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return myLabelConfigurable.isModified() || myChildrenConfigurable.isModified();
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
myLabelConfigurable.apply();
|
||||
myChildrenConfigurable.apply();
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myLabelConfigurable.reset();
|
||||
myChildrenConfigurable.reset();
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
myLabelConfigurable.disposeUIResources();
|
||||
myChildrenConfigurable.disposeUIResources();
|
||||
}
|
||||
}
|
||||
-73
@@ -1,73 +0,0 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.ui.tree.render.configurables;
|
||||
|
||||
import com.intellij.debugger.DebuggerBundle;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.impl.DebuggerUtilsEx;
|
||||
import com.intellij.debugger.ui.CompletionEditor;
|
||||
import com.intellij.debugger.ui.tree.render.LabelRenderer;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.options.UnnamedConfigurable;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.LabeledComponent;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class ClassLabelExpressionConfigurable implements UnnamedConfigurable{
|
||||
private final LabelRenderer myRenderer;
|
||||
private LabeledComponent<CompletionEditor> myCompletionEditor;
|
||||
private final JPanel myPanel;
|
||||
|
||||
public ClassLabelExpressionConfigurable(@NotNull Project project, LabelRenderer renderer) {
|
||||
myRenderer = renderer;
|
||||
|
||||
myCompletionEditor = new LabeledComponent<CompletionEditor>();
|
||||
final PsiClass psiClass = DebuggerUtils.findClass(myRenderer.getClassName(), project, GlobalSearchScope.allScope(project));
|
||||
myCompletionEditor.setComponent(((DebuggerUtilsEx)DebuggerUtils.getInstance()).createEditor(project, psiClass, "ClassLabelExpression"));
|
||||
myCompletionEditor.setText(DebuggerBundle.message("label.class.label.expression.configurable.node.label"));
|
||||
|
||||
myPanel = new JPanel(new BorderLayout());
|
||||
myPanel.add(myCompletionEditor, BorderLayout.NORTH);
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
return myPanel;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
return !myRenderer.getLabelExpression().equals(myCompletionEditor.getComponent().getText());
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
myRenderer.setLabelExpression(myCompletionEditor.getComponent().getText());
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
myCompletionEditor.getComponent().setText(myRenderer.getLabelExpression());
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
if (myCompletionEditor != null) {
|
||||
myCompletionEditor.getComponent().dispose();
|
||||
myCompletionEditor = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,6 +32,7 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -59,7 +60,7 @@ public abstract class SourcePosition implements Navigatable{
|
||||
@NotNull private final PsiFile myFile;
|
||||
private long myModificationStamp = -1L;
|
||||
|
||||
private PsiElement myPsiElement;
|
||||
private WeakReference<PsiElement> myPsiElementRef;
|
||||
private Integer myLine;
|
||||
private Integer myOffset;
|
||||
|
||||
@@ -120,7 +121,7 @@ public abstract class SourcePosition implements Navigatable{
|
||||
myModificationStamp = myFile.getModificationStamp();
|
||||
myLine = null;
|
||||
myOffset = null;
|
||||
myPsiElement = null;
|
||||
myPsiElementRef = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,7 +129,7 @@ public abstract class SourcePosition implements Navigatable{
|
||||
if (myModificationStamp != myFile.getModificationStamp()) {
|
||||
return true;
|
||||
}
|
||||
final PsiElement psiElement = myPsiElement;
|
||||
final PsiElement psiElement = myPsiElementRef != null ? myPsiElementRef.get() : null;
|
||||
return psiElement != null && !ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
@@ -158,10 +159,13 @@ public abstract class SourcePosition implements Navigatable{
|
||||
@Override
|
||||
public PsiElement getElementAt() {
|
||||
updateData();
|
||||
if (myPsiElement == null) {
|
||||
myPsiElement = calcPsiElement();
|
||||
PsiElement element = myPsiElementRef != null ? myPsiElementRef.get() : null;
|
||||
if (element == null) {
|
||||
element = calcPsiElement();
|
||||
myPsiElementRef = new WeakReference<PsiElement>(element);
|
||||
return element;
|
||||
}
|
||||
return myPsiElement;
|
||||
return element;
|
||||
}
|
||||
|
||||
protected int calcLine() {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.projectRoots.JavaSdk;
|
||||
import com.intellij.openapi.projectRoots.JdkUtil;
|
||||
import com.intellij.openapi.projectRoots.ProjectJdkTable;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.ex.PathUtilEx;
|
||||
@@ -39,7 +40,6 @@ import org.intellij.lang.annotations.MagicConstant;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -90,7 +90,9 @@ public class JavaParametersUtil {
|
||||
}
|
||||
final List<OrderEntry> entriesForFile = fileIndex.getOrderEntriesForFile(virtualFile);
|
||||
for (OrderEntry entry : entriesForFile) {
|
||||
if (entry instanceof ExportableOrderEntry && ((ExportableOrderEntry)entry).getScope() == DependencyScope.TEST) return JavaParameters.JDK_AND_CLASSES_AND_TESTS;
|
||||
if (entry instanceof ExportableOrderEntry && ((ExportableOrderEntry)entry).getScope() == DependencyScope.TEST) {
|
||||
return JavaParameters.JDK_AND_CLASSES_AND_TESTS;
|
||||
}
|
||||
}
|
||||
return JavaParameters.JDK_AND_CLASSES;
|
||||
}
|
||||
@@ -106,12 +108,17 @@ public class JavaParametersUtil {
|
||||
configureModule(module, parameters, classPathType, jreHome);
|
||||
}
|
||||
|
||||
public static void configureModule(Module module, JavaParameters parameters, @MagicConstant(valuesFromClass = JavaParameters.class) int classPathType, @Nullable String jreHome) throws CantRunException {
|
||||
public static void configureModule(Module module,
|
||||
JavaParameters parameters,
|
||||
@MagicConstant(valuesFromClass = JavaParameters.class) int classPathType,
|
||||
@Nullable String jreHome) throws CantRunException {
|
||||
parameters.configureByModule(module, classPathType, createModuleJdk(module, jreHome));
|
||||
}
|
||||
|
||||
public static void configureProject(Project project, final JavaParameters parameters, @MagicConstant(valuesFromClass = JavaParameters.class) final int classPathType, @Nullable String jreHome)
|
||||
throws CantRunException {
|
||||
public static void configureProject(Project project,
|
||||
final JavaParameters parameters,
|
||||
@MagicConstant(valuesFromClass = JavaParameters.class) final int classPathType,
|
||||
@Nullable String jreHome) throws CantRunException {
|
||||
parameters.configureByProject(project, classPathType, createProjectJdk(project, jreHome));
|
||||
}
|
||||
|
||||
@@ -136,23 +143,29 @@ public class JavaParametersUtil {
|
||||
if (configuredJdk != null) {
|
||||
return configuredJdk;
|
||||
}
|
||||
final boolean isJdk = JavaSdk.checkForJdk(new File(jreHome));
|
||||
if (isJdk) {
|
||||
throw new CantRunException("Alternative JRE path needs to point to a JRE, not to a complete JDK installation");
|
||||
|
||||
if (JdkUtil.checkForJdk(jreHome)) {
|
||||
throw new CantRunException(ExecutionBundle.message("jre.path.is.jdk.error.message"));
|
||||
}
|
||||
if (!JdkUtil.checkForJre(jreHome)) {
|
||||
throw new CantRunException(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.message", jreHome));
|
||||
}
|
||||
|
||||
final Sdk jdk = JavaSdk.getInstance().createJdk("", jreHome);
|
||||
if (jdk == null) throw CantRunException.noJdkConfigured();
|
||||
return jdk;
|
||||
}
|
||||
|
||||
public static void checkAlternativeJRE(CommonJavaRunConfigurationParameters configuration) throws RuntimeConfigurationWarning {
|
||||
public static void checkAlternativeJRE(@NotNull CommonJavaRunConfigurationParameters configuration) throws RuntimeConfigurationWarning {
|
||||
if (configuration.isAlternativeJrePathEnabled()) {
|
||||
String alternativeJrePath = configuration.getAlternativeJrePath();
|
||||
if (StringUtil.isEmpty(alternativeJrePath) ||
|
||||
ProjectJdkTable.getInstance().findJdk(alternativeJrePath) == null && !JavaSdk.checkForJre(alternativeJrePath)) {
|
||||
throw new RuntimeConfigurationWarning(
|
||||
ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.mesage", alternativeJrePath));
|
||||
}
|
||||
checkAlternativeJRE(configuration.getAlternativeJrePath());
|
||||
}
|
||||
}
|
||||
|
||||
public static void checkAlternativeJRE(@Nullable String jrePath) throws RuntimeConfigurationWarning {
|
||||
if (StringUtil.isEmpty(jrePath) ||
|
||||
ProjectJdkTable.getInstance().findJdk(jrePath) == null && !JavaSdk.checkForJre(jrePath)) {
|
||||
throw new RuntimeConfigurationWarning(ExecutionBundle.message("jre.path.is.not.valid.jre.home.error.message", jrePath));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1040,6 +1040,7 @@ public class HighlightMethodUtil {
|
||||
boolean isInterface = aClass != null && aClass.isInterface();
|
||||
boolean isExtension = method.hasModifierProperty(PsiModifier.DEFAULT);
|
||||
boolean isStatic = method.hasModifierProperty(PsiModifier.STATIC);
|
||||
boolean isPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
|
||||
|
||||
final List<IntentionAction> additionalFixes = new ArrayList<IntentionAction>();
|
||||
String description = null;
|
||||
@@ -1053,7 +1054,7 @@ public class HighlightMethodUtil {
|
||||
}
|
||||
}
|
||||
else if (isInterface) {
|
||||
if (!isExtension && !isStatic) {
|
||||
if (!isExtension && !isStatic && !isPrivate) {
|
||||
description = JavaErrorMessages.message("interface.methods.cannot.have.body");
|
||||
if (languageLevel.isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
additionalFixes.add(QUICK_FIX_FACTORY.createModifierListFix(method, PsiModifier.DEFAULT, true, false));
|
||||
|
||||
+7
-6
@@ -154,12 +154,16 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
Set<String> incompatibles = incompatibleModifiersHash.get(modifier);
|
||||
if (incompatibles == null) return null;
|
||||
final boolean level8OrHigher = PsiUtil.isLanguageLevel8OrHigher(modifierList);
|
||||
final boolean level9OrHigher = PsiUtil.isLanguageLevel9OrHigher(modifierList);
|
||||
for (@PsiModifier.ModifierConstant String incompatible : incompatibles) {
|
||||
if (level8OrHigher) {
|
||||
if (modifier.equals(PsiModifier.STATIC) && incompatible.equals(PsiModifier.ABSTRACT)){
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (level9OrHigher && modifier.equals(PsiModifier.PRIVATE) && incompatible.equals(PsiModifier.PUBLIC)) {
|
||||
continue;
|
||||
}
|
||||
if (modifier.equals(PsiModifier.STATIC) && incompatible.equals(PsiModifier.FINAL)) {
|
||||
final PsiElement parent = modifierList.getParent();
|
||||
if (parent instanceof PsiMethod) {
|
||||
@@ -475,6 +479,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
HighlightInfo highlightInfo = checkAssignability(lType, rType, initializer, new TextRange(start, end), 0);
|
||||
if (highlightInfo != null) {
|
||||
registerChangeVariableTypeFixes(variable, rType, variable.getInitializer(), highlightInfo);
|
||||
registerChangeVariableTypeFixes(initializer, lType, null, highlightInfo);
|
||||
}
|
||||
return highlightInfo;
|
||||
}
|
||||
@@ -883,7 +888,8 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
|
||||
if (PsiModifier.PRIVATE.equals(modifier) || PsiModifier.PROTECTED.equals(modifier) || PsiModifier.TRANSIENT.equals(modifier) ||
|
||||
PsiModifier.STRICTFP.equals(modifier) || PsiModifier.SYNCHRONIZED.equals(modifier)) {
|
||||
isAllowed &= modifierOwnerParent instanceof PsiClass && !((PsiClass)modifierOwnerParent).isInterface();
|
||||
isAllowed &= modifierOwnerParent instanceof PsiClass &&
|
||||
(!((PsiClass)modifierOwnerParent).isInterface() || PsiUtil.isLanguageLevel9OrHigher(modifierOwner));
|
||||
}
|
||||
|
||||
if (containingClass != null && containingClass.isAnnotationType()) {
|
||||
@@ -2726,11 +2732,6 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
QuickFixAction.registerQuickFixAction(highlightInfo, PriorityActionWrapper
|
||||
.lowPriority(method, QUICK_FIX_FACTORY.createMethodReturnFix(method, parameter.getType(), true)));
|
||||
}
|
||||
} else if (expr instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolve = ((PsiReferenceExpression)expr).resolve();
|
||||
if (resolve instanceof PsiVariable) {
|
||||
registerChangeVariableTypeFixes((PsiVariable)resolve, parameter.getType(), null, highlightInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-3
@@ -141,7 +141,8 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
PsiClass containingClass = PsiTreeUtil.getParentOfType(scope, PsiClass.class);
|
||||
if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) return;
|
||||
|
||||
final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, true) {
|
||||
final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(TREAT_UNKNOWN_MEMBERS_AS_NULLABLE, !isInsideConstructorOrInitializer(
|
||||
scope)) {
|
||||
@Override
|
||||
protected boolean shouldCheckTimeLimit() {
|
||||
if (!onTheFly) return false;
|
||||
@@ -151,6 +152,15 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
analyzeDfaWithNestedClosures(scope, holder, dfaRunner, Arrays.asList(dfaRunner.createMemoryState()), onTheFly);
|
||||
}
|
||||
|
||||
private static boolean isInsideConstructorOrInitializer(PsiElement element) {
|
||||
while (element != null) {
|
||||
element = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClassInitializer.class);
|
||||
if (element instanceof PsiClassInitializer) return true;
|
||||
if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void analyzeDfaWithNestedClosures(PsiElement scope,
|
||||
ProblemsHolder holder,
|
||||
StandardDataFlowRunner dfaRunner,
|
||||
@@ -190,7 +200,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
|
||||
final PsiBinaryExpression binary = (PsiBinaryExpression)elementFactory.createExpressionFromText("a != null", null);
|
||||
binary.getLOperand().replace(qualifier);
|
||||
ContainerUtil.addIfNotNull(fixes, createAssertFix(binary));
|
||||
ContainerUtil.addIfNotNull(fixes, createAssertFix(binary, expression));
|
||||
}
|
||||
|
||||
addSurroundWithIfFix(qualifier, fixes, onTheFly);
|
||||
@@ -206,7 +216,7 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
protected LocalQuickFix createAssertFix(PsiBinaryExpression binary) {
|
||||
protected LocalQuickFix createAssertFix(PsiBinaryExpression binary, PsiExpression expression) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ public class JavaInheritorsGetter extends CompletionProvider<CompletionParameter
|
||||
final String erasedText = TypeConversionUtil.erasure(psiType).getCanonicalText();
|
||||
String canonicalText = psiType.getCanonicalText();
|
||||
if (canonicalText.contains("?extends") || canonicalText.contains("?super")) {
|
||||
LOG.error("Malformed canonical text: " + psiType + " of " + psiType.getClass() + "; " +
|
||||
LOG.error("Malformed canonical text: " + canonicalText + "; presentable text: " + psiType + " of " + psiType.getClass() + "; " +
|
||||
(psiType instanceof PsiClassReferenceType ? ((PsiClassReferenceType)psiType).getReference().getClass() : ""));
|
||||
return null;
|
||||
}
|
||||
|
||||
+4
-3
@@ -67,8 +67,9 @@ public class MissingMethodBodyFixer implements Fixer {
|
||||
static boolean shouldHaveBody(PsiMethod method) {
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) return false;
|
||||
if (containingClass.isInterface() && !method.hasModifierProperty(DEFAULT)) return false;
|
||||
if (method.hasModifierProperty(ABSTRACT)) return false;
|
||||
return !method.hasModifierProperty(NATIVE);
|
||||
if (method.hasModifierProperty(PRIVATE)) return true;
|
||||
if (method.hasModifierProperty(ABSTRACT) || method.hasModifierProperty(NATIVE)) return false;
|
||||
if (containingClass.isInterface() && !method.hasModifierProperty(DEFAULT) && !method.hasModifierProperty(STATIC)) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiAssignmentExpression;
|
||||
import com.intellij.psi.PsiBinaryExpression;
|
||||
import com.intellij.psi.PsiExpression;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.refactoring.util.RefactoringUtil;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
@@ -59,8 +60,8 @@ public class DataFlowInspection extends DataFlowInspectionBase {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AddAssertStatementFix createAssertFix(PsiBinaryExpression binary) {
|
||||
return new AddAssertStatementFix(binary);
|
||||
protected AddAssertStatementFix createAssertFix(PsiBinaryExpression binary, PsiExpression expression) {
|
||||
return RefactoringUtil.getParentStatement(expression, false) == null ? null : new AddAssertStatementFix(binary);
|
||||
}
|
||||
|
||||
private class OptionsPanel extends JPanel {
|
||||
|
||||
@@ -762,7 +762,7 @@ public class JavaDocumentationProvider implements CodeDocumentationProvider, Ext
|
||||
|
||||
@Override
|
||||
public boolean hasDocumentationFor(PsiElement element, PsiElement originalElement) {
|
||||
return CompositeDocumentationProvider.hasUrlsFor(this, element, originalElement);
|
||||
return CompositeDocumentationProvider.hasBrowsableUrlsFor(this, element, originalElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+4
-2
@@ -211,13 +211,15 @@ public class IntroduceParameterObjectProcessor extends FixableUsagesRefactoringP
|
||||
final ParameterChunk parameterChunk = ParameterChunk.getChunkByParameter(parameter, parameters);
|
||||
|
||||
@NonNls String getter = parameterChunk != null ? parameterChunk.getter : null;
|
||||
final String paramName = parameterChunk != null ? parameterChunk.parameter.name : replacedParameter.getName();
|
||||
final PsiType paramType = parameterChunk != null ? parameterChunk.parameter.type : replacedParameter.getType();
|
||||
if (getter == null) {
|
||||
getter = GenerateMembersUtil.suggestGetterName(replacedParameter.getName(), replacedParameter.getType(), myProject);
|
||||
getter = GenerateMembersUtil.suggestGetterName(paramName, paramType, myProject);
|
||||
paramsNeedingGetters.add(replacedParameter);
|
||||
}
|
||||
@NonNls String setter = parameterChunk != null ? parameterChunk.setter : null;
|
||||
if (setter == null) {
|
||||
setter = GenerateMembersUtil.suggestSetterName(replacedParameter.getName(), replacedParameter.getType(), myProject);
|
||||
setter = GenerateMembersUtil.suggestSetterName(paramName, paramType, myProject);
|
||||
}
|
||||
if (RefactoringUtil.isPlusPlusOrMinusMinus(paramUsage.getParent())) {
|
||||
usages.add(new ReplaceParameterIncrementDecrement(paramUsage, fixedParamName, setter, getter));
|
||||
|
||||
+15
-7
@@ -16,6 +16,8 @@
|
||||
package com.intellij.refactoring.introduceparameterobject.usageInfo;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
@@ -66,14 +68,15 @@ public class MergeMethodArguments extends FixableUsageInfo {
|
||||
}
|
||||
|
||||
public void fixUsage() throws IncorrectOperationException {
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(method.getProject());
|
||||
final Project project = method.getProject();
|
||||
final JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(project);
|
||||
final PsiMethod deepestSuperMethod = method.findDeepestSuperMethod();
|
||||
final PsiClass psiClass;
|
||||
if (myContainingClass != null) {
|
||||
psiClass = myContainingClass.findInnerClassByName(className, false);
|
||||
}
|
||||
else {
|
||||
psiClass = psiFacade.findClass(StringUtil.getQualifiedName(packageName, className), GlobalSearchScope.allScope(getProject()));
|
||||
psiClass = psiFacade.findClass(StringUtil.getQualifiedName(packageName, className), GlobalSearchScope.allScope(project));
|
||||
}
|
||||
assert psiClass != null;
|
||||
PsiSubstitutor subst = PsiSubstitutor.EMPTY;
|
||||
@@ -93,12 +96,12 @@ public class MergeMethodArguments extends FixableUsageInfo {
|
||||
}
|
||||
}
|
||||
final List<ParameterInfoImpl> parametersInfo = new ArrayList<ParameterInfoImpl>();
|
||||
final PsiClassType classType = JavaPsiFacade.getElementFactory(getProject()).createType(psiClass, subst);
|
||||
final PsiClassType classType = JavaPsiFacade.getElementFactory(project).createType(psiClass, subst);
|
||||
|
||||
final ParameterInfoImpl mergedParamInfo = new ParameterInfoImpl(-1, parameterName, classType, null) {
|
||||
@Override
|
||||
public PsiExpression getValue(final PsiCallExpression expr) throws IncorrectOperationException {
|
||||
return (PsiExpression)JavaCodeStyleManager.getInstance(getProject())
|
||||
return (PsiExpression)JavaCodeStyleManager.getInstance(project)
|
||||
.shortenClassReferences(psiFacade.getElementFactory().createExpressionFromText(getMergedParam(expr), expr));
|
||||
}
|
||||
};
|
||||
@@ -114,9 +117,9 @@ public class MergeMethodArguments extends FixableUsageInfo {
|
||||
}
|
||||
|
||||
parametersInfo.add(firstIncludedIdx == -1 ? 0 : firstIncludedIdx, mergedParamInfo);
|
||||
final SmartPsiElementPointer<PsiMethod> meth = SmartPointerManager.getInstance(getProject()).createSmartPsiElementPointer(method);
|
||||
final SmartPsiElementPointer<PsiMethod> meth = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(method);
|
||||
|
||||
Runnable performChangeSignatureRunnable = new Runnable() {
|
||||
final Runnable performChangeSignatureRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final PsiMethod psiMethod = meth.getElement();
|
||||
@@ -134,7 +137,12 @@ public class MergeMethodArguments extends FixableUsageInfo {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
performChangeSignatureRunnable.run();
|
||||
} else {
|
||||
ApplicationManager.getApplication().invokeLater(performChangeSignatureRunnable);
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
CommandProcessor.getInstance().runUndoTransparentAction(performChangeSignatureRunnable);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -83,7 +83,7 @@ public class MakeMethodStaticProcessor extends MakeMethodOrClassStaticProcessor<
|
||||
@Override
|
||||
protected MultiMap<PsiElement, String> getConflictDescriptions(UsageInfo[] usages) {
|
||||
MultiMap<PsiElement, String> descriptions = super.getConflictDescriptions(usages);
|
||||
if (mySettings.isMakeClassParameter()) {
|
||||
if (mySettings.isMakeClassParameter() || mySettings.isMakeFieldParameters()) {
|
||||
for (UsageInfo usage : usages) {
|
||||
PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiMethodReferenceExpression) {
|
||||
@@ -329,7 +329,7 @@ public class MakeMethodStaticProcessor extends MakeMethodOrClassStaticProcessor<
|
||||
if (anchor != null) {
|
||||
anchor = argList.addAfter(fieldRef, anchor);
|
||||
}
|
||||
else {
|
||||
else if (argList != null) {
|
||||
if (exprs.length > 0) {
|
||||
anchor = argList.addBefore(fieldRef, exprs[0]);
|
||||
}
|
||||
|
||||
@@ -82,7 +82,11 @@ public abstract class PsiClassType extends PsiType {
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) return true;
|
||||
if (!(obj instanceof PsiClassType)) return false;
|
||||
if (!(obj instanceof PsiClassType)) {
|
||||
return obj instanceof PsiCapturedWildcardType &&
|
||||
((PsiCapturedWildcardType)obj).getLowerBound().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) &&
|
||||
equalsToText(CommonClassNames.JAVA_LANG_OBJECT);
|
||||
}
|
||||
PsiClassType otherClassType = (PsiClassType)obj;
|
||||
|
||||
String className = getClassName();
|
||||
|
||||
@@ -889,6 +889,10 @@ public final class PsiUtil extends PsiUtilCore {
|
||||
return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_8);
|
||||
}
|
||||
|
||||
public static boolean isLanguageLevel9OrHigher(@NotNull final PsiElement element) {
|
||||
return getLanguageLevel(element).isAtLeast(LanguageLevel.JDK_1_9);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static LanguageLevel getLanguageLevel(@NotNull PsiElement element) {
|
||||
if (element instanceof PsiDirectory) {
|
||||
|
||||
@@ -130,7 +130,10 @@ public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub>
|
||||
return false;
|
||||
}
|
||||
if (type == JavaTokenType.ABSTRACT_KEYWORD) {
|
||||
return getNode().findChildByType(JavaTokenType.DEFAULT_KEYWORD) == null && getNode().findChildByType(JavaTokenType.STATIC_KEYWORD) == null;
|
||||
final ASTNode node = getNode();
|
||||
return node.findChildByType(JavaTokenType.DEFAULT_KEYWORD) == null &&
|
||||
node.findChildByType(JavaTokenType.STATIC_KEYWORD) == null &&
|
||||
node.findChildByType(JavaTokenType.PRIVATE_KEYWORD) == null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public class T {
|
||||
|
||||
|
||||
public void tutu() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void test() {}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
public class T {
|
||||
|
||||
|
||||
<selection> public void tutu() {
|
||||
|
||||
}</selection>
|
||||
|
||||
|
||||
public void test() {}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public interface Foo {
|
||||
private void foo(<caret>)
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public interface Foo {
|
||||
private void foo() {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
public interface Foo {
|
||||
static void foo(<caret>)
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
public interface Foo {
|
||||
static void foo() {
|
||||
<caret>
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
interface A {
|
||||
private void m() {}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
class A<T> {}
|
||||
|
||||
class Test {
|
||||
{
|
||||
A<? super Object> queue = null;
|
||||
A<Object> q = queue;
|
||||
queue = q;
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
// "Assert 'myFoo != null'" "false"
|
||||
class A{
|
||||
private final String myFoo = null;
|
||||
String myBar = my<caret>Foo.substring(0);
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Change field 'foo' type to 'java.lang.String[]'" "true"
|
||||
|
||||
class Base {
|
||||
private String[] foo;
|
||||
public void bar(String... args) {
|
||||
foo = args;
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
// "Change field 'foo' type to 'java.lang.String[]'" "true"
|
||||
|
||||
class Base {
|
||||
private String foo;
|
||||
public void bar(String... args) {
|
||||
foo<caret> = args;
|
||||
}
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
class SomeClass {
|
||||
private final Object myField;
|
||||
|
||||
{
|
||||
if (<error descr="Variable 'myField' might not have been initialized">myField</error> != null) { // false-positive report 'condition is always true'
|
||||
System.out.println(myField.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public SomeClass(SomeOtherClass o) {
|
||||
o.invoke(new Runnable() {
|
||||
public void run() {
|
||||
if (myField != null) { // false-positive report 'condition is always true'
|
||||
System.out.println(myField.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
myField = "xxx";
|
||||
}
|
||||
}
|
||||
|
||||
class SomeOtherClass {
|
||||
public void invoke(Runnable r) {
|
||||
r.run();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test4 {
|
||||
void test() {
|
||||
Runnable f = Test4::yyy;
|
||||
}
|
||||
|
||||
String myField = "";
|
||||
static void yyy() {
|
||||
System.out.println(myField);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class Test4 {
|
||||
void test() {
|
||||
Runnable f = this::yyy;
|
||||
}
|
||||
|
||||
String myField = "";
|
||||
void yy<caret>y() {
|
||||
System.out.println(myField);
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@ package com.intellij.codeInsight;
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.lang.java.JavaLanguage;
|
||||
import com.intellij.openapi.actionSystem.IdeActions;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.psi.codeStyle.CommonCodeStyleSettings;
|
||||
import com.intellij.testFramework.EditorActionTestCase;
|
||||
@@ -272,6 +271,8 @@ public class CompleteStatementTest extends EditorActionTestCase {
|
||||
public void testGenericMethodBody() throws Exception { doTest(); }
|
||||
|
||||
public void testDefaultMethodBody() { doTest(); }
|
||||
public void testStaticInterfaceMethodBody() { doTest(); }
|
||||
public void testPrivateInterfaceMethodBody() { doTest(); }
|
||||
|
||||
public void testArrayInitializerRBracket() throws Exception { doTest(); }
|
||||
|
||||
|
||||
+5
@@ -102,4 +102,9 @@ public class ReformatCodeActionInEditorTest extends LightPlatformCodeInsightFixt
|
||||
public void testFormatOptimizeRearrangeVcsChanges() {
|
||||
doTest(new ReformatCodeRunOptions(VCS_CHANGED_TEXT).setOptimizeImports(true).setRearrangeCode(true));
|
||||
}
|
||||
|
||||
public void testFormatSelection_DoNotTouchTrailingWhiteSpaces() {
|
||||
//todo actually test is not working, and working test is not working
|
||||
doTest(new ReformatCodeRunOptions(SELECTED_TEXT));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,6 +471,10 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testSuperObjectCapturedWildcardEquality() throws Exception {
|
||||
doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false);
|
||||
}
|
||||
|
||||
public void testJavaUtilCollections_NoVerify() throws Exception {
|
||||
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));
|
||||
assertNotNull(collectionsClass);
|
||||
|
||||
+1
@@ -53,4 +53,5 @@ public class LightAdvHighlightingJdk9Test extends LightDaemonAnalyzerTestCase {
|
||||
}
|
||||
|
||||
public void testSafeVarargsApplicability() { doTest(true, false); }
|
||||
public void testPrivateInInterfaces() { doTest(false, false); }
|
||||
}
|
||||
|
||||
@@ -194,6 +194,7 @@ public class DataFlowInspectionTest extends LightCodeInsightFixtureTestCase {
|
||||
public void testRememberLocalTransientFieldState() { doTest(); }
|
||||
public void testFinalFieldDuringInitialization() { doTest(); }
|
||||
public void testFinalFieldDuringSuperInitialization() { doTest(); }
|
||||
public void testFinalFieldInConstructorAnonymous() { doTest(); }
|
||||
public void _testSymmetricUncheckedCast() { doTest(); } // https://youtrack.jetbrains.com/issue/IDEABKL-6871
|
||||
public void testNullCheckDoesntAffectUncheckedCast() { doTest(); }
|
||||
public void testThrowNull() { doTest(); }
|
||||
|
||||
@@ -203,6 +203,10 @@ public class MakeMethodStaticTest extends LightRefactoringTestCase {
|
||||
doTest(true);
|
||||
}
|
||||
|
||||
public void testThisMethodReference() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
public void testPreserveParametersAlignment() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
+34
-13
@@ -1471,26 +1471,47 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
|
||||
@Override
|
||||
public void visitNewExpression(final PsiNewExpression new1) {
|
||||
if (myMatchingVisitor.getElement() instanceof PsiArrayInitializerExpression &&
|
||||
myMatchingVisitor.getElement().getParent() instanceof PsiVariable &&
|
||||
final PsiElement other = myMatchingVisitor.getElement();
|
||||
final PsiJavaCodeReferenceElement classReference = new1.getClassReference();
|
||||
if (other instanceof PsiArrayInitializerExpression &&
|
||||
other.getParent() instanceof PsiVariable &&
|
||||
new1.getArrayDimensions().length == 0 &&
|
||||
new1.getArrayInitializer() != null
|
||||
) {
|
||||
myMatchingVisitor.setResult(
|
||||
myMatchingVisitor.match(new1.getClassReference(), ((PsiVariable)myMatchingVisitor.getElement().getParent()).getTypeElement()));
|
||||
myMatchingVisitor.matchSons(new1.getArrayInitializer(), myMatchingVisitor.getElement());
|
||||
final boolean looseMatching = myMatchingVisitor.getMatchContext().getOptions().isLooseMatching();
|
||||
final boolean typedVar = myMatchingVisitor.getMatchContext().getPattern().isTypedVar(classReference);
|
||||
if ((typedVar || !looseMatching) && !allowsAbsenceOfMatch(classReference)) {
|
||||
myMatchingVisitor.setResult(false);
|
||||
return;
|
||||
}
|
||||
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(other.getProject());
|
||||
final PsiType otherType = ((PsiVariable)other.getParent()).getType();
|
||||
final PsiTypeElement otherTypeElement = factory.createTypeElement(otherType.getDeepComponentType());
|
||||
final MatchContext matchContext = myMatchingVisitor.getMatchContext();
|
||||
final MatchingHandler handler = matchContext.getPattern().getHandler(classReference);
|
||||
if (handler instanceof SubstitutionHandler) {
|
||||
final SubstitutionHandler substitutionHandler = (SubstitutionHandler)handler;
|
||||
myMatchingVisitor.setResult(substitutionHandler.handle(otherTypeElement, matchContext));
|
||||
}
|
||||
else {
|
||||
final PsiType type = new1.getType();
|
||||
myMatchingVisitor.setResult(type != null && type.equals(otherType));
|
||||
}
|
||||
if (myMatchingVisitor.getResult()) {
|
||||
myMatchingVisitor.matchSons(new1.getArrayInitializer(), other);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(myMatchingVisitor.getElement() instanceof PsiNewExpression)) {
|
||||
if (!(other instanceof PsiNewExpression)) {
|
||||
myMatchingVisitor.setResult(false);
|
||||
return;
|
||||
}
|
||||
final PsiNewExpression new2 = (PsiNewExpression)myMatchingVisitor.getElement();
|
||||
final PsiNewExpression new2 = (PsiNewExpression)other;
|
||||
|
||||
if (new1.getClassReference() != null) {
|
||||
if (classReference != null) {
|
||||
if (new2.getClassReference() != null) {
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), new2.getClassReference()) &&
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, new2.getClassReference()) &&
|
||||
myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
|
||||
|
||||
if (myMatchingVisitor.getResult()) {
|
||||
@@ -1507,7 +1528,7 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
if (element != null && element.getNextSibling() instanceof PsiKeyword) {
|
||||
((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true);
|
||||
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), element.getNextSibling()) &&
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, element.getNextSibling()) &&
|
||||
myMatchingVisitor.matchSons(new1.getArrayInitializer(), new2.getArrayInitializer()));
|
||||
|
||||
((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false);
|
||||
@@ -1521,17 +1542,17 @@ public class JavaMatchingVisitor extends JavaElementVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
if (new1.getClassReference() == new2.getClassReference()) {
|
||||
if (classReference == new2.getClassReference()) {
|
||||
// probably anonymous class or array of primitive type
|
||||
((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(true);
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.matchSons(new1, new2));
|
||||
((LexicalNodesFilter)LexicalNodesFilter.getInstance()).setCareKeyWords(false);
|
||||
}
|
||||
else if (new1.getAnonymousClass() == null &&
|
||||
new1.getClassReference() != null &&
|
||||
classReference != null &&
|
||||
new2.getAnonymousClass() != null) {
|
||||
// allow matching anonymous class without pattern
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(new1.getClassReference(), new2.getAnonymousClass().getBaseClassReference()) &&
|
||||
myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, new2.getAnonymousClass().getBaseClassReference()) &&
|
||||
myMatchingVisitor.matchSons(new1.getArgumentList(), new2.getArgumentList()));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.jetbrains.jps.builders.*;
|
||||
import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
|
||||
import org.jetbrains.jps.builders.java.dependencyView.Callbacks;
|
||||
import org.jetbrains.jps.incremental.MessageHandler;
|
||||
import org.jetbrains.jps.incremental.RebuildRequestedException;
|
||||
import org.jetbrains.jps.incremental.TargetTypeRegistry;
|
||||
import org.jetbrains.jps.incremental.Utils;
|
||||
import org.jetbrains.jps.incremental.fs.BuildFSState;
|
||||
@@ -567,14 +568,13 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
return event.getChangedPathsCount() != 0 || event.getDeletedPathsCount() != 0;
|
||||
}
|
||||
|
||||
private void finishBuild(Throwable error, boolean hadBuildErrors, boolean doneSomething) {
|
||||
private void finishBuild(final Throwable error, boolean hadBuildErrors, boolean doneSomething) {
|
||||
CmdlineRemoteProto.Message lastMessage = null;
|
||||
try {
|
||||
if (error instanceof CannotLoadJpsModelException) {
|
||||
String text = "Failed to load project configuration: " + StringUtil.decapitalize(error.getMessage());
|
||||
String path = ((CannotLoadJpsModelException)error).getFile().getAbsolutePath();
|
||||
lastMessage = CmdlineProtoUtil.toMessage(mySessionId, CmdlineProtoUtil.createCompileMessage(BuildMessage.Kind.ERROR, text, path,
|
||||
-1, -1, -1, -1, -1, -1.0f));
|
||||
lastMessage = CmdlineProtoUtil.toMessage(mySessionId, CmdlineProtoUtil.createCompileMessage(BuildMessage.Kind.ERROR, text, path, -1, -1, -1, -1, -1, -1.0f));
|
||||
}
|
||||
else if (error != null) {
|
||||
Throwable cause = error.getCause();
|
||||
@@ -596,6 +596,9 @@ final class BuildSession implements Runnable, CanceledStatus {
|
||||
if (!trace.isEmpty()) {
|
||||
messageText.append("\n").append(trace);
|
||||
}
|
||||
if (error instanceof RebuildRequestedException) {
|
||||
messageText.append("\n").append("Please perform full project rebuild (Build | Rebuild Project)");
|
||||
}
|
||||
lastMessage = CmdlineProtoUtil.toMessage(mySessionId, CmdlineProtoUtil.createFailure(messageText.toString(), cause));
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -425,9 +425,8 @@ public class IconUtil {
|
||||
final BufferedImage img = UIUtil.createImage(source.getIconWidth(), source.getIconHeight(), Transparency.TRANSLUCENT);
|
||||
int[] rgba = new int[4];
|
||||
float[] hsb = new float[3];
|
||||
boolean hiDPI = RetinaImage.isAppleHiDPIScaledImage(image);
|
||||
for (int y = 0; y < image.getHeight() * (hiDPI ? 2 : 1); y++) {
|
||||
for (int x = 0; x < image.getWidth() * (hiDPI ? 2 : 1); x++) {
|
||||
for (int y = 0; y < image.getRaster().getHeight(); y++) {
|
||||
for (int x = 0; x < image.getRaster().getWidth(); x++) {
|
||||
image.getRaster().getPixel(x, y, rgba);
|
||||
if (rgba[3] != 0) {
|
||||
Color.RGBtoHSB(rgba[0], rgba[1], rgba[2], hsb);
|
||||
|
||||
+20
-14
@@ -46,6 +46,13 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.smartPointers.SmartPointerManagerImpl");
|
||||
private static final Object lock = new Object();
|
||||
private static final ReferenceQueue<SmartPointerEx> ourQueue = new ReferenceQueue<SmartPointerEx>();
|
||||
@SuppressWarnings("unused") private static final LowMemoryWatcher ourWatcher = LowMemoryWatcher.register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
processQueue();
|
||||
}
|
||||
});
|
||||
|
||||
private final Project myProject;
|
||||
private final Key<Set<PointerReference>> POINTERS_KEY;
|
||||
private final Key<Boolean> POINTERS_ARE_FASTENED_KEY;
|
||||
@@ -54,24 +61,18 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
myProject = project;
|
||||
POINTERS_KEY = Key.create("SMART_POINTERS for "+project);
|
||||
POINTERS_ARE_FASTENED_KEY = Key.create("SMART_POINTERS_ARE_FASTENED for "+project);
|
||||
LowMemoryWatcher.register(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
processQueue();
|
||||
}
|
||||
}, project);
|
||||
}
|
||||
|
||||
private void processQueue() {
|
||||
private static void processQueue() {
|
||||
while (true) {
|
||||
PointerReference reference = (PointerReference)ourQueue.poll();
|
||||
if (reference == null) break;
|
||||
synchronized (lock) {
|
||||
Set<PointerReference> pointers = reference.file.getUserData(POINTERS_KEY);
|
||||
Set<PointerReference> pointers = reference.file.getUserData(reference.key);
|
||||
if (pointers != null) {
|
||||
pointers.remove(reference);
|
||||
if (pointers.isEmpty()) {
|
||||
reference.file.putUserData(POINTERS_KEY, null);
|
||||
reference.file.putUserData(reference.key, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,7 +217,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
pointers = ContainerUtil.newTroveSet(); // we synchronise access anyway
|
||||
containingFile.putUserData(POINTERS_KEY, pointers);
|
||||
}
|
||||
pointers.add(new PointerReference(pointer, containingFile));
|
||||
pointers.add(new PointerReference(pointer, containingFile, ourQueue, POINTERS_KEY));
|
||||
|
||||
if (areBeltsFastened(containingFile)) {
|
||||
pointer.fastenBelt(0, null);
|
||||
@@ -294,7 +295,7 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
file.putUserData(POINTERS_ARE_FASTENED_KEY, null);
|
||||
return fastened;
|
||||
}
|
||||
private boolean areBeltsFastened(@NotNull VirtualFile file) {
|
||||
private boolean areBeltsFastened(VirtualFile file) {
|
||||
return file.getUserData(POINTERS_ARE_FASTENED_KEY) == Boolean.TRUE;
|
||||
}
|
||||
|
||||
@@ -304,12 +305,17 @@ public class SmartPointerManagerImpl extends SmartPointerManager {
|
||||
}
|
||||
|
||||
private static class PointerReference extends WeakReference<SmartPointerEx> {
|
||||
@NotNull
|
||||
private final VirtualFile file;
|
||||
private final Key<Set<PointerReference>> key;
|
||||
|
||||
private PointerReference(@NotNull SmartPointerEx<?> pointer, @NotNull VirtualFile containingFile) {
|
||||
super(pointer, ourQueue);
|
||||
public PointerReference(SmartPointerEx<?> pointer,
|
||||
VirtualFile containingFile,
|
||||
ReferenceQueue<SmartPointerEx> queue,
|
||||
Key<Set<PointerReference>> key) {
|
||||
super(pointer, queue);
|
||||
file = containingFile;
|
||||
this.key = key;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -334,5 +334,25 @@ public class DiffIterableUtil {
|
||||
this.val1 = val1;
|
||||
this.val2 = val2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
IntPair pair = (IntPair)o;
|
||||
|
||||
if (val1 != pair.val1) return false;
|
||||
if (val2 != pair.val2) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = val1;
|
||||
result = 31 * result + val2;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,12 @@
|
||||
*/
|
||||
package com.intellij.diff.comparison;
|
||||
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
import com.intellij.util.text.CharSequenceSubSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Map;
|
||||
@@ -68,4 +72,37 @@ public abstract class AutoTestCase extends UsefulTestCase {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String textToReadableFormat(@Nullable Document text) {
|
||||
if (text == null) return "null";
|
||||
return "'" + text.getCharsSequence().toString().replace('\n', '*').replace('\t', '+') + "'";
|
||||
}
|
||||
|
||||
public static void assertEqualsCharSequences(@NotNull CharSequence chunk1, @NotNull CharSequence chunk2,
|
||||
boolean ignoreSpaces, boolean skipLastNewline) {
|
||||
if (ignoreSpaces) {
|
||||
assertTrue(StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2));
|
||||
}
|
||||
else {
|
||||
if (skipLastNewline) {
|
||||
CharSequence chunk12 = StringUtil.endsWithChar(chunk1, '\n') ? trimLastChar(chunk1) : null;
|
||||
CharSequence chunk22 = StringUtil.endsWithChar(chunk2, '\n') ? trimLastChar(chunk2) : null;
|
||||
|
||||
if (StringUtil.equals(chunk1, chunk2)) return;
|
||||
if (StringUtil.equals(chunk12, chunk2)) return;
|
||||
if (StringUtil.equals(chunk1, chunk22)) return;
|
||||
|
||||
assertTrue(false);
|
||||
}
|
||||
else {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence trimLastChar(@NotNull CharSequence text) {
|
||||
return new CharSequenceSubSequence(text, 0, text.length() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,11 +22,8 @@ import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.util.text.CharSequenceSubSequence;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -37,8 +34,8 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
private static DumbProgressIndicator INDICATOR = DumbProgressIndicator.INSTANCE;
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
private static int CHAR_COUNT = 12;
|
||||
private static Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
private static final int CHAR_COUNT = 12;
|
||||
private static final Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
|
||||
private boolean myOldRegistryValue;
|
||||
|
||||
@@ -173,8 +170,8 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
System.out.println("Policy: " + policy);
|
||||
System.out.println("I: " + i);
|
||||
System.out.println("Current seed: " + getLastSeed());
|
||||
System.out.println("Text1: " + normalize(text1));
|
||||
System.out.println("Text2: " + normalize(text2));
|
||||
System.out.println("Text1: " + textToReadableFormat(text1));
|
||||
System.out.println("Text2: " + textToReadableFormat(text2));
|
||||
System.out.println("Debug Data: " + debugData.get());
|
||||
if (e instanceof Error) throw (Error)e;
|
||||
if (e instanceof Exception) throw (Exception)e;
|
||||
@@ -320,41 +317,14 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
CharSequence chunk1 = text1.subSequence(last1, fragment.getStartOffset1());
|
||||
CharSequence chunk2 = text2.subSequence(last2, fragment.getStartOffset2());
|
||||
|
||||
check(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
|
||||
last1 = fragment.getEndOffset1();
|
||||
last2 = fragment.getEndOffset2();
|
||||
}
|
||||
CharSequence chunk1 = text1.subSequence(last1, text1.length());
|
||||
CharSequence chunk2 = text2.subSequence(last2, text2.length());
|
||||
check(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
}
|
||||
|
||||
private static void check(@NotNull CharSequence chunk1, @NotNull CharSequence chunk2,
|
||||
boolean ignoreSpaces, boolean skipNewline) {
|
||||
if (ignoreSpaces) {
|
||||
assertTrue(StringUtil.equalsIgnoreWhitespaces(chunk1, chunk2));
|
||||
}
|
||||
else {
|
||||
if (skipNewline) {
|
||||
CharSequence chunk12 = StringUtil.endsWithChar(chunk1, '\n') ? trimLastChar(chunk1) : null;
|
||||
CharSequence chunk22 = StringUtil.endsWithChar(chunk2, '\n') ? trimLastChar(chunk2) : null;
|
||||
|
||||
if (StringUtil.equals(chunk1, chunk2)) return;
|
||||
if (StringUtil.equals(chunk12, chunk2)) return;
|
||||
if (StringUtil.equals(chunk1, chunk22)) return;
|
||||
|
||||
assertTrue(false);
|
||||
}
|
||||
else {
|
||||
assertTrue(StringUtil.equals(chunk1, chunk2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence trimLastChar(@NotNull CharSequence text) {
|
||||
return new CharSequenceSubSequence(text, 0, text.length() - 1);
|
||||
assertEqualsCharSequences(chunk1, chunk2, ignoreSpaces, skipNewline);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -383,12 +353,6 @@ public class ComparisonUtilAutoTest extends AutoTestCase {
|
||||
return map;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String normalize(@Nullable Document text) {
|
||||
if (text == null) return "null";
|
||||
return "'" + text.getCharsSequence().toString().replace('\n', '*').replace('\t', '+') + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static CharSequence subsequence(@NotNull Document document, int start, int end) {
|
||||
return document.getCharsSequence().subSequence(start, end);
|
||||
|
||||
+216
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.diff.tools.fragmented;
|
||||
|
||||
import com.intellij.diff.comparison.AutoTestCase;
|
||||
import com.intellij.diff.comparison.ComparisonManager;
|
||||
import com.intellij.diff.comparison.ComparisonManagerImpl;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class OnesideFragmentBuilderAutoTest extends AutoTestCase {
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
private static final int CHAR_COUNT = 12;
|
||||
private static final Map<Integer, Character> CHAR_TABLE = initCharMap();
|
||||
|
||||
public void test() throws Exception {
|
||||
doTest(System.currentTimeMillis(), 30, 30);
|
||||
}
|
||||
|
||||
public void doTest(long seed, int runs, int maxLength) throws Exception {
|
||||
myRng.setSeed(seed);
|
||||
|
||||
ComparisonPolicy policy = null;
|
||||
Side masterSide = null;
|
||||
|
||||
for (int i = 0; i < runs; i++) {
|
||||
if (i % 1000 == 0) System.out.println(i);
|
||||
Document text1 = null;
|
||||
Document text2 = null;
|
||||
try {
|
||||
rememberSeed();
|
||||
|
||||
text1 = generateText(maxLength);
|
||||
text2 = generateText(maxLength);
|
||||
|
||||
for (Side side : Side.values()) {
|
||||
for (ComparisonPolicy comparisonPolicy : ComparisonPolicy.values()) {
|
||||
policy = comparisonPolicy;
|
||||
masterSide = side;
|
||||
doTest(text1, text2, policy, masterSide);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Throwable e) {
|
||||
System.out.println("Seed: " + seed);
|
||||
System.out.println("Runs: " + runs);
|
||||
System.out.println("MaxLength: " + maxLength);
|
||||
System.out.println("Policy: " + policy);
|
||||
System.out.println("Current side: " + masterSide);
|
||||
System.out.println("I: " + i);
|
||||
System.out.println("Current seed: " + getLastSeed());
|
||||
System.out.println("Text1: " + textToReadableFormat(text1));
|
||||
System.out.println("Text2: " + textToReadableFormat(text2));
|
||||
if (e instanceof Error) throw (Error)e;
|
||||
if (e instanceof Exception) throw (Exception)e;
|
||||
throw new Exception(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void doTest(@NotNull Document document1, @NotNull Document document2, @NotNull ComparisonPolicy policy, @NotNull Side masterSide) {
|
||||
CharSequence sequence1 = document1.getCharsSequence();
|
||||
CharSequence sequence2 = document2.getCharsSequence();
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(sequence1, sequence2,
|
||||
policy, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, masterSide);
|
||||
builder.exec();
|
||||
|
||||
boolean ignoreWhitespaces = policy != ComparisonPolicy.DEFAULT;
|
||||
CharSequence text = builder.getText();
|
||||
List<ChangedBlock> blocks = builder.getBlocks();
|
||||
LineNumberConvertor convertor = builder.getConvertor();
|
||||
List<DiffIterableUtil.IntPair> changedLines = builder.getChangedLines();
|
||||
List<HighlightRange> ranges = builder.getRanges();
|
||||
|
||||
// both documents - before and after - should be subsequence of result text.
|
||||
assertTrue(isSubsequence(text, sequence1, ignoreWhitespaces));
|
||||
assertTrue(isSubsequence(text, sequence2, ignoreWhitespaces));
|
||||
|
||||
// all changes should be inside ChangedLines
|
||||
for (LineFragment fragment : fragments) {
|
||||
int startLine1 = fragment.getStartLine1();
|
||||
int endLine1 = fragment.getEndLine1();
|
||||
int startLine2 = fragment.getStartLine2();
|
||||
int endLine2 = fragment.getEndLine2();
|
||||
|
||||
for (int i = startLine1; i < endLine1; i++) {
|
||||
int targetLine = convertor.convertInv1(i);
|
||||
assertTrue(targetLine != -1);
|
||||
assertTrue(isLineChanged(targetLine, changedLines));
|
||||
}
|
||||
for (int i = startLine2; i < endLine2; i++) {
|
||||
int targetLine = convertor.convertInv2(i);
|
||||
assertTrue(targetLine != -1);
|
||||
assertTrue(isLineChanged(targetLine, changedLines));
|
||||
}
|
||||
}
|
||||
|
||||
// changed fragments and changed blocks should have same content
|
||||
assertEquals(blocks.size(), fragments.size());
|
||||
for (int i = 0; i < fragments.size(); i++) {
|
||||
LineFragment fragment = fragments.get(i);
|
||||
ChangedBlock block = blocks.get(i);
|
||||
|
||||
CharSequence fragment1 = sequence1.subSequence(fragment.getStartOffset1(), fragment.getEndOffset1());
|
||||
CharSequence fragment2 = sequence2.subSequence(fragment.getStartOffset2(), fragment.getEndOffset2());
|
||||
|
||||
CharSequence block1 = text.subSequence(block.getStartOffset1(), block.getEndOffset1());
|
||||
CharSequence block2 = text.subSequence(block.getStartOffset2(), block.getEndOffset2());
|
||||
|
||||
assertEqualsCharSequences(fragment1, block1, ignoreWhitespaces, true);
|
||||
assertEqualsCharSequences(fragment2, block2, ignoreWhitespaces, true);
|
||||
}
|
||||
|
||||
// ranges should have exact same content
|
||||
for (HighlightRange range : ranges) {
|
||||
CharSequence sideSequence = range.getSide().select(sequence1, sequence2);
|
||||
CharSequence baseRange = text.subSequence(range.getBase().getStartOffset(), range.getBase().getEndOffset());
|
||||
CharSequence sideRange = sideSequence.subSequence(range.getChanged().getStartOffset(), range.getChanged().getEndOffset());
|
||||
assertTrue(StringUtil.equals(baseRange, sideRange));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isSubsequence(@NotNull CharSequence text, @NotNull CharSequence sequence, boolean ignoreWhitespaces) {
|
||||
int index1 = 0;
|
||||
int index2 = 0;
|
||||
|
||||
while (index2 < sequence.length()) {
|
||||
char c2 = sequence.charAt(index2);
|
||||
if (c2 == '\n' ||
|
||||
StringUtil.isWhiteSpace(c2) && ignoreWhitespaces) {
|
||||
index2++;
|
||||
continue;
|
||||
}
|
||||
|
||||
assertTrue(index1 < text.length());
|
||||
char c1 = text.charAt(index1);
|
||||
if (c1 == '\n' ||
|
||||
StringUtil.isWhiteSpace(c1) && ignoreWhitespaces) {
|
||||
index1++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (c1 == c2) {
|
||||
index1++;
|
||||
index2++;
|
||||
}
|
||||
else {
|
||||
index1++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isLineChanged(int line, @NotNull List<DiffIterableUtil.IntPair> changedLines) {
|
||||
for (DiffIterableUtil.IntPair changedLine : changedLines) {
|
||||
if (changedLine.val1 <= line && changedLine.val2 > line) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Document generateText(int maxLength) {
|
||||
return new DocumentImpl(generateText(maxLength, CHAR_COUNT, CHAR_TABLE));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<Integer, Character> initCharMap() {
|
||||
Map<Integer, Character> map = new HashMap<Integer, Character>();
|
||||
|
||||
List<Character> characters = new ArrayList<Character>();
|
||||
characters.add('\n');
|
||||
characters.add('\n');
|
||||
characters.add('\t');
|
||||
characters.add(' ');
|
||||
characters.add(' ');
|
||||
characters.add('.');
|
||||
characters.add('<');
|
||||
characters.add('!');
|
||||
|
||||
for (int i = 0; i < characters.size(); i++) {
|
||||
map.put(i, characters.get(i));
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.diff.tools.fragmented;
|
||||
|
||||
import com.intellij.diff.comparison.ComparisonManager;
|
||||
import com.intellij.diff.comparison.ComparisonManagerImpl;
|
||||
import com.intellij.diff.comparison.ComparisonPolicy;
|
||||
import com.intellij.diff.comparison.iterables.DiffIterableUtil;
|
||||
import com.intellij.diff.fragments.LineFragment;
|
||||
import com.intellij.diff.util.Side;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.impl.DocumentImpl;
|
||||
import com.intellij.openapi.progress.DumbProgressIndicator;
|
||||
import com.intellij.testFramework.UsefulTestCase;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class OnesideFragmentBuilderTest extends UsefulTestCase {
|
||||
private static ComparisonManager myComparisonManager = new ComparisonManagerImpl();
|
||||
|
||||
public void testEquals() {
|
||||
Document document1 = new DocumentImpl("A\nB\nC");
|
||||
Document document2 = new DocumentImpl("A\nB\nC");
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(document1.getCharsSequence(), document2.getCharsSequence(),
|
||||
ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, Side.LEFT);
|
||||
builder.exec();
|
||||
|
||||
assertTrue(builder.isEqual());
|
||||
assertEquals(builder.getText().toString(), "A\nB\nC\n");
|
||||
assertEmpty(builder.getChangedLines());
|
||||
assertEmpty(builder.getBlocks());
|
||||
}
|
||||
|
||||
public void testWrongEndLineTypoBug() {
|
||||
Document document1 = new DocumentImpl("A\nB\nC\nD");
|
||||
Document document2 = new DocumentImpl("A\nD");
|
||||
|
||||
List<LineFragment> fragments = myComparisonManager.compareLinesInner(document1.getCharsSequence(), document2.getCharsSequence(),
|
||||
ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE);
|
||||
|
||||
OnesideFragmentBuilder builder = new OnesideFragmentBuilder(fragments, document1, document2, true, Side.RIGHT);
|
||||
builder.exec();
|
||||
|
||||
assertFalse(builder.isEqual());
|
||||
assertEquals(builder.getText().toString(), "A\nB\nC\nD\n");
|
||||
assertEquals(builder.getChangedLines(), Collections.singletonList(new DiffIterableUtil.IntPair(1, 3)));
|
||||
|
||||
assertEquals(builder.getBlocks().size(), 1);
|
||||
ChangedBlock block = builder.getBlocks().get(0);
|
||||
assertEquals(block.getLine1(), 1);
|
||||
assertEquals(block.getLine2(), 3);
|
||||
assertEquals(block.getStartOffset1(), 2);
|
||||
assertEquals(block.getEndOffset1(), 6);
|
||||
assertEquals(block.getStartOffset2(), 6);
|
||||
assertEquals(block.getEndOffset2(), 6);
|
||||
}
|
||||
}
|
||||
+26
-30
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -22,12 +22,14 @@ import com.intellij.execution.runners.ProgramRunner;
|
||||
import com.intellij.openapi.options.SettingsEditor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.InvalidDataException;
|
||||
import com.intellij.openapi.util.JDOMExternalizerUtil;
|
||||
import com.intellij.openapi.util.UserDataHolderBase;
|
||||
import com.intellij.openapi.util.WriteExternalException;
|
||||
import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
|
||||
import com.intellij.util.xmlb.XmlSerializer;
|
||||
import com.intellij.util.xmlb.annotations.Attribute;
|
||||
import com.intellij.util.xmlb.annotations.Transient;
|
||||
import org.jdom.Element;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -40,24 +42,22 @@ import java.util.List;
|
||||
*
|
||||
* @author dyoma
|
||||
*/
|
||||
public abstract class RunConfigurationBase extends UserDataHolderBase
|
||||
implements RunConfiguration, TargetAwareRunProfile {
|
||||
public abstract class RunConfigurationBase extends UserDataHolderBase implements RunConfiguration, TargetAwareRunProfile {
|
||||
private static final String LOG_FILE = "log_file";
|
||||
private static final String PREDEFINED_LOG_FILE_ELEMENT = "predefined_log_file";
|
||||
private static final String FILE_OUTPUT = "output_file";
|
||||
private static final String SAVE = "is_save";
|
||||
private static final String OUTPUT_FILE = "path";
|
||||
private static final String SHOW_CONSOLE_ON_STD_OUT = "show_console_on_std_out";
|
||||
private static final String SHOW_CONSOLE_ON_STD_ERR = "show_console_on_std_err";
|
||||
|
||||
private final ConfigurationFactory myFactory;
|
||||
private final Project myProject;
|
||||
private String myName = "";
|
||||
private final Icon myIcon;
|
||||
|
||||
private ArrayList<LogFileOptions> myLogFiles = new ArrayList<LogFileOptions>();
|
||||
private ArrayList<PredefinedLogFile> myPredefinedLogFiles = new ArrayList<PredefinedLogFile>();
|
||||
|
||||
@NonNls private static final String LOG_FILE = "log_file";
|
||||
@NonNls private static final String PREDEFINED_LOG_FILE_ELEMENT = "predefined_log_file";
|
||||
@NonNls private static final String FILE_OUTPUT = "output_file";
|
||||
@NonNls private static final String SAVE = "is_save";
|
||||
@NonNls private static final String OUTPUT_FILE = "path";
|
||||
@NonNls private static final String SHOW_CONSOLE_ON_STD_OUT = "show_console_on_std_out";
|
||||
@NonNls private static final String SHOW_CONSOLE_ON_STD_ERR = "show_console_on_std_err";
|
||||
|
||||
private final Icon myIcon;
|
||||
private boolean mySaveOutput = false;
|
||||
private boolean myShowConsoleOnStdOut = false;
|
||||
private boolean myShowConsoleOnStdErr = false;
|
||||
@@ -111,7 +111,8 @@ public abstract class RunConfigurationBase extends UserDataHolderBase
|
||||
return super.hashCode();
|
||||
}
|
||||
|
||||
public void checkRunnerSettings(@NotNull ProgramRunner runner, @Nullable RunnerSettings runnerSettings,
|
||||
public void checkRunnerSettings(@NotNull ProgramRunner runner,
|
||||
@Nullable RunnerSettings runnerSettings,
|
||||
@Nullable ConfigurationPerRunnerSettings configurationPerRunnerSettings) throws RuntimeConfigurationException {
|
||||
}
|
||||
|
||||
@@ -223,22 +224,17 @@ public abstract class RunConfigurationBase extends UserDataHolderBase
|
||||
|
||||
@Override
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
for (final LogFileOptions options : myLogFiles) {
|
||||
Element logFile = new Element(LOG_FILE);
|
||||
options.writeExternal(logFile);
|
||||
element.addContent(logFile);
|
||||
}
|
||||
for (PredefinedLogFile predefinedLogFile : myPredefinedLogFiles) {
|
||||
Element fileElement = new Element(PREDEFINED_LOG_FILE_ELEMENT);
|
||||
predefinedLogFile.writeExternal(fileElement);
|
||||
element.addContent(fileElement);
|
||||
}
|
||||
final Element fileOutputPathElement = new Element(FILE_OUTPUT);
|
||||
if (myFileOutputPath != null) {
|
||||
fileOutputPathElement.setAttribute(OUTPUT_FILE, myFileOutputPath);
|
||||
}
|
||||
fileOutputPathElement.setAttribute(SAVE, String.valueOf(mySaveOutput));
|
||||
JDOMExternalizerUtil.addChildren(element, LOG_FILE, myLogFiles);
|
||||
JDOMExternalizerUtil.addChildren(element, PREDEFINED_LOG_FILE_ELEMENT, myPredefinedLogFiles);
|
||||
|
||||
if (myFileOutputPath != null || mySaveOutput) {
|
||||
Element fileOutputPathElement = new Element(FILE_OUTPUT);
|
||||
if (myFileOutputPath != null) {
|
||||
fileOutputPathElement.setAttribute(OUTPUT_FILE, myFileOutputPath);
|
||||
}
|
||||
if (mySaveOutput) {
|
||||
fileOutputPathElement.setAttribute(SAVE, String.valueOf(mySaveOutput));
|
||||
}
|
||||
element.addContent(fileOutputPathElement);
|
||||
}
|
||||
|
||||
|
||||
+8
-1
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.intellij.lang.documentation;
|
||||
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -190,7 +191,7 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
|
||||
if (((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement)) return true;
|
||||
}
|
||||
else {
|
||||
if (hasUrlsFor(provider, element, originalElement)) return true;
|
||||
if (hasBrowsableUrlsFor(provider, element, originalElement)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@@ -224,6 +225,12 @@ public class CompositeDocumentationProvider extends DocumentationProviderEx impl
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasBrowsableUrlsFor(DocumentationProvider provider, PsiElement element, PsiElement originalElement) {
|
||||
final List<String> urls = BrowserUtil.retainBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
if (urls != null && !urls.isEmpty()) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement getCustomDocumentationElement(@NotNull Editor editor,
|
||||
|
||||
+4
-2
@@ -31,8 +31,10 @@ public interface ExternalDocumentationProvider {
|
||||
String fetchExternalDocumentation(final Project project, PsiElement element, final List<String> docUrls);
|
||||
|
||||
/**
|
||||
* Quick check for existence of external documentation for specified element. Called from action update, so must be fast.
|
||||
* If not implemented, update check is performed by calling {@link DocumentationProvider#getUrlFor(com.intellij.psi.PsiElement, com.intellij.psi.PsiElement)}.
|
||||
* Quick check for existence of external documentation for specified element which can be displayed in external browser.
|
||||
* Called from action update, so must be fast. If not implemented, update check is performed by calling
|
||||
* {@link DocumentationProvider#getUrlFor(PsiElement, PsiElement)} and retaining only 'browsable' urls
|
||||
* (see {@link com.intellij.ide.BrowserUtil#canBeBrowsed(String)}).
|
||||
*
|
||||
* @param element the element to check for existence of documentation
|
||||
* @param originalElement the element at caret (on which the action was invoked)
|
||||
|
||||
@@ -98,8 +98,12 @@ public class JdkUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean checkForJdk(@NotNull String homePath) {
|
||||
return checkForJdk(new File(FileUtil.toSystemDependentName(homePath)));
|
||||
}
|
||||
|
||||
public static boolean checkForJdk(@NotNull File homePath) {
|
||||
File binPath = new File(homePath.getAbsolutePath() + File.separator + "bin");
|
||||
File binPath = new File(homePath, "bin");
|
||||
if (!binPath.exists()) return false;
|
||||
|
||||
FileFilter fileFilter = new FileFilter() {
|
||||
@@ -117,8 +121,11 @@ public class JdkUtil {
|
||||
}
|
||||
|
||||
public static boolean checkForJre(@NotNull String homePath) {
|
||||
homePath = new File(FileUtil.toSystemDependentName(homePath)).getAbsolutePath();
|
||||
File binPath = new File(homePath + File.separator + "bin");
|
||||
return checkForJre(new File(FileUtil.toSystemDependentName(homePath)));
|
||||
}
|
||||
|
||||
public static boolean checkForJre(@NotNull File homePath) {
|
||||
File binPath = new File(homePath, "bin");
|
||||
if (!binPath.exists()) return false;
|
||||
|
||||
FileFilter fileFilter = new FileFilter() {
|
||||
@@ -130,7 +137,7 @@ public class JdkUtil {
|
||||
File[] children = binPath.listFiles(fileFilter);
|
||||
|
||||
return children != null && children.length >= 1 &&
|
||||
checkForRuntime(homePath);
|
||||
checkForRuntime(homePath.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static boolean checkForRuntime(@NotNull String homePath) {
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.impl.EditorFactoryImpl;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.module.ModifiableModuleModel;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleManager;
|
||||
@@ -38,7 +37,6 @@ import com.intellij.openapi.vcs.ex.LineStatusTracker;
|
||||
import com.intellij.openapi.vcs.ex.Range;
|
||||
import com.intellij.openapi.vcs.ex.RangesBuilder;
|
||||
import com.intellij.openapi.vcs.impl.LineStatusTrackerManager;
|
||||
import com.intellij.openapi.vcs.impl.LineStatusTrackerManagerI;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
@@ -51,7 +49,8 @@ import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class FormatChangedTextUtil {
|
||||
public static final Key<CharSequence> TEST_REVISION_CONTENT = Key.create("test.revision.content");
|
||||
@@ -158,52 +157,6 @@ public class FormatChangedTextUtil {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to ask for the changed text of the given file (in comparison with VCS).
|
||||
*
|
||||
* @param file target file
|
||||
* @return collection of changed regions for the given file
|
||||
*/
|
||||
@NotNull
|
||||
public static Collection<TextRange> getChanges(@NotNull PsiFile file) {
|
||||
final Set<TextRange> defaultResult = Collections.singleton(file.getTextRange());
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final Change change = ChangeListManager.getInstance(file.getProject()).getChange(virtualFile);
|
||||
if (change != null && change.getType() == Change.Type.NEW) {
|
||||
return defaultResult;
|
||||
}
|
||||
}
|
||||
|
||||
final LineStatusTrackerManagerI manager = LineStatusTrackerManager.getInstance(file.getProject());
|
||||
if (manager == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
if (document == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final LineStatusTracker lineStatusTracker = manager.getLineStatusTracker(document);
|
||||
if (lineStatusTracker == null) {
|
||||
return defaultResult;
|
||||
}
|
||||
final List<Range> ranges = lineStatusTracker.getRanges();
|
||||
if (ranges == null || ranges.isEmpty()) {
|
||||
return defaultResult;
|
||||
}
|
||||
|
||||
List<TextRange> result = new ArrayList<TextRange>();
|
||||
for (Range range : ranges) {
|
||||
if (range.getType() != Range.DELETED) {
|
||||
final RangeHighlighter highlighter = range.getHighlighter();
|
||||
if (highlighter != null) {
|
||||
result.add(new TextRange(highlighter.getStartOffset(), highlighter.getEndOffset()));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static List<PsiFile> getChangedFilesFromDirs(@NotNull Project project, @NotNull List<PsiDirectory> dirs) {
|
||||
ChangeListManager changeListManager = ChangeListManager.getInstance(project);
|
||||
|
||||
@@ -54,7 +54,7 @@ public class ReformatCodeProcessor extends AbstractLayoutCodeProcessor {
|
||||
}
|
||||
|
||||
public ReformatCodeProcessor(@NotNull PsiFile file, @NotNull SelectionModel selectionModel) {
|
||||
super(file.getProject(), file, COMMAND_NAME, PROGRESS_TEXT, false);
|
||||
super(file.getProject(), file, PROGRESS_TEXT, COMMAND_NAME, false);
|
||||
mySelectionModel = selectionModel;
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.hint.ElementLocationUtil;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.actions.BaseNavigateToSourceAction;
|
||||
import com.intellij.ide.actions.ExternalJavaDocAction;
|
||||
@@ -696,7 +697,6 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ExternalDocAction extends AnAction implements HintManagerImpl.ActionToIgnore {
|
||||
public ExternalDocAction() {
|
||||
super(CodeInsightBundle.message("javadoc.action.view.external"), null, AllIcons.Actions.Browser_externalJavaDoc);
|
||||
@@ -722,10 +722,10 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
if (!processed) {
|
||||
final Component component = PlatformDataKeys.CONTEXT_COMPONENT.getData(e.getDataContext());
|
||||
final List<String> urls;
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl)) {
|
||||
if (!StringUtil.isEmptyOrSpaces(myEffectiveExternalUrl) && BrowserUtil.canBeBrowsed(myEffectiveExternalUrl)) {
|
||||
urls = Collections.singletonList(myEffectiveExternalUrl);
|
||||
} else {
|
||||
urls = provider.getUrlFor(element, originalElement);
|
||||
urls = BrowserUtil.retainBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
assert urls != null : provider;
|
||||
assert !urls.isEmpty() : provider;
|
||||
}
|
||||
@@ -746,7 +746,7 @@ public class DocumentationComponent extends JPanel implements Disposable, DataPr
|
||||
presentation.setEnabled(element != null && ((ExternalDocumentationProvider)provider).hasDocumentationFor(element, originalElement));
|
||||
}
|
||||
else {
|
||||
final List<String> urls = provider.getUrlFor(element, originalElement);
|
||||
List<String> urls = BrowserUtil.retainBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
presentation.setEnabled(element != null && urls != null && !urls.isEmpty());
|
||||
}
|
||||
}
|
||||
|
||||
+1
-4
@@ -1080,10 +1080,7 @@ public class DocumentationManager extends DockablePopupManager<DocumentationComp
|
||||
public List<String> compute() {
|
||||
final SmartPsiElementPointer originalElementPtr = myElement.getUserData(ORIGINAL_ELEMENT_KEY);
|
||||
final PsiElement originalElement = originalElementPtr != null ? originalElementPtr.getElement() : null;
|
||||
if (((ExternalDocumentationProvider)provider).hasDocumentationFor(myElement, originalElement)) {
|
||||
return provider.getUrlFor(myElement, originalElement);
|
||||
}
|
||||
return null;
|
||||
return provider.getUrlFor(myElement, originalElement);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
+5
@@ -148,6 +148,11 @@ public class ShowImplementationsAction extends AnAction implements PopupAction {
|
||||
}
|
||||
}
|
||||
|
||||
//check attached sources if any
|
||||
if (element instanceof PsiCompiledElement) {
|
||||
element = element.getNavigationElement();
|
||||
}
|
||||
|
||||
String text = "";
|
||||
PsiElement[] impls = new PsiElement[0];
|
||||
if (element != null) {
|
||||
|
||||
@@ -498,6 +498,19 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds transparent (actually, non-opaque) component over console.
|
||||
* It will be as big as console. Use it to draw on console because it does not prevent user from console usage.
|
||||
*
|
||||
* @param component component to add
|
||||
*/
|
||||
public final void addLayerToPane(@NotNull final JComponent component) {
|
||||
getComponent(); // Make sure component exists
|
||||
component.setOpaque(false);
|
||||
component.setVisible(true);
|
||||
myJLayeredPane.add(component, 0);
|
||||
}
|
||||
|
||||
protected void initConsoleEditor() {
|
||||
myEditor = createConsoleEditor();
|
||||
registerConsoleEditorActions();
|
||||
|
||||
@@ -60,6 +60,7 @@ import java.util.List;
|
||||
|
||||
public class ExecutionManagerImpl extends ExecutionManager implements Disposable {
|
||||
public static final Key<Object> EXECUTION_SESSION_ID_KEY = Key.create("EXECUTION_SESSION_ID_KEY");
|
||||
public static final Key<Boolean> EXECUTION_SKIP_RUN = Key.create("EXECUTION_SKIP_RUN");
|
||||
|
||||
private static final Logger LOG = Logger.getInstance(ExecutionManagerImpl.class);
|
||||
private static final ProcessHandler[] EMPTY_PROCESS_HANDLERS = new ProcessHandler[0];
|
||||
@@ -169,17 +170,24 @@ public class ExecutionManagerImpl extends ExecutionManager implements Disposable
|
||||
}
|
||||
|
||||
protected void doRun(@NotNull final ExecutionEnvironment environment, @NotNull final Runnable startRunnable) {
|
||||
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
|
||||
// and execution of startRunnable could be skipped if modality state check fails
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myProject.isDisposed()) {
|
||||
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
|
||||
Boolean allowSkipRun = environment.getUserData(EXECUTION_SKIP_RUN);
|
||||
if (allowSkipRun != null && allowSkipRun) {
|
||||
environment.getProject().getMessageBus().syncPublisher(EXECUTION_TOPIC).processNotStarted(environment.getExecutor().getId(),
|
||||
environment);
|
||||
}
|
||||
else {
|
||||
// important! Do not use DumbService.smartInvokeLater here because it depends on modality state
|
||||
// and execution of startRunnable could be skipped if modality state check fails
|
||||
//noinspection SSBasedInspection
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!myProject.isDisposed()) {
|
||||
DumbService.getInstance(myProject).runWhenSmart(startRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -74,8 +74,12 @@ public class MyDiffContainer extends JBLayeredPane implements Disposable {
|
||||
private class MyOverlayLayout extends AbstractLayoutManager {
|
||||
@Override
|
||||
public void layoutContainer(Container parent) {
|
||||
myContent.setBounds(0, 0, getWidth(), getHeight());
|
||||
myLoadingPanel.setBounds(0, 0, getWidth(), getHeight());
|
||||
/**
|
||||
* Propogate bound to all children
|
||||
*/
|
||||
for(int i = 0; i< getComponentCount(); i++) {
|
||||
getComponent(i).setBounds(0, 0, getWidth(), getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+64
-60
@@ -31,6 +31,7 @@ import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
@@ -193,75 +194,78 @@ extends BeforeRunTaskProvider<RunConfigurationBeforeRunProvider.RunConfigurableB
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return doRun(executorId, environment);
|
||||
}
|
||||
}
|
||||
beforeRun(environment);
|
||||
|
||||
protected boolean doRun(@NotNull final String executorId, @NotNull final ExecutionEnvironment environment) {
|
||||
final Semaphore targetDone = new Semaphore();
|
||||
final Ref<Boolean> result = new Ref<Boolean>(false);
|
||||
final Disposable disposable = Disposer.newDisposable();
|
||||
final Semaphore targetDone = new Semaphore();
|
||||
final Ref<Boolean> result = new Ref<Boolean>(false);
|
||||
final Disposable disposable = Disposer.newDisposable();
|
||||
|
||||
myProject.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
|
||||
@Override
|
||||
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
targetDone.down();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
onProcessNotStarted(environment, result, targetDone);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processStarted(final String executorIdLocal,
|
||||
@NotNull final ExecutionEnvironment environmentLocal,
|
||||
@NotNull final ProcessHandler handler) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
handler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
result.set(event.getExitCode() == 0);
|
||||
targetDone.up();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
|
||||
myProject.getMessageBus().connect(disposable).subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
environment.getRunner().execute(environment);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
targetDone.up();
|
||||
LOG.error(e);
|
||||
public void processStartScheduled(final String executorIdLocal, final ExecutionEnvironment environmentLocal) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
targetDone.down();
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
|
||||
@Override
|
||||
public void processNotStarted(final String executorIdLocal, @NotNull final ExecutionEnvironment environmentLocal) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
Boolean skipRun = environment.getUserData(ExecutionManagerImpl.EXECUTION_SKIP_RUN);
|
||||
if (skipRun != null && skipRun) {
|
||||
result.set(true);
|
||||
}
|
||||
targetDone.up();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processStarted(final String executorIdLocal,
|
||||
@NotNull final ExecutionEnvironment environmentLocal,
|
||||
@NotNull final ProcessHandler handler) {
|
||||
if (executorId.equals(executorIdLocal) && environment.equals(environmentLocal)) {
|
||||
handler.addProcessListener(new ProcessAdapter() {
|
||||
@Override
|
||||
public void processTerminated(ProcessEvent event) {
|
||||
result.set(event.getExitCode() == 0);
|
||||
targetDone.up();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
ApplicationManager.getApplication().invokeAndWait(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
environment.getRunner().execute(environment);
|
||||
}
|
||||
catch (ExecutionException e) {
|
||||
targetDone.up();
|
||||
LOG.error(e);
|
||||
}
|
||||
}
|
||||
}, ModalityState.NON_MODAL);
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.error(e);
|
||||
Disposer.dispose(disposable);
|
||||
return false;
|
||||
}
|
||||
|
||||
targetDone.waitFor();
|
||||
Disposer.dispose(disposable);
|
||||
return false;
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
targetDone.waitFor();
|
||||
Disposer.dispose(disposable);
|
||||
|
||||
return result.get();
|
||||
}
|
||||
|
||||
protected void onProcessNotStarted(@NotNull ExecutionEnvironment environment, @NotNull Ref<Boolean> result,
|
||||
@NotNull Semaphore targetDone) {
|
||||
targetDone.up();
|
||||
private static void beforeRun(@NotNull ExecutionEnvironment environment) {
|
||||
for (RunConfigurationBeforeRunProviderDelegate delegate : Extensions.getExtensions(RunConfigurationBeforeRunProviderDelegate.EP_NAME)) {
|
||||
delegate.beforeRun(environment);
|
||||
}
|
||||
}
|
||||
|
||||
public class RunConfigurableBeforeRunTask extends BeforeRunTask<RunConfigurableBeforeRunTask> {
|
||||
|
||||
+9
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -13,18 +13,14 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.debugger.actions;
|
||||
package com.intellij.execution.impl;
|
||||
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.execution.runners.ExecutionEnvironment;
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class StepOutActionHandler extends AbstractSteppingActionHandler {
|
||||
public void perform(@NotNull final Project project, AnActionEvent e) {
|
||||
final DebuggerSession session = getSession(project);
|
||||
if (session != null) {
|
||||
session.stepOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
public interface RunConfigurationBeforeRunProviderDelegate {
|
||||
ExtensionPointName<RunConfigurationBeforeRunProviderDelegate> EP_NAME = ExtensionPointName.create("com.intellij.runConfigurationBeforeRunProviderDelegate");
|
||||
|
||||
void beforeRun(@NotNull ExecutionEnvironment environment);
|
||||
}
|
||||
@@ -406,7 +406,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
|
||||
balloonBuilder.setCloseButtonEnabled(true);
|
||||
myReplacementBalloon = balloonBuilder.createBalloon();
|
||||
|
||||
myReplacementBalloon.show(new ReplacementBalloonPositionTracker(editor), Balloon.Position.above);
|
||||
myReplacementBalloon.show(new ReplacementBalloonPositionTracker(editor), Balloon.Position.below);
|
||||
}
|
||||
|
||||
private void hideBalloon() {
|
||||
@@ -534,7 +534,7 @@ public class LivePreview extends DocumentAdapter implements SearchResults.Search
|
||||
|
||||
Point startPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(startOffset));
|
||||
Point endPoint = myEditor.visualPositionToXY(myEditor.offsetToVisualPosition(endOffset));
|
||||
Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y);
|
||||
Point point = new Point((startPoint.x + endPoint.x)/2, startPoint.y + myEditor.getLineHeight());
|
||||
|
||||
return new RelativePoint(myEditor.getContentComponent(), point);
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ExternalJavaDocAction extends AnAction {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<String> urls = provider.getUrlFor(element, originalElement);
|
||||
final List<String> urls = BrowserUtil.retainBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
if (urls != null && !urls.isEmpty()) {
|
||||
showExternalJavadoc(urls, PlatformDataKeys.CONTEXT_COMPONENT.getData(dataContext));
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class ExternalJavaDocAction extends AnAction {
|
||||
enabled = edProvider.hasDocumentationFor(element, originalElement) || edProvider.canPromptToConfigureDocumentation(element);
|
||||
}
|
||||
else {
|
||||
final List<String> urls = provider.getUrlFor(element, originalElement);
|
||||
final List<String> urls = BrowserUtil.retainBrowsableUrls(provider.getUrlFor(element, originalElement));
|
||||
enabled = urls != null && !urls.isEmpty();
|
||||
}
|
||||
if (editor != null) {
|
||||
|
||||
+1
-1
@@ -265,7 +265,7 @@ public class ProjectSettingsStepBase extends AbstractActionWithPanel implements
|
||||
final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
|
||||
myLocationField.addBrowseFolderListener("Select base directory", "Select base directory for the Project",
|
||||
null, descriptor);
|
||||
return LabeledComponent.create(myLocationField, "Location");
|
||||
return LabeledComponent.create(myLocationField, "&Location");
|
||||
}
|
||||
|
||||
private static File findSequentNonExistingUntitled() {
|
||||
|
||||
+1
-1
@@ -180,7 +180,7 @@ public class GithubProjectGeneratorPeer implements WebProjectGenerator.Generator
|
||||
|
||||
@Override
|
||||
public void buildUI(@NotNull SettingsStep settingsStep) {
|
||||
settingsStep.addSettingsField("\u001BVersion:", myVersionPanel);
|
||||
settingsStep.addSettingsField("&Version:", myVersionPanel);
|
||||
settingsStep.addSettingsComponent(myReloadableComboBoxPanel.getErrorComponent());
|
||||
}
|
||||
|
||||
|
||||
@@ -115,6 +115,8 @@ public class ClasspathStorage extends StateStorageBase<ClasspathStorage.MyStorag
|
||||
ModifiableRootModel model = null;
|
||||
try {
|
||||
model = ((ModuleRootManagerImpl)component).getModifiableModel();
|
||||
// IDEA-137969 Eclipse integration: external remove of classpathentry is not synchronized
|
||||
model.clear();
|
||||
myConverter.readClasspath(model);
|
||||
((RootModelImpl)model).writeExternal(element);
|
||||
}
|
||||
|
||||
+10
-3
@@ -43,6 +43,7 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio
|
||||
private static final Key<EditorNotificationPanel> KEY = Key.create("indent.options.notification.provider");
|
||||
private static final Key<Boolean> NOTIFIED_FLAG = Key.create("indent.options.notification.provider.status");
|
||||
protected static final Key<Boolean> DETECT_INDENT_NOTIFICATION_SHOWN_KEY = Key.create("indent.options.notification.provider.status.test.notification.shown");
|
||||
protected static final Key<Boolean> SHOW_NOTIFICATION_IN_TEST = Key.create("indent.options.notification.provider.should.update.notification.in.test");
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@@ -106,13 +107,19 @@ public class DetectedIndentOptionsNotificationProvider extends EditorNotificatio
|
||||
}
|
||||
|
||||
public static void updateIndentNotification(@NotNull PsiFile file, boolean enforce) {
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment() || ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
FileEditor fileEditor = FileEditorManager.getInstance(file.getProject()).getSelectedEditor(file.getVirtualFile());
|
||||
VirtualFile vFile = file.getVirtualFile();
|
||||
if (vFile == null) return;
|
||||
|
||||
if (!ApplicationManager.getApplication().isHeadlessEnvironment()
|
||||
|| ApplicationManager.getApplication().isUnitTestMode()
|
||||
&& vFile.getUserData(SHOW_NOTIFICATION_IN_TEST) != null)
|
||||
{
|
||||
FileEditor fileEditor = FileEditorManager.getInstance(file.getProject()).getSelectedEditor(vFile);
|
||||
if (fileEditor != null) {
|
||||
Boolean notifiedFlag = fileEditor.getUserData(NOTIFIED_FLAG);
|
||||
if (notifiedFlag == null || enforce) {
|
||||
fileEditor.putUserData(NOTIFIED_FLAG, Boolean.TRUE);
|
||||
EditorNotifications.getInstance(file.getProject()).updateNotifications(file.getVirtualFile());
|
||||
EditorNotifications.getInstance(file.getProject()).updateNotifications(vFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +213,11 @@ public class TemplateDataElementType extends IFileElementType implements ITempla
|
||||
return language;
|
||||
}
|
||||
};
|
||||
|
||||
// Since we're already inside a template language PSI that was built regardless of the file size (for whatever reason),
|
||||
// there should also be no file size checks for template data files.
|
||||
SingleRootFileViewProvider.doNotCheckFileSizeLimit(virtualFile);
|
||||
|
||||
return viewProvider.getPsi(language);
|
||||
}
|
||||
|
||||
|
||||
@@ -543,6 +543,7 @@ public abstract class BaseRefactoringProcessor implements Runnable {
|
||||
return;
|
||||
}
|
||||
if (ApplicationManager.getApplication().isWriteAccessAllowed()) {
|
||||
LOG.info(new Exception());
|
||||
DumbService.getInstance(myProject).smartInvokeLater(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user