diff options
Diffstat (limited to 'java/debugger/impl')
46 files changed, 850 insertions, 445 deletions
diff --git a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java index 09be13076ca1..58134d49a138 100644 --- a/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/InstanceFilter.java @@ -94,4 +94,24 @@ public class InstanceFilter implements JDOMExternalizable{ } return cFilters; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + InstanceFilter filter = (InstanceFilter)o; + + if (ID != filter.ID) return false; + if (ENABLED != filter.ENABLED) return false; + + return true; + } + + @Override + public int hashCode() { + int result = (int)(ID ^ (ID >>> 32)); + result = 31 * result + (ENABLED ? 1 : 0); + return result; + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java index d2216191903a..86ddfaa5fc08 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java @@ -123,14 +123,14 @@ public abstract class DebuggerAction extends AnAction { return true; } }; - //listener.installOn(tree); + listener.installOn(tree); final AnAction action = ActionManager.getInstance().getAction(actionName); action.registerCustomShortcutSet(CommonShortcuts.getEditSource(), tree); return new Disposable() { public void dispose() { - //listener.uninstall(tree); + listener.uninstall(tree); action.unregisterCustomShortcutSet(tree); } }; diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java index 01e214091308..e127596ec3b5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/GotoFrameSourceAction.java @@ -15,13 +15,12 @@ */ package com.intellij.debugger.actions; -import com.intellij.debugger.impl.DebuggerContextUtil; +import com.intellij.debugger.SourcePosition; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; /** @@ -38,7 +37,11 @@ public abstract class GotoFrameSourceAction extends DebuggerAction{ if(project == null) return; StackFrameDescriptorImpl stackFrameDescriptor = getStackFrameDescriptor(dataContext); if(stackFrameDescriptor != null) { - DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getFrameProxy()); + //DebuggerContextUtil.setStackFrame(getContextManager(dataContext), stackFrameDescriptor.getFrameProxy()); + SourcePosition sourcePosition = stackFrameDescriptor.getSourcePosition(); + if (sourcePosition != null) { + sourcePosition.navigate(true); + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java index 8904331bfaba..48efa9ac87dc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaSmartStepIntoHandler.java @@ -80,7 +80,8 @@ public class JavaSmartStepIntoHandler extends JvmSmartStepIntoHandler { //noinspection unchecked final List<SmartStepTarget> targets = new OrderedSet<SmartStepTarget>(); - final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(element.getTextOffset()), doc.getLineNumber(element.getTextOffset() + element.getTextLength())); + TextRange textRange = element.getTextRange(); + final Range<Integer> lines = new Range<Integer>(doc.getLineNumber(textRange.getStartOffset()), doc.getLineNumber(textRange.getEndOffset())); final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() { final Stack<PsiMethod> myContextStack = new Stack<PsiMethod>(); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java deleted file mode 100644 index a57211b60ead..000000000000 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ToggleBreakpointEnabledAction.java +++ /dev/null @@ -1,86 +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.DebuggerUtils; -import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointManager; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.Presentation; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiDocumentManager; -import com.intellij.psi.PsiFile; -import org.jetbrains.annotations.Nullable; - -public class ToggleBreakpointEnabledAction extends AnAction { - - public void actionPerformed(AnActionEvent e) { - final Project project = e.getData(CommonDataKeys.PROJECT); - Breakpoint breakpoint = findBreakpoint(project); - if (breakpoint != null) { - final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - breakpointManager.setBreakpointEnabled(breakpoint, !breakpoint.isEnabled()); - } - } - - @Nullable - private static Breakpoint findBreakpoint(final Project project) { - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - if(editor == null) { - return null; - } - BreakpointManager manager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - int offset = editor.getCaretModel().getOffset(); - return manager.findBreakpoint(editor.getDocument(), offset, null); - } - - public void update(AnActionEvent event){ - final Presentation presentation = event.getPresentation(); - Project project = event.getData(CommonDataKeys.PROJECT); - if (project == null) { - presentation.setEnabled(false); - return; - } - - Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor(); - if (editor == null) { - presentation.setEnabled(false); - return; - } - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - if (file == null) { - presentation.setEnabled(false); - return; - } - - if (DebuggerUtils.isBreakpointAware(file)) { - Breakpoint breakpoint = findBreakpoint(project); - if (breakpoint == null) { - presentation.setEnabled(false); - return; - } - presentation.setEnabled(true); - } - else { - presentation.setEnabled(false); - } - } -} diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index 45e2cef4b883..4d77dda4b0ad 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -17,6 +17,7 @@ package com.intellij.debugger.actions; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.EditorTextField; import com.intellij.xdebugger.impl.ui.TextViewer; import com.intellij.xdebugger.impl.ui.tree.actions.XFetchValueActionBase; @@ -33,7 +34,7 @@ public class ViewTextAction extends XFetchValueActionBase { protected void handle(Project project, String value) { final MyDialog dialog = new MyDialog(project); dialog.setTitle("View Text"); - dialog.setText(value); + dialog.setText(StringUtil.unquoteString(value)); dialog.show(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java index 1e3fa9bcd452..50fafaf563cc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/BasicStepMethodFilter.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable; * @author Eugene Zhuravlev * Date: 10/26/13 */ -public class BasicStepMethodFilter implements MethodFilter { +public class BasicStepMethodFilter implements NamedMethodFilter { @NotNull protected final JVMName myDeclaringClassName; @NotNull diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java index 127765ae9b1b..7e64da1a1bff 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/CompoundPositionManager.java @@ -26,6 +26,7 @@ import com.intellij.util.ThreeState; import com.intellij.xdebugger.frame.XStackFrame; import com.sun.jdi.Location; import com.sun.jdi.ReferenceType; +import com.sun.jdi.VMDisconnectedException; import com.sun.jdi.request.ClassPrepareRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -60,6 +61,9 @@ public class CompoundPositionManager extends PositionManagerEx { } catch (NoDataException ignored) { } + catch (VMDisconnectedException e) { + throw e; + } catch (Exception e) { LOG.error(e); } @@ -79,6 +83,9 @@ public class CompoundPositionManager extends PositionManagerEx { } catch (NoDataException ignored) { } + catch (VMDisconnectedException e) { + throw e; + } catch (Exception e) { LOG.error(e); } @@ -98,6 +105,9 @@ public class CompoundPositionManager extends PositionManagerEx { } catch (NoDataException ignored) { } + catch (VMDisconnectedException e) { + throw e; + } catch (Exception e) { LOG.error(e); } @@ -116,6 +126,9 @@ public class CompoundPositionManager extends PositionManagerEx { } catch (NoDataException ignored) { } + catch (VMDisconnectedException e) { + throw e; + } catch (Exception e) { LOG.error(e); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java index 2f41cb2288f1..1db0ed60774e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -40,6 +40,8 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.MessageType; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.util.Pair; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.sun.jdi.InternalException; import com.sun.jdi.ThreadReference; @@ -319,6 +321,12 @@ public class DebugProcessEvents extends DebugProcessImpl { myDebugProcessDispatcher.getMulticaster().processAttached(this); + // breakpoints should be initialized after all processAttached listeners work + XDebugSession session = getSession().getXDebugSession(); + if (session != null) { + session.initBreakpoints(); + } + final String addressDisplayName = DebuggerBundle.getAddressDisplayName(getConnection()); final String transportName = DebuggerBundle.getTransportName(getConnection()); showStatusText(DebuggerBundle.message("status.connected", addressDisplayName, transportName)); @@ -393,8 +401,8 @@ public class DebugProcessEvents extends DebugProcessImpl { getSuspendManager().voteSuspend(suspendContext); if (hint != null) { final MethodFilter methodFilter = hint.getMethodFilter(); - if (methodFilter instanceof BasicStepMethodFilter && !hint.wasStepTargetMethodMatched()) { - final String message = "Method <b>" + ((BasicStepMethodFilter)methodFilter).getMethodName() + "()</b> has not been called"; + if (methodFilter instanceof NamedMethodFilter && !hint.wasStepTargetMethodMatched()) { + final String message = "Method <b>" + ((NamedMethodFilter)methodFilter).getMethodName() + "()</b> has not been called"; XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(message, MessageType.INFO).notify(project); } } @@ -451,7 +459,13 @@ public class DebugProcessEvents extends DebugProcessImpl { if (requestHit && requestor instanceof Breakpoint) { // if requestor is a breakpoint and this breakpoint was hit, no matter its suspend policy - myBreakpointManager.processBreakpointHit((Breakpoint)requestor); + XDebugSession session = getSession().getXDebugSession(); + if (session != null) { + XBreakpoint breakpoint = ((Breakpoint)requestor).getXBreakpoint(); + if (breakpoint != null) { + ((XDebugSessionImpl)session).processDependencies(breakpoint); + } + } } if(!requestHit || resumePreferred) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java index f10491282d0e..613217f93ac2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -1157,7 +1157,12 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb public ArrayReference newInstance(final ArrayType arrayType, final int dimension) throws EvaluateException { - return arrayType.newInstance(dimension); + try { + return arrayType.newInstance(dimension); + } + catch (Exception e) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } } @Override @@ -1264,7 +1269,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb // for this refType and the refType is not visible to the loader. // Attempt to evaluate method with this refType will yield ClassNotLoadedException. // The only way to say for sure whether the class is _visible_ to the given loader, is to use the following API call - return fromLoader == null || fromLoader.visibleClasses().contains(refType); + return fromLoader == null || fromLoader.equals(refType.classLoader()) || fromLoader.visibleClasses().contains(refType); } private static String reformatArrayName(String className) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java index 1050c99a34b1..ad2c881d1336 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java @@ -49,6 +49,8 @@ public class JavaBreakpointHandler extends XBreakpointHandler { if (javaBreakpoint != null) { final Breakpoint bpt = javaBreakpoint; BreakpointManager.addBreakpoint(bpt); + // must use invoke to stay in the current request, + // otherwise dependent breakpoints do not get enabled on not-suspending parents hit myProcess.getManagerThread().invoke(new DebuggerCommandImpl() { @Override protected void action() throws Exception { @@ -62,6 +64,7 @@ public class JavaBreakpointHandler extends XBreakpointHandler { public void unregisterBreakpoint(@NotNull final XBreakpoint breakpoint, boolean temporary) { final Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint); if (javaBreakpoint != null) { + // must use invoke to stay in the current request, see comment in registerBreakpoint myProcess.getManagerThread().invoke(new DebuggerCommandImpl() { @Override protected void action() throws Exception { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java index 166ec95e7aeb..37ee00b94eaf 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -54,6 +54,7 @@ import com.intellij.xdebugger.breakpoints.XBreakpointHandler; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XValueMarkerProvider; +import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.actions.XDebuggerActions; import com.intellij.xdebugger.ui.XDebugTabLayouter; @@ -114,7 +115,7 @@ public class JavaDebugProcess extends XDebugProcess { Breakpoint breakpoint = descriptors.get(0).getFirst(); XBreakpoint xBreakpoint = breakpoint.getXBreakpoint(); if (xBreakpoint != null) { - getSession().breakpointReached(xBreakpoint, null, context); + ((XDebugSessionImpl)getSession()).breakpointReachedNoProcessing(xBreakpoint, context); return; } } @@ -130,9 +131,10 @@ public class JavaDebugProcess extends XDebugProcess { myNodeManager = new NodeManagerImpl(session.getProject(), null) { @Override public DebuggerTreeNodeImpl createNode(final NodeDescriptor descriptor, EvaluationContext evaluationContext) { - ((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext); + // value gathered here is required for correct renderers work. e.g. array renderer + //((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext); final DebuggerTreeNodeImpl node = new DebuggerTreeNodeImpl(null, descriptor); - ((NodeDescriptorImpl)descriptor).updateRepresentation((EvaluationContextImpl)evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); + //((NodeDescriptorImpl)descriptor).updateRepresentation((EvaluationContextImpl)evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); return node; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java index 4104000a0b27..e37576bae8f4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java @@ -20,7 +20,6 @@ import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.EditorTextProvider; import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; @@ -61,6 +60,11 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator { @Nullable XSourcePosition expressionPosition) { myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) { @Override + public Priority getPriority() { + return Priority.NORMAL; + } + + @Override public void threadAction() { WatchItemDescriptor descriptor = new WatchItemDescriptor(myDebugProcess.getProject(), TextWithImportsImpl.fromXExpression( expression)); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java index 5d8f50c2a594..793438ebbe05 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java @@ -18,6 +18,8 @@ package com.intellij.debugger.engine; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; @@ -31,8 +33,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; +import java.util.Collections; +import java.util.Iterator; /** * @author egor @@ -69,7 +72,7 @@ public class JavaExecutionStack extends XExecutionStack { } @NotNull - public ThreadReferenceProxyImpl getThreadProxy() { + ThreadReferenceProxyImpl getThreadProxy() { return myThreadProxy; } @@ -101,6 +104,11 @@ public class JavaExecutionStack extends XExecutionStack { else { myDebugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { @Override + public Priority getPriority() { + return Priority.HIGH; + } + + @Override protected void action() throws Exception { myTopFrame = calcTopFrame(); } @@ -112,46 +120,81 @@ public class JavaExecutionStack extends XExecutionStack { @Override public void computeStackFrames(final int firstFrameIndex, final XStackFrameContainer container) { - myDebugProcess.getManagerThread().schedule(new DebuggerCommandImpl() { + myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) { + @Override + public Priority getPriority() { + return Priority.NORMAL; + } + @Override - protected void action() throws Exception { - boolean showLibraryStackframes = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES; - List<JavaStackFrame> frames = new ArrayList<JavaStackFrame>(); + public void threadAction() { if (!myThreadProxy.isCollected() && myDebugProcess.getSuspendManager().isSuspended(myThreadProxy)) { int status = myThreadProxy.status(); if (!(status == ThreadReference.THREAD_STATUS_UNKNOWN) && !(status == ThreadReference.THREAD_STATUS_NOT_STARTED) && !(status == ThreadReference.THREAD_STATUS_ZOMBIE)) { try { - int framesToSkip = firstFrameIndex; - boolean first = true; - for (StackFrameProxyImpl stackFrame : myThreadProxy.frames()) { - if (first && framesToSkip > 0) { - framesToSkip--; - first = false; - continue; - } - JavaStackFrame frame = new JavaStackFrame(stackFrame, myDebugProcess, myTracker); - if (showLibraryStackframes || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) { - if (framesToSkip > 0) { - framesToSkip--; - continue; - } - frames.add(frame); - } + int added = 0; + Iterator<StackFrameProxyImpl> iterator = myThreadProxy.frames().iterator(); + if (iterator.hasNext() && firstFrameIndex > 0) { + iterator.next(); + added++; } + myDebugProcess.getManagerThread().schedule(new AppendFrameCommand(getSuspendContext(), iterator, container, added, firstFrameIndex)); } catch (EvaluateException e) { container.errorOccurred(e.getMessage()); - return; } } } - container.addStackFrames(frames, true); + else { + container.errorOccurred(DebuggerBundle.message("frame.panel.frames.not.available")); + } } }); } + private class AppendFrameCommand extends SuspendContextCommandImpl { + private final Iterator<StackFrameProxyImpl> myStackFramesIterator; + private final XStackFrameContainer myContainer; + private int myAdded; + private final int mySkip; + + public AppendFrameCommand(SuspendContextImpl suspendContext, + Iterator<StackFrameProxyImpl> stackFramesIterator, + XStackFrameContainer container, + int added, + int skip) { + super(suspendContext); + myStackFramesIterator = stackFramesIterator; + myContainer = container; + myAdded = added; + mySkip = skip; + } + + @Override + public Priority getPriority() { + return myAdded <= 10 ? Priority.NORMAL : Priority.LOW; + } + + @Override + public void contextAction() throws Exception { + if (myStackFramesIterator.hasNext()) { + JavaStackFrame frame = new JavaStackFrame(myStackFramesIterator.next(), myDebugProcess, myTracker); + if (DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) { + if (++myAdded > mySkip) { + myContainer.addStackFrames(Arrays.asList(frame), false); + } + } + myDebugProcess.getManagerThread().schedule( + new AppendFrameCommand(getSuspendContext(), myStackFramesIterator, myContainer, myAdded, mySkip)); + } + else { + myContainer.addStackFrames(Collections.<JavaStackFrame>emptyList(), true); + } + } + } + private static String calcRepresentation(ThreadReferenceProxyImpl thread) { DebuggerManagerThreadImpl.assertIsManagerThread(); String name = thread.name(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java index 316c49201e4c..ed4d8296c381 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -151,6 +151,11 @@ public class JavaStackFrame extends XStackFrame { } myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) { @Override + public Priority getPriority() { + return Priority.NORMAL; + } + + @Override public void threadAction() { XValueChildrenList children = new XValueChildrenList(); buildVariablesThreadAction(getFrameDebuggerContext(), children, node); @@ -202,8 +207,13 @@ public class JavaStackFrame extends XStackFrame { } } + DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + if (debugProcess == null) { + return; + } + // add last method return value if any - final Pair<Method, Value> methodValuePair = debuggerContext.getDebugProcess().getLastExecutedMethod(); + final Pair<Method, Value> methodValuePair = debugProcess.getLastExecutedMethod(); if (methodValuePair != null) { ValueDescriptorImpl returnValueDescriptor = myNodeManager.getMethodReturnValueDescriptor(stackDescriptor, methodValuePair.getFirst(), methodValuePair.getSecond()); children.add(JavaValue.create(returnValueDescriptor, evaluationContext, myNodeManager)); @@ -222,11 +232,10 @@ public class JavaStackFrame extends XStackFrame { final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer(); if (classRenderer.SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) { - if (thisObjectReference != null && evaluationContext.getDebugProcess().getVirtualMachineProxy().canGetSyntheticAttribute()) { + if (thisObjectReference != null && debugProcess.getVirtualMachineProxy().canGetSyntheticAttribute()) { final ReferenceType thisRefType = thisObjectReference.referenceType(); if (thisRefType instanceof ClassType && thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only final ClassType clsType = (ClassType)thisRefType; - final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); final VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy(); for (Field field : clsType.fields()) { if ((!vm.canGetSyntheticAttribute() || field.isSynthetic()) && StringUtil diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java index d1461961be00..6af021c0f9cc 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -29,10 +29,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.impl.DebuggerTreeRenderer; import com.intellij.debugger.ui.impl.watch.*; import com.intellij.debugger.ui.tree.*; -import com.intellij.debugger.ui.tree.render.ArrayRenderer; -import com.intellij.debugger.ui.tree.render.ChildrenBuilder; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; -import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.debugger.ui.tree.render.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; @@ -69,17 +66,15 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { myNodeManager = nodeManager; } - private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) { + private static JavaValue create(JavaValue parent, @NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager, boolean init) { DebuggerManagerThreadImpl.assertIsManagerThread(); - valueDescriptor.setContext(evaluationContext); - valueDescriptor.updateRepresentation(evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); return new JavaValue(parent, valueDescriptor, evaluationContext, nodeManager); } static JavaValue create(@NotNull ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) { - return create(null, valueDescriptor, evaluationContext, nodeManager); + return create(null, valueDescriptor, evaluationContext, nodeManager, true); } public JavaValue getParent() { @@ -100,38 +95,95 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { if (myEvaluationContext.getSuspendContext().isResumed()) return; myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) { @Override + public Priority getPriority() { + return Priority.NORMAL; + } + + @Override public void threadAction() { - Icon nodeIcon = DebuggerTreeRenderer.getValueIcon(myValueDescriptor); - final String[] strings = splitValue(myValueDescriptor.getValueLabel()); - String value = StringUtil.notNullize(strings[1]); - XValuePresentation presentation = new XRegularValuePresentation(value, strings[0]); - if (myValueDescriptor.isString()) { - presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), strings[0]); - } - if (value.length() > XValueNode.MAX_VALUE_LENGTH) { - node.setFullValueEvaluator(new XFullValueEvaluator() { - @Override - public void startEvaluation(@NotNull final XFullValueEvaluationCallback callback) { - myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) { + myValueDescriptor.setContext(myEvaluationContext); + myValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() { + @Override + public void labelChanged() { + Icon nodeIcon = DebuggerTreeRenderer.getValueIcon(myValueDescriptor); + final String[] strings = splitValue(myValueDescriptor.getValueLabel()); + final String value = StringUtil.notNullize(strings[1]); + String type = strings[0]; + XValuePresentation presentation; + if (myValueDescriptor.isString()) { + presentation = new TypedStringValuePresentation(StringUtil.unquoteString(value), type); + } + else { + EvaluateException exception = myValueDescriptor.getEvaluateException(); + if (myValueDescriptor.getLastRenderer() instanceof ToStringRenderer && exception == null) { + presentation = new XRegularValuePresentation(StringUtil.wrapWithDoubleQuote(value), type); + } + else { + presentation = new JavaValuePresentation(value, type, exception != null ? exception.getMessage() : null); + } + } + if (value.length() > XValueNode.MAX_VALUE_LENGTH) { + node.setFullValueEvaluator(new XFullValueEvaluator() { @Override - public void threadAction() { - final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(myEvaluationContext, myValueDescriptor.getValue()); - DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + public void startEvaluation(@NotNull final XFullValueEvaluationCallback callback) { + myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) { + @Override + public Priority getPriority() { + return Priority.NORMAL; + } + @Override - public void run() { - callback.evaluated(valueAsString); + public void threadAction() { + final String valueAsString = DebuggerUtilsEx.getValueOrErrorAsString(myEvaluationContext, myValueDescriptor.getValue()); + DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { + @Override + public void run() { + callback.evaluated(valueAsString); + } + }); } }); } }); } - }); - } - node.setPresentation(nodeIcon, presentation, myValueDescriptor.isExpandable()); + node.setPresentation(nodeIcon, presentation, myValueDescriptor.isExpandable()); + } + }); } }); } + private static class JavaValuePresentation extends XValuePresentation { + private final String myValue; + private final String myType; + private final String myError; + + public JavaValuePresentation(@NotNull String value, @Nullable String type, @Nullable String error) { + myValue = value; + myType = type; + myError = error; + } + + @Nullable + @Override + public String getType() { + return myType; + } + + @Override + public void renderValue(@NotNull XValueTextRenderer renderer) { + if (myError != null) { + if (myValue.endsWith(myError)) { + renderer.renderValue(myValue.substring(0, myValue.length() - myError.length())); + } + renderer.renderError(myError); + } + else { + renderer.renderValue(myValue); + } + } + } + String getValueString() { return splitValue(myValueDescriptor.getValueLabel())[1]; } @@ -168,6 +220,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { if (myEvaluationContext.getSuspendContext().isResumed()) return; myEvaluationContext.getDebugProcess().getManagerThread().schedule(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) { @Override + public Priority getPriority() { + return Priority.NORMAL; + } + + @Override public void contextAction() throws Exception { final XValueChildrenList children = new XValueChildrenList(); final NodeRenderer renderer = myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess()); @@ -205,7 +262,8 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { for (DebuggerTreeNode node : nodes) { final NodeDescriptor descriptor = node.getDescriptor(); if (descriptor instanceof ValueDescriptorImpl) { - children.add(create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager)); + // Value is calculated already in NodeManagerImpl + children.add(create(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager, false)); } else if (descriptor instanceof MessageDescriptor) { children.add("", new XValue() { @@ -272,6 +330,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess(); debugProcess.getManagerThread().schedule(new JumpToObjectAction.NavigateCommand(getDebuggerContext(), myValueDescriptor, debugProcess, null) { @Override + public Priority getPriority() { + return Priority.HIGH; + } + + @Override protected void doAction(@Nullable final SourcePosition sourcePosition) { if (sourcePosition != null) { ApplicationManager.getApplication().runReadAction(new Runnable() { @@ -301,6 +364,11 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider { DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess(); debugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { @Override + public Priority getPriority() { + return Priority.HIGH; + } + + @Override protected void action() throws Exception { evaluationExpression = ApplicationManager.getApplication().runReadAction(new Computable<String>() { @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java index 713b4c9b8dd6..c7e59106beb8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -45,6 +45,8 @@ import org.jetbrains.annotations.Nullable; import javax.swing.*; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING; + /* * Class SetValueAction * @author Jeka @@ -231,7 +233,7 @@ public class JavaValueModifier extends XValueModifier { } private Value preprocessValue(EvaluationContextImpl context, Value value, Type varType) throws EvaluateException { - if (value != null && "java.lang.String".equals(varType.name()) && !(value instanceof StringReference)) { + if (value != null && JAVA_LANG_STRING.equals(varType.name()) && !(value instanceof StringReference)) { String v = DebuggerUtilsEx.getValueAsString(context, value); if (v != null) { value = context.getSuspendContext().getDebugProcess().getVirtualMachineProxy().mirrorOf(v); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java b/java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java index 91b223c613c9..90a5aa2b4927 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/actions/FocusOnBreakpointAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/NamedMethodFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.debugger.ui.breakpoints.actions; +package com.intellij.debugger.engine; -import com.intellij.execution.ui.actions.AbstractFocusOnAction; -import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; - -public class FocusOnBreakpointAction extends AbstractFocusOnAction { - public FocusOnBreakpointAction() { - super(XDebuggerUIConstants.LAYOUT_VIEW_BREAKPOINT_CONDITION); - } -}
\ No newline at end of file +/** + * Nikolay.Tropin + * 2014-06-10 + */ +public interface NamedMethodFilter extends MethodFilter { + String getMethodName(); +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java index 0e37ff354e47..2c31e75cc521 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/PositionManagerImpl.java @@ -28,6 +28,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.NullableComputable; import com.intellij.openapi.util.Ref; import com.intellij.psi.*; +import com.intellij.psi.search.FilenameIndex; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiUtil; import com.sun.jdi.AbsentInformationException; @@ -192,6 +193,18 @@ public class PositionManagerImpl implements PositionManager { final PsiElement element = psiClass.getNavigationElement(); return element.getContainingFile(); } + else { + // for now just take the first file with the required name + // TODO: if there are more than one, we can try matching package name and sourcePath if available + try { + PsiFile[] files = FilenameIndex.getFilesByName(project, refType.sourceName(), GlobalSearchScope.allScope(project)); + if (files.length > 0) { + return files[0]; + } + } + catch (AbsentInformationException ignore) { + } + } return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java index 6786078319a5..00aae83904ce 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java @@ -33,9 +33,7 @@ import com.sun.jdi.request.EventRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Set; +import java.util.*; import java.util.concurrent.ConcurrentLinkedQueue; /** @@ -61,7 +59,7 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp private final HashSet<ObjectReference> myKeptReferences = new HashSet<ObjectReference>(); private EvaluationContextImpl myEvaluationContext = null; - private JavaExecutionStack[] myExecutionStacks; + private JavaExecutionStack myActiveExecutionStack; SuspendContextImpl(@NotNull DebugProcessImpl debugProcess, int suspendPolicy, int eventVotes, EventSet set) { myDebugProcess = debugProcess; @@ -231,27 +229,48 @@ public abstract class SuspendContextImpl extends XSuspendContext implements Susp @Nullable @Override public XExecutionStack getActiveExecutionStack() { - for (JavaExecutionStack stack : myExecutionStacks) { - if (stack.getThreadProxy().equals(myThread)) { - return stack; - } + return myActiveExecutionStack; + } + + public void initExecutionStacks(ThreadReferenceProxyImpl newThread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + myThread = newThread; + if (newThread != null) { + myActiveExecutionStack = new JavaExecutionStack(newThread, myDebugProcess, true); } - return null; } @Override - public XExecutionStack[] getExecutionStacks() { - return myExecutionStacks; + public void computeExecutionStacks(final XExecutionStackContainer container) { + myDebugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(this) { + @Override + public void contextAction() throws Exception { + List<JavaExecutionStack> res = new ArrayList<JavaExecutionStack>(); + Collection<ThreadReferenceProxyImpl> threads = getDebugProcess().getVirtualMachineProxy().allThreads(); + JavaExecutionStack currentStack = null; + for (ThreadReferenceProxyImpl thread : threads) { + boolean current = thread == myThread; + JavaExecutionStack stack = new JavaExecutionStack(thread, myDebugProcess, current); + if (!current) { + res.add(stack); + } + else { + currentStack = stack; + } + } + Collections.sort(res, THREADS_COMPARATOR); + if (currentStack != null) { + res.add(0, currentStack); + } + container.addExecutionStack(res, true); + } + }); } - public void initExecutionStacks(ThreadReferenceProxyImpl newThread) { - DebuggerManagerThreadImpl.assertIsManagerThread(); - Collection<JavaExecutionStack> res = new ArrayList<JavaExecutionStack>(); - Collection<ThreadReferenceProxyImpl> threads = getDebugProcess().getVirtualMachineProxy().allThreads(); - for (ThreadReferenceProxyImpl thread : threads) { - res.add(new JavaExecutionStack(thread, myDebugProcess, thread == myThread)); + private static final Comparator<JavaExecutionStack> THREADS_COMPARATOR = new Comparator<JavaExecutionStack>() { + @Override + public int compare(JavaExecutionStack th1, JavaExecutionStack th2) { + return th1.getDisplayName().compareToIgnoreCase(th2.getDisplayName()); } - myExecutionStacks = res.toArray(new JavaExecutionStack[res.size()]); - myThread = newThread; - } + }; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java index d6975e6d021a..45af0e10ac72 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java @@ -220,31 +220,11 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { @Override public void visitForStatement(PsiForStatement statement) { - PsiStatement initializer = statement.getInitialization(); - Evaluator initializerEvaluator = null; - if(initializer != null){ - initializer.accept(this); - initializerEvaluator = myResult; - } - - PsiExpression condition = statement.getCondition(); - Evaluator conditionEvaluator = null; - if(condition != null) { - condition.accept(this); - conditionEvaluator = myResult; - } - - PsiStatement update = statement.getUpdate(); - Evaluator updateEvaluator = null; - if(update != null){ - update.accept(this); - updateEvaluator = myResult; - } - - PsiStatement body = statement.getBody(); - if(body == null) return; - body.accept(this); - Evaluator bodyEvaluator = myResult; + Evaluator initializerEvaluator = accept(statement.getInitialization()); + Evaluator conditionEvaluator = accept(statement.getCondition()); + Evaluator updateEvaluator = accept(statement.getUpdate()); + Evaluator bodyEvaluator = accept(statement.getBody()); + if (bodyEvaluator == null) return; String label = null; if(statement.getParent() instanceof PsiLabeledStatement) { @@ -254,6 +234,37 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } @Override + public void visitForeachStatement(PsiForeachStatement statement) { + try { + String iterationParameterName = statement.getIterationParameter().getName(); + myCurrentFragmentEvaluator.setInitialValue(iterationParameterName, null); + SyntheticVariableEvaluator iterationParameterEvaluator = new SyntheticVariableEvaluator(myCurrentFragmentEvaluator, iterationParameterName); + + Evaluator iteratedValueEvaluator = accept(statement.getIteratedValue()); + Evaluator bodyEvaluator = accept(statement.getBody()); + if (bodyEvaluator == null) return; + + String label = null; + if(statement.getParent() instanceof PsiLabeledStatement) { + label = ((PsiLabeledStatement)statement.getParent()).getLabelIdentifier().getText(); + } + myResult = new ForeachStatementEvaluator(iterationParameterEvaluator, iteratedValueEvaluator, bodyEvaluator, label); + } + catch (EvaluateException e) { + throw new EvaluateRuntimeException(e); + } + } + + @Nullable + private Evaluator accept(@Nullable PsiElement element) { + if (element == null || element instanceof PsiEmptyStatement) { + return null; + } + element.accept(this); + return myResult; + } + + @Override public void visitIfStatement(PsiIfStatement statement) { PsiStatement thenBranch = statement.getThenBranch(); if(thenBranch == null) return; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java index ff35ef7fe1dd..5914c878086e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluator.java @@ -16,87 +16,67 @@ package com.intellij.debugger.engine.evaluation.expression; import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.openapi.util.Comparing; -import com.sun.jdi.BooleanValue; /** * @author lex */ -public class ForStatementEvaluator implements Evaluator { +public class ForStatementEvaluator extends ForStatementEvaluatorBase { private final Evaluator myInitializationEvaluator; private final Evaluator myConditionEvaluator; private final Evaluator myUpdateEvaluator; private final Evaluator myBodyEvaluator; private Modifier myModifier; - private final String myLabelName; public ForStatementEvaluator(Evaluator initializationEvaluator, Evaluator conditionEvaluator, Evaluator updateEvaluator, Evaluator bodyEvaluator, String labelName) { - myInitializationEvaluator = new DisableGC(initializationEvaluator); - myConditionEvaluator = new DisableGC(conditionEvaluator); - myUpdateEvaluator = new DisableGC(updateEvaluator); - myBodyEvaluator = new DisableGC(bodyEvaluator); - myLabelName = labelName; + super(labelName); + myInitializationEvaluator = initializationEvaluator != null ? new DisableGC(initializationEvaluator) : null; + myConditionEvaluator = conditionEvaluator != null ? new DisableGC(conditionEvaluator) : null; + myUpdateEvaluator = updateEvaluator != null ? new DisableGC(updateEvaluator) : null; + myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null; } public Modifier getModifier() { return myModifier; } - public Object evaluate(EvaluationContextImpl context) throws EvaluateException { - Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + @Override + protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException { + if (myBodyEvaluator != null) { + myBodyEvaluator.evaluate(context); + } + } + + @Override + protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException { if (myInitializationEvaluator != null) { value = myInitializationEvaluator.evaluate(context); myModifier = myInitializationEvaluator.getModifier(); } + return value; + } - while (true) { - if (myConditionEvaluator != null) { - value = myConditionEvaluator.evaluate(context); - myModifier = myConditionEvaluator.getModifier(); - if (!(value instanceof BooleanValue)) { - throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; - } - else { - if (!((BooleanValue)value).booleanValue()) { - break; - } - } - } - - try { - myBodyEvaluator.evaluate(context); - } - catch (BreakException e) { - if (Comparing.equal(e.getLabelName(), myLabelName)) { - break; - } - else { - throw e; - } - } - catch (ContinueException e) { - if (Comparing.equal(e.getLabelName(), myLabelName)) { - //continue; - } - else { - throw e; - } - } - - if (myUpdateEvaluator != null) { - value = myUpdateEvaluator.evaluate(context); - myModifier = myUpdateEvaluator.getModifier(); - } + @Override + protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException { + if (myConditionEvaluator != null) { + Object value = myConditionEvaluator.evaluate(context); + myModifier = myConditionEvaluator.getModifier(); + return value; } + return true; + } + @Override + protected Object evaluateUpdate(EvaluationContextImpl context, Object value) throws EvaluateException { + if (myUpdateEvaluator != null) { + value = myUpdateEvaluator.evaluate(context); + myModifier = myUpdateEvaluator.getModifier(); + } return value; } - } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java new file mode 100644 index 000000000000..7af8c894e9b4 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForStatementEvaluatorBase.java @@ -0,0 +1,94 @@ +/* + * Copyright 2000-2014 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.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.openapi.util.Comparing; +import com.sun.jdi.BooleanValue; + +/** + * @author egor + */ +public abstract class ForStatementEvaluatorBase implements Evaluator { + private final String myLabelName; + + public ForStatementEvaluatorBase(String labelName) { + myLabelName = labelName; + } + + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + Object value = context.getDebugProcess().getVirtualMachineProxy().mirrorOf(); + value = evaluateInitialization(context, value); + + while (true) { + // condition + Object codition = evaluateCondition(context); + if (codition instanceof Boolean) { + if (!(Boolean)codition) break; + } + else if (codition instanceof BooleanValue) { + if (!((BooleanValue)codition).booleanValue()) break; + } + else { + throw EvaluateExceptionUtil.BOOLEAN_EXPECTED; + } + + // body + + try { + evaluateBody(context); + } + catch (BreakException e) { + if (Comparing.equal(e.getLabelName(), myLabelName)) { + break; + } + else { + throw e; + } + } + catch (ContinueException e) { + if (Comparing.equal(e.getLabelName(), myLabelName)) { + //continue; + } + else { + throw e; + } + } + + // update + value = evaluateUpdate(context, value); + } + + return value; + } + + protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException { + return value; + } + + protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException { + return true; + } + + protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException { + } + + protected Object evaluateUpdate(EvaluationContextImpl context, Object value) throws EvaluateException { + return value; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java new file mode 100644 index 000000000000..7b7b44856155 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/ForeachStatementEvaluator.java @@ -0,0 +1,109 @@ +/* + * Copyright 2000-2014 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.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.sun.jdi.ArrayReference; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; + +/** + * @author egor + */ +public class ForeachStatementEvaluator extends ForStatementEvaluatorBase { + private final Evaluator myIterationParameterEvaluator; + private final Evaluator myIterableEvaluator; + private final Evaluator myBodyEvaluator; + + private Evaluator myConditionEvaluator; + private Evaluator myNextEvaluator; + + private int myArrayLength = -1; + private int myCurrentIndex = 0; + + private Modifier myModifier; + + public ForeachStatementEvaluator(Evaluator iterationParameterEvaluator, + Evaluator iterableEvaluator, + Evaluator bodyEvaluator, + String labelName) { + super(labelName); + myIterationParameterEvaluator = iterationParameterEvaluator; + myIterableEvaluator = new DisableGC(iterableEvaluator); + myBodyEvaluator = bodyEvaluator != null ? new DisableGC(bodyEvaluator) : null; + } + + public Modifier getModifier() { + return myModifier; + } + + @Override + protected Object evaluateInitialization(EvaluationContextImpl context, Object value) throws EvaluateException { + final Object iterable = myIterableEvaluator.evaluate(context); + if (!(iterable instanceof ObjectReference)) { + throw new EvaluateException("Unable to do foreach for" + iterable); + } + IdentityEvaluator iterableEvaluator = new IdentityEvaluator((Value)iterable); + if (iterable instanceof ArrayReference) { + myArrayLength = ((ArrayReference)iterable).length(); + myNextEvaluator = new AssignmentEvaluator(myIterationParameterEvaluator, + new Evaluator() { + @Override + public Object evaluate(EvaluationContextImpl context) throws EvaluateException { + return ((ArrayReference)iterable).getValue(myCurrentIndex++); + } + + @Override + public Modifier getModifier() { + return null; + } + }); + } + else { + Object iterator = new MethodEvaluator(iterableEvaluator, null, "iterator", null, new Evaluator[0]).evaluate(context); + IdentityEvaluator iteratorEvaluator = new IdentityEvaluator((Value)iterator); + myConditionEvaluator = new MethodEvaluator(iteratorEvaluator, null, "hasNext", null, new Evaluator[0]); + myNextEvaluator = new AssignmentEvaluator(myIterationParameterEvaluator, + new MethodEvaluator(iteratorEvaluator, null, "next", null, new Evaluator[0])); + } + return value; + } + + private boolean isArray() { + return myArrayLength > -1; + } + + @Override + protected Object evaluateCondition(EvaluationContextImpl context) throws EvaluateException { + if (isArray()) { + return myCurrentIndex < myArrayLength; + } + else { + Object res = myConditionEvaluator.evaluate(context); + myModifier = myConditionEvaluator.getModifier(); + return res; + } + } + + @Override + protected void evaluateBody(EvaluationContextImpl context) throws EvaluateException { + myNextEvaluator.evaluate(context); + if (myBodyEvaluator != null) { + myBodyEvaluator.evaluate(context); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index c404aef4004c..58296e2b7273 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -392,42 +392,6 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque public void processAttached(DebugProcessImpl process) { myEventRequestManager = myDebugProcess.getVirtualMachineProxy().eventRequestManager(); - // invoke later, so that requests are for sure created only _after_ 'processAttached()' methods of other listeners are executed - process.getManagerThread().schedule(new DebuggerCommandImpl() { - protected void action() throws Exception { - ApplicationManager.getApplication().runReadAction(new Runnable() { - @Override - public void run() { - XDebugSession session = myDebugProcess.getSession().getXDebugSession(); - if (session != null) { - session.initBreakpoints(); - } - } - }); - //Project project = myDebugProcess.getProject(); - //final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - //for (final Breakpoint breakpoint : breakpointManager.getBreakpoints()) { - // try { - // breakpoint.createRequest(myDebugProcess); - // } catch (Exception e) { - // LOG.error(e); - // } - //} - - //AccessToken token = ReadAction.start(); - //try { - // JavaBreakpointAdapter adapter = new JavaBreakpointAdapter(project); - // for (XLineBreakpoint breakpoint : XDebuggerManager.getInstance(project).getBreakpointManager() - // .getBreakpoints(JavaLineBreakpointType.class)) { - // //new JavaLineBreakpointRequestor(breakpoint).createRequest(myDebugProcess); - // //adapter.getOrCreate(breakpoint).createRequest(myDebugProcess); - // } - //} - //finally { - // token.finish(); - //} - } - }); } public void processClassPrepared(final ClassPrepareEvent event) { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java index c04c5e4e4817..11b077340eb7 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java @@ -84,10 +84,6 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { @Nullable public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls) { - if (!(element instanceof PsiIdentifier || element instanceof PsiKeyword)) { - return null; - } - PsiElement expression = null; PsiElement parent = element.getParent(); if (parent instanceof PsiVariable) { @@ -98,6 +94,12 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { if (pparent instanceof PsiCallExpression) { parent = pparent; } + else if (pparent instanceof PsiReferenceExpression) { + PsiElement resolve = ((PsiReferenceExpression)parent).resolve(); + if (resolve instanceof PsiClass) { + parent = pparent; + } + } if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) { expression = parent; } @@ -105,6 +107,19 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { else if (parent instanceof PsiThisExpression) { expression = parent; } + else if (parent instanceof PsiInstanceOfExpression || parent instanceof PsiBinaryExpression || parent instanceof PsiPolyadicExpression) { + if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) { + expression = parent; + } + } + else if (allowMethodCalls) { + PsiElement e = PsiTreeUtil.getParentOfType(element, PsiVariable.class, PsiExpression.class, PsiMethod.class); + if (e instanceof PsiNewExpression) { + if (((PsiNewExpression)e).getAnonymousClass() == null) { + expression = e; + } + } + } if (expression != null) { try { diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java index 0f813d0bf167..e570b642b2bd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/CompoundRendererConfigurable.java @@ -25,12 +25,14 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.ui.DebuggerExpressionTextField; import com.intellij.debugger.ui.JavaDebuggerSupport; import com.intellij.debugger.ui.tree.render.*; +import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Document; import com.intellij.openapi.options.ConfigurationException; import com.intellij.openapi.options.UnnamedConfigurable; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; @@ -141,10 +143,17 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable { } } }, myProject); - myClassNameField.getEditorTextField().addFocusListener(new FocusAdapter() { + final EditorTextField textField = myClassNameField.getEditorTextField(); + final FocusAdapter updateContextListener = new FocusAdapter() { public void focusLost(FocusEvent e) { - final String qName = myClassNameField.getText(); - updateContext(qName); + updateContext(myClassNameField.getText()); + } + }; + textField.addFocusListener(updateContextListener); + Disposer.register(myClassNameField, new Disposable() { + @Override + public void dispose() { + textField.removeFocusListener(updateContextListener); } }); @@ -388,10 +397,12 @@ public class CompoundRendererConfigurable implements UnnamedConfigurable { myChildrenEditor.dispose(); myChildrenExpandedEditor.dispose(); myListChildrenEditor.dispose(); + Disposer.dispose(myClassNameField); myLabelEditor = null; myChildrenEditor = null; myChildrenExpandedEditor = null; myListChildrenEditor = null; + myClassNameField = null; myProject = null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java index a43ca7e9eae3..e1d80414f0e6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/NodeRendererSettings.java @@ -33,6 +33,7 @@ import com.intellij.openapi.components.*; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.CommonClassNames; import com.intellij.psi.JavaPsiFacade; import com.intellij.psi.PsiElementFactory; @@ -546,7 +547,12 @@ public class NodeRendererSettings implements PersistentStateComponent<Element> { } static String constructLabelText(final String keylabel, final String valueLabel) { - return keylabel + " -> " + valueLabel; + StringBuilder sb = new StringBuilder(); + sb.append('\"').append(keylabel).append("\" -> "); + if (!StringUtil.isEmpty(valueLabel)) { + sb.append('\"').append(valueLabel).append('\"'); + } + return sb.toString(); } private static String getDescriptorLabel(final ValueDescriptorImpl keyDescriptor) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index 3c78eaefaea5..6879407b3c9a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -502,19 +502,23 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements if (getProperties() == null) { return false; } - return getProperties().COUNT_FILTER_ENABLED; + return getProperties().isCOUNT_FILTER_ENABLED(); } public void setCountFilterEnabled(boolean enabled) { - getProperties().COUNT_FILTER_ENABLED = enabled; + if (getProperties().setCOUNT_FILTER_ENABLED(enabled)) { + fireBreakpointChanged(); + } } @Override public int getCountFilter() { - return getProperties().COUNT_FILTER; + return getProperties().getCOUNT_FILTER(); } public void setCountFilter(int filter) { - getProperties().COUNT_FILTER = filter; + if (getProperties().setCOUNT_FILTER(filter)) { + fireBreakpointChanged(); + } } @Override @@ -522,11 +526,13 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements if (getProperties() == null) { return false; } - return getProperties().CLASS_FILTERS_ENABLED; + return getProperties().isCLASS_FILTERS_ENABLED(); } public void setClassFiltersEnabled(boolean enabled) { - getProperties().CLASS_FILTERS_ENABLED = enabled; + if (getProperties().setCLASS_FILTERS_ENABLED(enabled)) { + fireBreakpointChanged(); + } } @Override @@ -535,7 +541,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements } public void setClassFilters(ClassFilter[] filters) { - getProperties().setClassFilters(filters); + if (getProperties().setClassFilters(filters)) { + fireBreakpointChanged(); + } } @Override @@ -544,7 +552,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements } protected void setClassExclusionFilters(ClassFilter[] filters) { - getProperties().setClassExclusionFilters(filters); + if (getProperties().setClassExclusionFilters(filters)) { + fireBreakpointChanged(); + } } @Override @@ -552,11 +562,13 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements if (getProperties() == null) { return false; } - return getProperties().INSTANCE_FILTERS_ENABLED; + return getProperties().isINSTANCE_FILTERS_ENABLED(); } public void setInstanceFiltersEnabled(boolean enabled) { - getProperties().INSTANCE_FILTERS_ENABLED = enabled; + if (getProperties().setINSTANCE_FILTERS_ENABLED(enabled)) { + fireBreakpointChanged(); + } } @Override @@ -565,7 +577,9 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements } public void setInstanceFilters(InstanceFilter[] filters) { - getProperties().setInstanceFilters(filters); + if (getProperties().setInstanceFilters(filters)) { + fireBreakpointChanged(); + } } private static String getSuspendPolicy(XBreakpoint breakpoint) { @@ -622,4 +636,8 @@ public abstract class Breakpoint<P extends JavaBreakpointProperties> implements protected void addInstanceFilter(long l) { getProperties().addInstanceFilter(l); } + + protected void fireBreakpointChanged() { + ((XBreakpointBase)myXBreakpoint).fireBreakpointChanged(); + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index b8fa39e399c7..87453ef57f98 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -689,34 +689,6 @@ public class BreakpointManager { } } - // copied from XDebugSessionImpl processDependencies - public void processBreakpointHit(@NotNull final Breakpoint breakpoint) { - XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); - XBreakpoint xBreakpoint = breakpoint.myXBreakpoint; - if (!dependentBreakpointManager.isMasterOrSlave(xBreakpoint)) { - return; - } - List<XBreakpoint<?>> breakpoints = dependentBreakpointManager.getSlaveBreakpoints(xBreakpoint); - for (final XBreakpoint<?> slaveBreakpoint : breakpoints) { - DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { - @Override - public void run() { - slaveBreakpoint.setEnabled(true); - } - }); - } - - if (dependentBreakpointManager.getMasterBreakpoint(xBreakpoint) != null && !dependentBreakpointManager.isLeaveEnabled(xBreakpoint)) { - DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { - @Override - public void run() { - breakpoint.setEnabled(false); - } - }); - //myDebuggerManager.getBreakpointManager().getLineBreakpointManager().queueBreakpointUpdate(breakpoint); - } - } - @Nullable public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) { XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java index 4af7275d1258..0bd7d9fc9826 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpointPropertiesPanel.java @@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; @@ -107,7 +108,12 @@ public class ExceptionBreakpointPropertiesPanel extends XBreakpointCustomPropert @Override public void saveTo(@NotNull XBreakpoint<JavaExceptionBreakpointProperties> breakpoint) { + boolean changed = breakpoint.getProperties().NOTIFY_CAUGHT != myNotifyCaughtCheckBox.isSelected(); breakpoint.getProperties().NOTIFY_CAUGHT = myNotifyCaughtCheckBox.isSelected(); + changed = breakpoint.getProperties().NOTIFY_UNCAUGHT != myNotifyUncaughtCheckBox.isSelected() || changed; breakpoint.getProperties().NOTIFY_UNCAUGHT = myNotifyUncaughtCheckBox.isSelected(); + if (changed) { + ((XBreakpointBase)breakpoint).fireBreakpointChanged(); + } } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java index 4d0bec2e165b..41f5417799b6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FieldBreakpointPropertiesPanel.java @@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.java.debugger.breakpoints.properties.JavaFieldBreakpointProperties; @@ -100,7 +101,12 @@ public class FieldBreakpointPropertiesPanel extends XBreakpointCustomPropertiesP @Override public void saveTo(@NotNull XLineBreakpoint<JavaFieldBreakpointProperties> breakpoint) { + boolean changed = breakpoint.getProperties().WATCH_ACCESS != myWatchAccessCheckBox.isSelected(); breakpoint.getProperties().WATCH_ACCESS = myWatchAccessCheckBox.isSelected(); + changed = breakpoint.getProperties().WATCH_MODIFICATION != myWatchModificationCheckBox.isSelected() || changed; breakpoint.getProperties().WATCH_MODIFICATION = myWatchModificationCheckBox.isSelected(); + if (changed) { + ((XBreakpointBase)breakpoint).fireBreakpointChanged(); + } } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java index 8731329275e9..23b18cb4f306 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpoint.java @@ -31,6 +31,7 @@ import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.requests.RequestManagerImpl; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.impl.PositionUtil; +import com.intellij.debugger.requests.Requestor; import com.intellij.icons.AllIcons; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -146,7 +147,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp RequestManagerImpl requestManager = debugProcess.getRequestsManager(); if (isWatchEntry()) { - MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class); + MethodEntryRequest entryRequest = findRequest(debugProcess, MethodEntryRequest.class, this); if (entryRequest == null) { entryRequest = requestManager.createMethodEntryRequest(this); } @@ -159,7 +160,7 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp debugProcess.getRequestsManager().enableRequest(entryRequest); } if (isWatchExit()) { - MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class); + MethodExitRequest exitRequest = findRequest(debugProcess, MethodExitRequest.class, this); if (exitRequest == null) { exitRequest = requestManager.createMethodExitRequest(this); } @@ -353,15 +354,13 @@ public class MethodBreakpoint extends BreakpointWithHighlighter<JavaMethodBreakp } @Nullable - private EventRequest findRequest(@NotNull DebugProcessImpl debugProcess, Class requestClass) { - Set reqSet = debugProcess.getRequestsManager().findRequests(this); - for (Iterator iterator = reqSet.iterator(); iterator.hasNext();) { - EventRequest eventRequest = (EventRequest) iterator.next(); - if(eventRequest.getClass().equals(requestClass)) { - return eventRequest; + static <T extends EventRequest> T findRequest(@NotNull DebugProcessImpl debugProcess, Class<T> requestClass, Requestor requestor) { + Set<EventRequest> requests = debugProcess.getRequestsManager().findRequests(requestor); + for (EventRequest eventRequest : requests) { + if (eventRequest.getClass().equals(requestClass)) { + return (T)eventRequest; } } - return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java index bf7419264105..c9026d152e99 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/MethodBreakpointPropertiesPanel.java @@ -25,6 +25,7 @@ import com.intellij.ui.IdeBorderFactory; import com.intellij.util.ui.DialogUtil; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.java.debugger.breakpoints.properties.JavaMethodBreakpointProperties; @@ -100,7 +101,12 @@ public class MethodBreakpointPropertiesPanel extends XBreakpointCustomProperties @Override public void saveTo(@NotNull XBreakpoint<JavaMethodBreakpointProperties> breakpoint) { + boolean changed = breakpoint.getProperties().WATCH_ENTRY != myWatchEntryCheckBox.isSelected(); breakpoint.getProperties().WATCH_ENTRY = myWatchEntryCheckBox.isSelected(); + changed = breakpoint.getProperties().WATCH_EXIT != myWatchExitCheckBox.isSelected() || changed; breakpoint.getProperties().WATCH_EXIT = myWatchExitCheckBox.isSelected(); + if (changed) { + ((XBreakpointBase)breakpoint).fireBreakpointChanged(); + } } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java index 295fddbaf187..c106f65cab81 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/WildcardMethodBreakpoint.java @@ -135,7 +135,7 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro try { RequestManagerImpl requestManager = debugProcess.getRequestsManager(); if (isWatchEntry()) { - MethodEntryRequest entryRequest = (MethodEntryRequest)findRequest(debugProcess, MethodEntryRequest.class); + MethodEntryRequest entryRequest = MethodBreakpoint.findRequest(debugProcess, MethodEntryRequest.class, this); if (entryRequest == null) { entryRequest = requestManager.createMethodEntryRequest(this); } @@ -146,7 +146,7 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro debugProcess.getRequestsManager().enableRequest(entryRequest); } if (isWatchExit()) { - MethodExitRequest exitRequest = (MethodExitRequest)findRequest(debugProcess, MethodExitRequest.class); + MethodExitRequest exitRequest = MethodBreakpoint.findRequest(debugProcess, MethodExitRequest.class, this); if (exitRequest == null) { exitRequest = requestManager.createMethodExitRequest(this); } @@ -162,18 +162,6 @@ public class WildcardMethodBreakpoint extends Breakpoint<JavaMethodBreakpointPro } } - private EventRequest findRequest(DebugProcessImpl debugProcess, Class requestClass) { - Set reqSet = debugProcess.getRequestsManager().findRequests(this); - for (Iterator iterator = reqSet.iterator(); iterator.hasNext();) { - EventRequest eventRequest = (EventRequest) iterator.next(); - if(eventRequest.getClass().equals(requestClass)) { - return eventRequest; - } - } - - return null; - } - public void processClassPrepare(DebugProcess debugProcess, ReferenceType refType) { // should be emty - does not make sense for this breakpoint } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java index ae2f2c115d82..d72c967f67be 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreeRenderer.java @@ -22,15 +22,14 @@ import com.intellij.debugger.ui.impl.watch.*; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.icons.AllIcons; import com.intellij.ide.highlighter.JavaHighlightingColors; -import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.editor.markup.TextAttributes; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.*; import com.intellij.util.PlatformIcons; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; -import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -119,18 +118,6 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { return nodeIcon; } - @NotNull - public static EditorColorsScheme getColorScheme(@Nullable JComponent component) { - EditorColorsScheme globalScheme = EditorColorsManager.getInstance().getGlobalScheme(); - if (component != null && ColorUtil.isDark(component.getBackground()) != ColorUtil.isDark(globalScheme.getDefaultBackground())) { - EditorColorsScheme scheme = EditorColorsManager.getInstance().getScheme(EditorColorsScheme.DEFAULT_SCHEME_NAME); - if (scheme != null) { - return scheme; - } - } - return globalScheme; - } - public static SimpleColoredText getDescriptorText(DebuggerContextImpl debuggerContext, NodeDescriptorImpl descriptor, EditorColorsScheme colorsScheme, @@ -139,11 +126,11 @@ public class DebuggerTreeRenderer extends ColoredTreeCellRenderer { } public static SimpleColoredText getDescriptorText(final DebuggerContextImpl debuggerContext, NodeDescriptorImpl descriptor, boolean multiline) { - return getDescriptorText(debuggerContext, descriptor, getColorScheme(null), multiline, true); + return getDescriptorText(debuggerContext, descriptor, DebuggerUIUtil.getColorScheme(null), multiline, true); } public static SimpleColoredText getDescriptorTitle(final DebuggerContextImpl debuggerContext, NodeDescriptorImpl descriptor) { - return getDescriptorText(debuggerContext, descriptor, getColorScheme(null), false, false); + return getDescriptorText(debuggerContext, descriptor, DebuggerUIUtil.getColorScheme(null), false, false); } private static SimpleColoredText getDescriptorText(DebuggerContextImpl debuggerContext, diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java index 554e5f117bcb..8cb6828d26e8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java @@ -273,6 +273,9 @@ public class FrameVariablesTree extends DebuggerTree { } catch (UnsupportedOperationException ignored) { } + catch (InternalException e) { + LOG.info(e); + } return Collections.emptyList(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java index dd8f17895522..87b0275e9139 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java @@ -36,6 +36,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.ui.SimpleColoredText; import com.intellij.util.containers.HashMap; +import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import org.jetbrains.annotations.Nullable; @@ -93,7 +94,7 @@ public class DebuggerTreeNodeImpl extends TreeBuilderNode implements DebuggerTre final NodeDescriptorImpl descriptor = getDescriptor(); myIcon = DebuggerTreeRenderer.getDescriptorIcon(descriptor); final DebuggerContextImpl context = getTree().getDebuggerContext(); - myText = DebuggerTreeRenderer.getDescriptorText(context, descriptor, DebuggerTreeRenderer.getColorScheme(myTree), false); + myText = DebuggerTreeRenderer.getDescriptorText(context, descriptor, DebuggerUIUtil.getColorScheme(myTree), false); if (descriptor instanceof ValueDescriptor) { final ValueMarkup markup = ((ValueDescriptor)descriptor).getMarkup(context.getDebugProcess()); myMarkupTooltipText = markup != null? markup.getToolTipText() : null; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java index 8547e48d3a46..0662112bca6a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/MethodsTracker.java @@ -26,6 +26,7 @@ import java.util.Map; */ public class MethodsTracker { private final Map<Method, Integer> myMethodToOccurrenceMap = new HashMap<Method, Integer>(); + private final Map<Integer, MethodOccurrence> myOccurences = new HashMap<Integer, MethodOccurrence>(); public final class MethodOccurrence { private final Method myMethod; @@ -49,8 +50,13 @@ public class MethodsTracker { } } - public MethodOccurrence getMethodOccurrence(Method method) { - return new MethodOccurrence(method, assignOccurrenceIndex(method)); + public MethodOccurrence getMethodOccurrence(int frameIndex, Method method) { + MethodOccurrence occurrence = myOccurences.get(frameIndex); + if (occurrence == null) { + occurrence = new MethodOccurrence(method, assignOccurrenceIndex(method)); + myOccurences.put(frameIndex, occurrence); + } + return occurrence; } private int getOccurrenceCount(Method method) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java index 28062f09c3d0..08f2e05c2835 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/StackFrameDescriptorImpl.java @@ -58,6 +58,7 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac private boolean myIsInLibraryContent; private ObjectReference myThisObject; private Color myBackgroundColor; + private SourcePosition mySourcePosition; private Icon myIcon = AllIcons.Debugger.StackFrame; @@ -68,13 +69,13 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac myUiIndex = frame.getFrameIndex(); myLocation = frame.location(); myThisObject = frame.thisObject(); - myMethodOccurrence = tracker.getMethodOccurrence(myLocation.method()); + myMethodOccurrence = tracker.getMethodOccurrence(myUiIndex, myLocation.method()); myIsSynthetic = DebuggerUtils.isSynthetic(myMethodOccurrence.getMethod()); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - final SourcePosition position = ContextUtil.getSourcePosition(StackFrameDescriptorImpl.this); - final PsiFile file = position != null? position.getFile() : null; + mySourcePosition = ContextUtil.getSourcePosition(StackFrameDescriptorImpl.this); + final PsiFile file = mySourcePosition != null? mySourcePosition.getFile() : null; if (file == null) { myIsInLibraryContent = true; } @@ -91,14 +92,14 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac catch (InternalException e) { LOG.info(e); myLocation = null; - myMethodOccurrence = tracker.getMethodOccurrence(null); + myMethodOccurrence = tracker.getMethodOccurrence(0, null); myIsSynthetic = false; myIsInLibraryContent = false; } catch (EvaluateException e) { LOG.info(e); myLocation = null; - myMethodOccurrence = tracker.getMethodOccurrence(null); + myMethodOccurrence = tracker.getMethodOccurrence(0, null); myIsSynthetic = false; myIsInLibraryContent = false; } @@ -273,6 +274,10 @@ public class StackFrameDescriptorImpl extends NodeDescriptorImpl implements Stac return myLocation; } + public SourcePosition getSourcePosition() { + return mySourcePosition; + } + private Icon calcIcon() { try { if(myFrame.isObsolete()) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 403015474caa..abda6968def4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -51,6 +51,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements NodeRenderer myAutoRenderer = null; private Value myValue; + private boolean myValueReady; + private EvaluateException myValueException; protected EvaluationContextImpl myStoredEvaluationContext = null; @@ -69,38 +71,51 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements protected ValueDescriptorImpl(Project project, Value value) { myProject = project; myValue = value; + myValueReady = true; } protected ValueDescriptorImpl(Project project) { myProject = project; } + private void assertValueReady() { + if (!myValueReady) { + LOG.error("Value is not yet calculated for " + getClass()); + } + } + @Override public boolean isArray() { + assertValueReady(); return myValue instanceof ArrayReference; } - public boolean isDirty() { + public boolean isDirty() { + assertValueReady(); return myIsDirty; } @Override public boolean isLvalue() { + assertValueReady(); return myIsLvalue; } @Override public boolean isNull() { + assertValueReady(); return myValue == null; } @Override public boolean isString() { + assertValueReady(); return myValue instanceof StringReference; } @Override public boolean isPrimitive() { + assertValueReady(); return myValue instanceof PrimitiveValue; } @@ -147,7 +162,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements semaphore.waitFor(); } } - + + assertValueReady(); return myValue; } @@ -190,6 +206,9 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements myValue = getTargetExceptionWithStackTraceFilled(evaluationContext, e); myIsExpandable = false; } + finally { + myValueReady = true; + } myIsNew = false; } @@ -239,7 +258,11 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements public void setAncestor(NodeDescriptor oldDescriptor) { super.setAncestor(oldDescriptor); myIsNew = false; - myValue = ((ValueDescriptorImpl)oldDescriptor).getValue(); + ValueDescriptorImpl other = (ValueDescriptorImpl)oldDescriptor; + if (other.myValueReady) { + myValue = other.getValue(); + myValueReady = true; + } } protected void setLvalue(boolean value) { @@ -282,8 +305,8 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements private String getCustomLabel(String label) { //translate only strings in quotes String customLabel = null; - final Value value = getValue(); - if(isShowIdLabel()) { + if(isShowIdLabel() && myValueReady) { + final Value value = getValue(); Renderer lastRenderer = getLastRenderer(); final EvaluationContextImpl evalContext = myStoredEvaluationContext; final String idLabel = evalContext != null && lastRenderer != null && !evalContext.getSuspendContext().isResumed()? diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java index 38cba3c27981..9615aae98233 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ArrayRenderer.java @@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerContext; import com.intellij.debugger.engine.DebuggerManagerThreadImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContext; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.settings.ViewsGeneralSettings; import com.intellij.debugger.ui.impl.watch.ArrayElementDescriptorImpl; import com.intellij.debugger.ui.impl.watch.MessageDescriptor; @@ -126,7 +127,12 @@ public class ArrayRenderer extends NodeRendererImpl{ DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext); if (arrayItemNode == null) continue; - if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue; + if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS) { + // need to init value to be able to ask for null + ValueDescriptorImpl descriptor = (ValueDescriptorImpl)arrayItemNode.getDescriptor(); + descriptor.setContext((EvaluationContextImpl)evaluationContext); + if (descriptor.isNull()) continue; + } //if(added >= (ENTRIES_LIMIT + 1)/ 2) break; children.add(arrayItemNode); added++; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java index bdf89a5c79b9..bd14ef55b054 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ClassRenderer.java @@ -110,9 +110,11 @@ public class ClassRenderer extends NodeRendererImpl{ final StringBuilder buf = StringBuilderSpinAllocator.alloc(); try { if (value instanceof StringReference) { - buf.append('\"'); - buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value())); - buf.append('\"'); + // no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation + //buf.append('\"'); + //buf.append(DebuggerUtils.convertToPresentationString(((StringReference)value).value())); + //buf.append('\"'); + buf.append(((StringReference)value).value()); } else if (value instanceof ClassObjectReference) { ReferenceType type = ((ClassObjectReference)value).reflectedType(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java index 6a967533f304..fd77aa900a7c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ToStringRenderer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 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. @@ -38,6 +38,8 @@ import org.jetbrains.annotations.NonNls; import java.util.Iterator; +import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING; + public class ToStringRenderer extends NodeRendererImpl { public static final @NonNls String UNIQUE_ID = "ToStringRenderer"; @@ -76,7 +78,8 @@ public class ToStringRenderer extends NodeRendererImpl { BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess()).invoke(new ToStringCommand(evaluationContext, value) { public void evaluationResult(String message) { valueDescriptor.setValueLabel( - message == null? "" : "\"" + DebuggerUtils.convertToPresentationString(DebuggerUtilsEx.truncateString(message)) + "\"" + // no need to add quotes and escape characters here, XValueTextRendererImpl handles the presentation + message == null? "" : /*"\"" + DebuggerUtils.convertToPresentationString(*/DebuggerUtilsEx.truncateString(message)/*) + "\""*/ ); labelListener.labelChanged(); } @@ -103,7 +106,7 @@ public class ToStringRenderer extends NodeRendererImpl { return false; } - if(type.name().equals("java.lang.String")) { + if(JAVA_LANG_STRING.equals(type.name())) { return false; // do not render 'String' objects for performance reasons } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java index 2afcf0fd339f..a4bac85f4995 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointFiltersPanel.java @@ -28,6 +28,7 @@ import com.intellij.ui.classFilter.ClassFilter; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; +import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; @@ -138,7 +139,7 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex public boolean isVisibleOnPopup(@NotNull B breakpoint) { JavaBreakpointProperties properties = breakpoint.getProperties(); if (properties != null) { - return properties.COUNT_FILTER_ENABLED || properties.CLASS_FILTERS_ENABLED || properties.INSTANCE_FILTERS_ENABLED; + return properties.isCOUNT_FILTER_ENABLED() || properties.isCLASS_FILTERS_ENABLED() || properties.isINSTANCE_FILTERS_ENABLED(); } return false; } @@ -150,27 +151,30 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex return; } + boolean changed = false; try { String text = myPassCountField.getText().trim(); - properties.COUNT_FILTER = !text.isEmpty() ? Integer.parseInt(text) : 0; - if (properties.COUNT_FILTER < 0) { - properties.COUNT_FILTER = 0; - } + int filter = !text.isEmpty() ? Integer.parseInt(text) : 0; + if (filter < 0) filter = 0; + changed = properties.setCOUNT_FILTER(filter); } catch (Exception ignored) { } - properties.COUNT_FILTER_ENABLED = properties.COUNT_FILTER > 0 && myPassCountCheckbox.isSelected(); + changed = properties.setCOUNT_FILTER_ENABLED(properties.getCOUNT_FILTER() > 0 && myPassCountCheckbox.isSelected()) || changed; reloadInstanceFilters(); reloadClassFilters(); updateInstanceFilterEditor(true); updateClassFilterEditor(true); - properties.INSTANCE_FILTERS_ENABLED = myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected(); - properties.CLASS_FILTERS_ENABLED = myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected(); - properties.setClassFilters(myClassFilters); - properties.setClassExclusionFilters(myClassExclusionFilters); - properties.setInstanceFilters(myInstanceFilters); + changed = properties.setINSTANCE_FILTERS_ENABLED(myInstanceFiltersField.getText().length() > 0 && myInstanceFiltersCheckBox.isSelected()) || changed; + changed = properties.setCLASS_FILTERS_ENABLED(myClassFiltersField.getText().length() > 0 && myClassFiltersCheckBox.isSelected()) || changed; + changed = properties.setClassFilters(myClassFilters) || changed; + changed = properties.setClassExclusionFilters(myClassExclusionFilters) || changed; + changed = properties.setInstanceFilters(myInstanceFilters) || changed; + if (changed) { + ((XBreakpointBase)breakpoint).fireBreakpointChanged(); + } } private static void insert(JPanel panel, JComponent component) { @@ -182,24 +186,24 @@ public class JavaBreakpointFiltersPanel<T extends JavaBreakpointProperties, B ex public void loadFrom(@NotNull B breakpoint) { JavaBreakpointProperties properties = breakpoint.getProperties(); if (properties != null) { - if (properties.COUNT_FILTER > 0) { - myPassCountField.setText(Integer.toString(properties.COUNT_FILTER)); + if (properties.getCOUNT_FILTER() > 0) { + myPassCountField.setText(Integer.toString(properties.getCOUNT_FILTER())); } else { myPassCountField.setText(""); } - myPassCountCheckbox.setSelected(properties.COUNT_FILTER_ENABLED); + myPassCountCheckbox.setSelected(properties.isCOUNT_FILTER_ENABLED()); - myInstanceFiltersCheckBox.setSelected(properties.INSTANCE_FILTERS_ENABLED); - myInstanceFiltersField.setEnabled(properties.INSTANCE_FILTERS_ENABLED); - myInstanceFiltersField.getTextField().setEditable(properties.INSTANCE_FILTERS_ENABLED); + myInstanceFiltersCheckBox.setSelected(properties.isINSTANCE_FILTERS_ENABLED()); + myInstanceFiltersField.setEnabled(properties.isINSTANCE_FILTERS_ENABLED()); + myInstanceFiltersField.getTextField().setEditable(properties.isINSTANCE_FILTERS_ENABLED()); myInstanceFilters = properties.getInstanceFilters(); updateInstanceFilterEditor(true); - myClassFiltersCheckBox.setSelected(properties.CLASS_FILTERS_ENABLED); - myClassFiltersField.setEnabled(properties.CLASS_FILTERS_ENABLED); - myClassFiltersField.getTextField().setEditable(properties.CLASS_FILTERS_ENABLED); + myClassFiltersCheckBox.setSelected(properties.isCLASS_FILTERS_ENABLED()); + myClassFiltersField.setEnabled(properties.isCLASS_FILTERS_ENABLED()); + myClassFiltersField.getTextField().setEditable(properties.isCLASS_FILTERS_ENABLED()); myClassFilters = properties.getClassFilters(); myClassExclusionFilters = properties.getClassExclusionFilters(); updateClassFilterEditor(true); diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java index daab63a93265..599aed3dd0dd 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/properties/JavaBreakpointProperties.java @@ -16,6 +16,7 @@ package org.jetbrains.java.debugger.breakpoints.properties; import com.intellij.debugger.InstanceFilter; +import com.intellij.openapi.util.Comparing; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.xmlb.annotations.AbstractCollection; import com.intellij.util.xmlb.annotations.OptionTag; @@ -27,18 +28,14 @@ import org.jetbrains.annotations.Nullable; * @author egor */ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extends XBreakpointProperties<T> { - @OptionTag("count-filter-enabled") - public boolean COUNT_FILTER_ENABLED = false; - @OptionTag("count-filter") - public int COUNT_FILTER = 0; + private boolean COUNT_FILTER_ENABLED = false; + private int COUNT_FILTER = 0; - @OptionTag("class-filters-enabled") - public boolean CLASS_FILTERS_ENABLED = false; + private boolean CLASS_FILTERS_ENABLED = false; private ClassFilter[] myClassFilters; private ClassFilter[] myClassExclusionFilters; - @OptionTag("instance-filters-enabled") - public boolean INSTANCE_FILTERS_ENABLED = false; + private boolean INSTANCE_FILTERS_ENABLED = false; private InstanceFilter[] myInstanceFilters; @Tag("instance-filters") @@ -47,8 +44,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend return myInstanceFilters != null ? myInstanceFilters : InstanceFilter.EMPTY_ARRAY; } - public void setInstanceFilters(InstanceFilter[] instanceFilters) { + public boolean setInstanceFilters(InstanceFilter[] instanceFilters) { + boolean changed = !Comparing.equal(myInstanceFilters, instanceFilters); myInstanceFilters = instanceFilters; + return changed; } public void addInstanceFilter(long l) { @@ -64,8 +63,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend return myClassFilters != null ? myClassFilters : ClassFilter.EMPTY_ARRAY; } - public final void setClassFilters(ClassFilter[] classFilters) { + public final boolean setClassFilters(ClassFilter[] classFilters) { + boolean changed = !Comparing.equal(myClassFilters, classFilters); myClassFilters = classFilters; + return changed; } @Tag("class-exclusion-filters") @@ -74,8 +75,10 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend return myClassExclusionFilters != null ? myClassExclusionFilters : ClassFilter.EMPTY_ARRAY; } - public void setClassExclusionFilters(ClassFilter[] classExclusionFilters) { + public boolean setClassExclusionFilters(ClassFilter[] classExclusionFilters) { + boolean changed = !Comparing.equal(myClassExclusionFilters, classExclusionFilters); myClassExclusionFilters = classExclusionFilters; + return changed; } @Nullable @@ -86,14 +89,58 @@ public class JavaBreakpointProperties<T extends JavaBreakpointProperties> extend @Override public void loadState(T state) { - COUNT_FILTER_ENABLED = state.COUNT_FILTER_ENABLED; - COUNT_FILTER = state.COUNT_FILTER; + setCOUNT_FILTER_ENABLED(state.isCOUNT_FILTER_ENABLED()); + setCOUNT_FILTER(state.getCOUNT_FILTER()); - CLASS_FILTERS_ENABLED = state.CLASS_FILTERS_ENABLED; + setCLASS_FILTERS_ENABLED(state.isCLASS_FILTERS_ENABLED()); myClassFilters = state.getClassFilters(); myClassExclusionFilters = state.getClassExclusionFilters(); - INSTANCE_FILTERS_ENABLED = state.INSTANCE_FILTERS_ENABLED; + setINSTANCE_FILTERS_ENABLED(state.isINSTANCE_FILTERS_ENABLED()); myInstanceFilters = state.getInstanceFilters(); } + + @OptionTag("count-filter-enabled") + public boolean isCOUNT_FILTER_ENABLED() { + return COUNT_FILTER_ENABLED; + } + + public boolean setCOUNT_FILTER_ENABLED(boolean COUNT_FILTER_ENABLED) { + boolean changed = this.COUNT_FILTER_ENABLED != COUNT_FILTER_ENABLED; + this.COUNT_FILTER_ENABLED = COUNT_FILTER_ENABLED; + return changed; + } + + @OptionTag("count-filter") + public int getCOUNT_FILTER() { + return COUNT_FILTER; + } + + public boolean setCOUNT_FILTER(int COUNT_FILTER) { + boolean changed = this.COUNT_FILTER != COUNT_FILTER; + this.COUNT_FILTER = COUNT_FILTER; + return changed; + } + + @OptionTag("class-filters-enabled") + public boolean isCLASS_FILTERS_ENABLED() { + return CLASS_FILTERS_ENABLED; + } + + public boolean setCLASS_FILTERS_ENABLED(boolean CLASS_FILTERS_ENABLED) { + boolean changed = this.CLASS_FILTERS_ENABLED != CLASS_FILTERS_ENABLED; + this.CLASS_FILTERS_ENABLED = CLASS_FILTERS_ENABLED; + return changed; + } + + @OptionTag("instance-filters-enabled") + public boolean isINSTANCE_FILTERS_ENABLED() { + return INSTANCE_FILTERS_ENABLED; + } + + public boolean setINSTANCE_FILTERS_ENABLED(boolean INSTANCE_FILTERS_ENABLED) { + boolean changed = this.INSTANCE_FILTERS_ENABLED != INSTANCE_FILTERS_ENABLED; + this.INSTANCE_FILTERS_ENABLED = INSTANCE_FILTERS_ENABLED; + return changed; + } } |