diff options
Diffstat (limited to 'java/debugger/impl/src/com')
44 files changed, 898 insertions, 390 deletions
diff --git a/java/debugger/impl/src/com/intellij/debugger/DebugUIEnvironment.java b/java/debugger/impl/src/com/intellij/debugger/DebugUIEnvironment.java index 8c89bada270d..04f4d583cf99 100644 --- a/java/debugger/impl/src/com/intellij/debugger/DebugUIEnvironment.java +++ b/java/debugger/impl/src/com/intellij/debugger/DebugUIEnvironment.java @@ -15,7 +15,6 @@ */ package com.intellij.debugger; -import com.intellij.diagnostic.logging.LogFilesManager; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.openapi.actionSystem.DefaultActionGroup; @@ -37,8 +36,6 @@ public interface DebugUIEnvironment { @Nullable Icon getIcon(); - void initLogs(RunContentDescriptor content, LogFilesManager logFilesManager); - void initActions(RunContentDescriptor content, DefaultActionGroup actionGroup); @Nullable diff --git a/java/debugger/impl/src/com/intellij/debugger/DefaultDebugUIEnvironment.java b/java/debugger/impl/src/com/intellij/debugger/DefaultDebugUIEnvironment.java index f29f3bfe572d..6f8b13e4d06a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/DefaultDebugUIEnvironment.java +++ b/java/debugger/impl/src/com/intellij/debugger/DefaultDebugUIEnvironment.java @@ -15,14 +15,10 @@ */ package com.intellij.debugger; -import com.intellij.diagnostic.logging.LogFilesManager; -import com.intellij.diagnostic.logging.OutputFileUtil; import com.intellij.execution.Executor; import com.intellij.execution.configurations.RemoteConnection; -import com.intellij.execution.configurations.RunConfigurationBase; import com.intellij.execution.configurations.RunProfile; import com.intellij.execution.configurations.RunProfileState; -import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.RestartAction; import com.intellij.execution.ui.RunContentDescriptor; @@ -64,21 +60,6 @@ public class DefaultDebugUIEnvironment implements DebugUIEnvironment { } @Override - public void initLogs(RunContentDescriptor content, LogFilesManager logFilesManager) { - ProcessHandler processHandler = content.getProcessHandler(); - if (getRunProfile() instanceof RunConfigurationBase) { - RunConfigurationBase runConfiguration = (RunConfigurationBase)getRunProfile(); - - logFilesManager.registerFileMatcher(runConfiguration); - - if (processHandler != null) { - logFilesManager.initLogConsoles(runConfiguration, processHandler); - OutputFileUtil.attachDumpListener(runConfiguration, processHandler, content.getExecutionConsole()); - } - } - } - - @Override public void initActions(RunContentDescriptor content, DefaultActionGroup actionGroup) { Executor executor = myExecutionEnvironment.getExecutor(); RestartAction restartAction = new RestartAction(content, myExecutionEnvironment); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java index ce375815bb77..0f5398a56cba 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/AdjustArrayRangeAction.java @@ -16,6 +16,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaValue; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.ArrayRendererConfigurable; @@ -27,6 +28,9 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.options.Configurable; import com.intellij.openapi.options.ShowSettingsUtil; import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.Nullable; public class AdjustArrayRangeAction extends DebuggerAction { @@ -44,42 +48,48 @@ public class AdjustArrayRangeAction extends DebuggerAction { final Project project = debuggerContext.getProject(); - final DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); - if (selectedNode == null) { + final XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); + if (node == null) { return; } - NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); - if(!(descriptor instanceof ValueDescriptorImpl /*&& ((ValueDescriptorImpl)descriptor).isArray()*/)) { + + XValue container = node.getValueContainer(); + if (!(container instanceof JavaValue)) { return; } - final ArrayRenderer renderer = getArrayRenderer((ValueDescriptorImpl)descriptor)/*(ArrayRenderer)((ValueDescriptorImpl)selectedNode.getDescriptor()).getLastRenderer()*/; + final ValueDescriptorImpl descriptor = ((JavaValue)container).getDescriptor(); + ArrayRenderer renderer = getArrayRenderer(descriptor); if (renderer == null) { return; } - String title = createNodeTitle("", selectedNode); - String label = selectedNode.toString(); - int index = label.indexOf('='); - if (index > 0) { - title = title + " " + label.substring(index); - } + //String title = createNodeTitle("", selectedNode); + //String label = selectedNode.toString(); + //int index = label.indexOf('='); + //if (index > 0) { + // title = title + " " + label.substring(index); + //} + String title = node.getName(); final ArrayRenderer clonedRenderer = renderer.clone(); + clonedRenderer.setForced(true); if (ShowSettingsUtil.getInstance().editConfigurable(project, new NamedArrayConfigurable(title, clonedRenderer))) { debugProcess.getManagerThread().schedule(new SuspendContextCommandImpl(debuggerContext.getSuspendContext()) { @Override public void contextAction() throws Exception { - final ValueDescriptorImpl nodeDescriptor = (ValueDescriptorImpl)selectedNode.getDescriptor(); - final Renderer lastRenderer = nodeDescriptor.getLastRenderer(); + final Renderer lastRenderer = descriptor.getLastRenderer(); if (lastRenderer instanceof ArrayRenderer) { - selectedNode.setRenderer(clonedRenderer); + descriptor.setRenderer(clonedRenderer); + refreshViews(node); + //selectedNode.setRenderer(clonedRenderer); } else if (lastRenderer instanceof CompoundNodeRenderer) { final CompoundNodeRenderer compoundRenderer = (CompoundNodeRenderer)lastRenderer; final ChildrenRenderer childrenRenderer = compoundRenderer.getChildrenRenderer(); if (childrenRenderer instanceof ExpressionChildrenRenderer) { - ExpressionChildrenRenderer.setPreferableChildrenRenderer(nodeDescriptor, clonedRenderer); - selectedNode.calcRepresentation(); + ExpressionChildrenRenderer.setPreferableChildrenRenderer(descriptor, clonedRenderer); + refreshViews(node); + //selectedNode.calcRepresentation(); } } } @@ -90,10 +100,14 @@ public class AdjustArrayRangeAction extends DebuggerAction { @Override public void update(AnActionEvent e) { boolean enable = false; - DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); - if(selectedNode != null) { - NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); - enable = descriptor instanceof ValueDescriptorImpl && getArrayRenderer((ValueDescriptorImpl)descriptor) != null; + XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); + if (node == null) { + return; + } + XValue container = node.getValueContainer(); + if (container instanceof JavaValue) { + ValueDescriptorImpl descriptor = ((JavaValue)container).getDescriptor(); + enable = getArrayRenderer(descriptor) != null; } e.getPresentation().setVisible(enable); } 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 86ddfaa5fc08..2e87aa973285 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/DebuggerAction.java @@ -22,6 +22,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerStateManager; import com.intellij.debugger.ui.impl.DebuggerTreePanel; @@ -32,6 +33,11 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.project.Project; import com.intellij.ui.DoubleClickListener; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.impl.frame.XDebugView; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -153,4 +159,18 @@ public abstract class DebuggerAction extends AnAction { } }); } + + public static void refreshViews(@NotNull XValueNodeImpl node) { + refreshViews(XDebugView.getSession(node.getTree())); + } + + public static void refreshViews(@Nullable XDebugSession session) { + if (session != null) { + XDebugProcess process = session.getDebugProcess(); + if (process instanceof JavaDebugProcess) { + ((JavaDebugProcess)process).saveNodeHistory(); + } + session.rebuildViews(); + } + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java index dcd0454c16aa..282a6dc9f30b 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaMarkObjectActionHandler.java @@ -50,6 +50,8 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import static com.intellij.openapi.actionSystem.PlatformDataKeys.CONTEXT_COMPONENT; + /* * Class SetValueAction * @author Jeka @@ -71,7 +73,8 @@ public class JavaMarkObjectActionHandler extends MarkObjectActionHandler { final DebuggerTree tree = node.getTree(); tree.saveState(node); - + + final Component parent = event.getData(CONTEXT_COMPONENT); final ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl)descriptor); final DebuggerContextImpl debuggerContext = tree.getDebuggerContext(); final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); @@ -93,7 +96,7 @@ public class JavaMarkObjectActionHandler extends MarkObjectActionHandler { final boolean suggestAdditionalMarkup = canSuggestAdditionalMarkup(debugProcess, valueDescriptor.getValue()); SwingUtilities.invokeAndWait(new Runnable() { public void run() { - ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(defaultText, suggestAdditionalMarkup); + ObjectMarkupPropertiesDialog dialog = new ObjectMarkupPropertiesDialog(parent, defaultText, suggestAdditionalMarkup); dialog.show(); if (dialog.isOK()) { result.set(Pair.create(dialog.getConfiguredMarkup(), dialog.isMarkAdditionalFields())); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java index 815ddd231f14..a362e7d7caff 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaReferringObjectsValue.java @@ -61,6 +61,7 @@ public class JavaReferringObjectsValue extends JavaValue { @Override public void computeChildren(@NotNull final XCompositeNode node) { + if (checkContextNotResumed(node)) return; getEvaluationContext().getDebugProcess().getManagerThread().schedule( new SuspendContextCommandImpl(getEvaluationContext().getSuspendContext()) { @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java index cd4aa14b7703..454b130307cf 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ObjectMarkupPropertiesDialog.java @@ -20,6 +20,7 @@ import com.intellij.openapi.ui.ex.MultiLineLabel; import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialogBase; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; @@ -35,8 +36,8 @@ public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialogB private JPanel myAdditionalPropertiesPanel; private MultiLineLabel myDescriptionLabel; - public ObjectMarkupPropertiesDialog(@NotNull final String defaultText, boolean suggestAdditionalMarkup) { - super(defaultText); + public ObjectMarkupPropertiesDialog(@Nullable Component parent, @NotNull final String defaultText, boolean suggestAdditionalMarkup) { + super(parent, defaultText); mySuggestAdditionalMarkup = suggestAdditionalMarkup; myDescriptionLabel.setText("If the value is referenced by a constant field of an abstract class,\n" + "IDEA could additionally mark all values referenced from this class with the names of referencing fields."); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java index f5aa685c7994..f89ae5ce8292 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java @@ -19,68 +19,212 @@ */ package com.intellij.debugger.actions; +import com.intellij.CommonBundle; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.JavaStackFrame; import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; -import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.actionSystem.ActionPlaces; import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.DialogWrapper; +import com.intellij.openapi.ui.MessageDialogBuilder; import com.intellij.openapi.ui.Messages; +import com.intellij.psi.PsiCodeBlock; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiStatement; +import com.intellij.psi.PsiTryStatement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.containers.ContainerUtil; +import com.intellij.util.ui.UIUtil; import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerBundle; import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.evaluation.EvaluationMode; +import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.sun.jdi.InvalidStackFrameException; import com.sun.jdi.NativeMethodException; import com.sun.jdi.VMDisconnectedException; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + public class PopFrameAction extends DebuggerAction { public void actionPerformed(AnActionEvent e) { - Project project = e.getData(CommonDataKeys.PROJECT); - StackFrameProxyImpl stackFrame = getStackFrameProxy(e); + final Project project = e.getData(CommonDataKeys.PROJECT); + final JavaStackFrame stackFrame = getStackFrame(e); if(stackFrame == null) { return; } try { - DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); - DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); if(debugProcess == null) { return; } - debugProcess.getManagerThread().schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame)); + + if (!DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { + List<PsiStatement> statements = getFinallyStatements(debuggerContext.getSourcePosition()); + if (!statements.isEmpty()) { + StringBuilder sb = new StringBuilder(); + for (PsiStatement statement : statements) { + sb.append("\n").append(statement.getText()); + } + if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME)) { + evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb); + return; + } + else { + int res = MessageDialogBuilder + .yesNoCancel(UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), + DebuggerBundle.message("warning.finally.block.detected") + sb) + .project(project) + .icon(Messages.getWarningIcon()) + .yesText(DebuggerBundle.message("button.execute.finally")) + .noText(DebuggerBundle.message("button.drop.anyway")) + .cancelText(CommonBundle.message("button.cancel")) + .doNotAsk( + new DialogWrapper.DoNotAskOption() { + @Override + public boolean isToBeShown() { + return !DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME) && + !DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME); + } + + @Override + public void setToBeShown(boolean value, int exitCode) { + if (!value) { + DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = + exitCode == Messages.YES ? DebuggerSettings.EVALUATE_FINALLY_ALWAYS : DebuggerSettings.EVALUATE_FINALLY_NEVER; + } + else { + DebuggerSettings.getInstance().EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK; + } + } + + @Override + public boolean canBeHidden() { + return true; + } + + @Override + public boolean shouldSaveOptionsOnCancel() { + return false; + } + + @NotNull + @Override + public String getDoNotShowMessage() { + return CommonBundle.message("dialog.options.do.not.show"); + } + }) + .show(); + + switch (res) { + case Messages.CANCEL: + return; + case Messages.NO: + break; + case Messages.YES: // evaluate finally + evaluateAndPop(project, stackFrame, debuggerContext, debugProcess, sb); + return; + } + } + } + } + debugProcess.getManagerThread().schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy())); } catch (NativeMethodException e2){ - Messages.showMessageDialog(project, DebuggerBundle.message("error.native.method.exception"), ActionsBundle.actionText(DebuggerActions.POP_FRAME), Messages.getErrorIcon()); + Messages.showMessageDialog(project, DebuggerBundle.message("error.native.method.exception"), + UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), Messages.getErrorIcon()); } catch (InvalidStackFrameException ignored) { } - catch(VMDisconnectedException vde) { + catch(VMDisconnectedException ignored) { } } - @Nullable - private static StackFrameProxyImpl getStackFrameProxy(AnActionEvent e) { - DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); - if(selectedNode != null) { - NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); - if(descriptor instanceof StackFrameDescriptorImpl) { - if(selectedNode.getNextSibling() != null) { - StackFrameDescriptorImpl frameDescriptor = ((StackFrameDescriptorImpl)descriptor); - return frameDescriptor.getFrameProxy(); - } - return null; - } - else if(descriptor instanceof ThreadDescriptorImpl || descriptor instanceof ThreadGroupDescriptorImpl) { - return null; + private static void evaluateAndPop(final Project project, + final JavaStackFrame stackFrame, + final DebuggerContextImpl debuggerContext, + final DebugProcessImpl debugProcess, StringBuilder sb) { + XDebuggerEvaluator evaluator = stackFrame.getEvaluator(); + if (evaluator != null) { + evaluator.evaluate(XExpressionImpl.fromText(sb.toString(), EvaluationMode.CODE_FRAGMENT), + new XDebuggerEvaluator.XEvaluationCallback() { + @Override + public void evaluated(@NotNull XValue result) { + debugProcess.getManagerThread() + .schedule(debugProcess.createPopFrameCommand(debuggerContext, stackFrame.getStackFrameProxy())); + } + + @Override + public void errorOccurred(@NotNull final String errorMessage) { + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + Messages + .showMessageDialog(project, DebuggerBundle.message("error.executing.finally", errorMessage), + UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), + Messages.getErrorIcon()); + } + }); + } + }, stackFrame.getSourcePosition()); + } + else { + Messages.showMessageDialog(project, XDebuggerBundle.message("xdebugger.evaluate.stack.frame.has.not.evaluator"), + UIUtil.removeMnemonic(ActionsBundle.actionText(DebuggerActions.POP_FRAME)), + Messages.getErrorIcon()); + } + } + + private static List<PsiStatement> getFinallyStatements(SourcePosition position) { + List<PsiStatement> res = new ArrayList<PsiStatement>(); + PsiElement element = position.getFile().findElementAt(position.getOffset()); + PsiTryStatement tryStatement = PsiTreeUtil.getParentOfType(element, PsiTryStatement.class); + while (tryStatement != null) { + PsiCodeBlock finallyBlock = tryStatement.getFinallyBlock(); + if (finallyBlock != null) { + ContainerUtil.addAll(res, finallyBlock.getStatements()); } + tryStatement = PsiTreeUtil.getParentOfType(tryStatement, PsiTryStatement.class); } + return res; + } + + @Nullable + private static JavaStackFrame getStackFrame(AnActionEvent e) { + //DebuggerTreeNodeImpl selectedNode = getSelectedNode(e.getDataContext()); + //if(selectedNode != null) { + // NodeDescriptorImpl descriptor = selectedNode.getDescriptor(); + // if(descriptor instanceof StackFrameDescriptorImpl) { + // if(selectedNode.getNextSibling() != null) { + // StackFrameDescriptorImpl frameDescriptor = ((StackFrameDescriptorImpl)descriptor); + // return frameDescriptor.getFrameProxy(); + // } + // return null; + // } + // else if(descriptor instanceof ThreadDescriptorImpl || descriptor instanceof ThreadGroupDescriptorImpl) { + // return null; + // } + //} Project project = e.getProject(); if (project != null) { @@ -89,18 +233,19 @@ public class PopFrameAction extends DebuggerAction { XStackFrame frame = session.getCurrentStackFrame(); if (frame instanceof JavaStackFrame) { StackFrameProxyImpl proxy = ((JavaStackFrame)frame).getStackFrameProxy(); - return !proxy.isBottom() ? proxy : null; + return !proxy.isBottom() ? ((JavaStackFrame)frame) : null; } } } - DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); - StackFrameProxyImpl frameProxy = debuggerContext.getFrameProxy(); - - if(frameProxy == null || frameProxy.isBottom()) { - return null; - } - return frameProxy; + //DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); + //StackFrameProxyImpl frameProxy = debuggerContext.getFrameProxy(); + // + //if(frameProxy == null || frameProxy.isBottom()) { + // return null; + //} + //return frameProxy; + return null; } private static boolean isAtBreakpoint(AnActionEvent e) { @@ -118,14 +263,14 @@ public class PopFrameAction extends DebuggerAction { public void update(AnActionEvent e) { boolean enable = false; - StackFrameProxyImpl stackFrameProxy = getStackFrameProxy(e); + JavaStackFrame stackFrame = getStackFrame(e); - if(stackFrameProxy != null && isAtBreakpoint(e)) { - VirtualMachineProxyImpl virtualMachineProxy = stackFrameProxy.getVirtualMachine(); + if(stackFrame != null && isAtBreakpoint(e)) { + VirtualMachineProxyImpl virtualMachineProxy = stackFrame.getStackFrameProxy().getVirtualMachine(); enable = virtualMachineProxy.canPopFrames(); } - if(ActionPlaces.MAIN_MENU.equals(e.getPlace()) || ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) { + if(ActionPlaces.isMainMenuOrActionSearch(e.getPlace()) || ActionPlaces.DEBUGGER_TOOLBAR.equals(e.getPlace())) { e.getPresentation().setEnabled(enable); } else { diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java index bd8efab637ac..fd0d8f6785b3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java @@ -22,13 +22,11 @@ import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.debugger.ui.tree.render.NodeRenderer; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.DumbAware; import com.intellij.xdebugger.frame.XValue; -import com.intellij.xdebugger.frame.XValuePlace; import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NotNull; @@ -66,7 +64,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { } XValue container = node.getValueContainer(); if (container instanceof JavaValue) { - if (((ValueDescriptorImpl)((JavaValue)container).getDescriptor()).getLastRenderer() != myNodeRenderer) { + if (((JavaValue)container).getDescriptor().getLastRenderer() != myNodeRenderer) { return false; } } @@ -83,11 +81,12 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { public void threadAction() { XValue container = node.getValueContainer(); if (container instanceof JavaValue) { - final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)((JavaValue)container).getDescriptor(); + final ValueDescriptorImpl valueDescriptor = ((JavaValue)container).getDescriptor(); if (state) { valueDescriptor.setRenderer(myNodeRenderer); - valueDescriptor.updateRepresentation(debuggerContext.createEvaluationContext(), DescriptorLabelListener.DUMMY_LISTENER); - container.computePresentation(node, XValuePlace.TREE); + DebuggerAction.refreshViews(node); + //valueDescriptor.updateRepresentation(debuggerContext.createEvaluationContext(), DescriptorLabelListener.DUMMY_LISTENER); + //container.computePresentation(node, XValuePlace.TREE); } } } 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 4714ca49bd06..7640a959597e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessEvents.java @@ -29,7 +29,6 @@ import com.intellij.debugger.requests.Requestor; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.DebuggerPanelsManager; import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.debugger.ui.breakpoints.LineBreakpoint; import com.intellij.execution.configurations.RemoteConnection; import com.intellij.openapi.application.ApplicationManager; @@ -57,15 +56,15 @@ import com.sun.jdi.request.ThreadStartRequest; * @author lex */ public class DebugProcessEvents extends DebugProcessImpl { - private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.DebugProcessEvents"); + private static final Logger LOG = Logger.getInstance(DebugProcessEvents.class); + private DebuggerEventThread myEventThread; - private final BreakpointManager myBreakpointManager; public DebugProcessEvents(Project project) { super(project); - myBreakpointManager = DebuggerManagerEx.getInstanceEx(getProject()).getBreakpointManager(); } + @Override protected void commitVM(final VirtualMachine vm) { super.commitVM(vm); if(vm != null) { @@ -134,18 +133,19 @@ public class DebugProcessEvents extends DebugProcessImpl { return myIsStopped; } + @Override public void run() { try { EventQueue eventQueue = myVmProxy.eventQueue(); while (!isStopped()) { try { final EventSet eventSet = eventQueue.remove(); - + final boolean methodWatcherActive = myReturnValueWatcher != null && myReturnValueWatcher.isEnabled(); int processed = 0; for (EventIterator eventIterator = eventSet.eventIterator(); eventIterator.hasNext();) { final Event event = eventIterator.nextEvent(); - + if (methodWatcherActive) { if (event instanceof MethodExitEvent) { if (myReturnValueWatcher.processMethodExitEvent((MethodExitEvent)event)) { @@ -158,6 +158,7 @@ public class DebugProcessEvents extends DebugProcessImpl { processed++; final ThreadReference thread = ((ThreadStartEvent)event).thread(); getManagerThread().schedule(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { getVirtualMachineProxy().threadStarted(thread); myDebugProcessDispatcher.getMulticaster().threadStarted(DebugProcessEvents.this, thread); @@ -168,6 +169,7 @@ public class DebugProcessEvents extends DebugProcessImpl { processed++; final ThreadReference thread = ((ThreadDeathEvent)event).thread(); getManagerThread().schedule(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { getVirtualMachineProxy().threadStopped(thread); myDebugProcessDispatcher.getMulticaster().threadStopped(DebugProcessEvents.this, thread); @@ -175,15 +177,15 @@ public class DebugProcessEvents extends DebugProcessImpl { }); } } - + if (processed == eventSet.size()) { eventSet.resume(); continue; } getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { - if (eventSet.suspendPolicy() == EventRequest.SUSPEND_ALL && !DebuggerSession.enableBreakpointsDuringEvaluation()) { // check if there is already one request with policy SUSPEND_ALL for (SuspendContextImpl context : getSuspendManager().getEventContexts()) { @@ -193,12 +195,10 @@ public class DebugProcessEvents extends DebugProcessImpl { } } } - + final SuspendContextImpl suspendContext = getSuspendManager().pushSuspendContext(eventSet); - for (EventIterator eventIterator = eventSet.eventIterator(); eventIterator.hasNext();) { final Event event = eventIterator.nextEvent(); - //if (LOG.isDebugEnabled()) { // LOG.debug("EVENT : " + event); //} @@ -207,10 +207,7 @@ public class DebugProcessEvents extends DebugProcessImpl { //Sun WTK fails when J2ME when event set is resumed on VMStartEvent processVMStartEvent(suspendContext, (VMStartEvent)event); } - else if (event instanceof VMDeathEvent) { - processVMDeathEvent(suspendContext, event); - } - else if (event instanceof VMDisconnectEvent) { + else if (event instanceof VMDeathEvent || event instanceof VMDisconnectEvent) { processVMDeathEvent(suspendContext, event); } else if (event instanceof ClassPrepareEvent) { @@ -240,7 +237,6 @@ public class DebugProcessEvents extends DebugProcessImpl { } } }); - } catch (InternalException e) { LOG.debug(e); @@ -264,13 +260,15 @@ public class DebugProcessEvents extends DebugProcessImpl { } catch (VMDisconnectedException e) { invokeVMDeathEvent(); - } finally { + } + finally { Thread.interrupted(); // reset interrupted status } } private void invokeVMDeathEvent() { getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + @Override protected void action() throws Exception { SuspendContextImpl suspendContext = getSuspendManager().pushSuspendContext(EventRequest.SUSPEND_NONE, 1); processVMDeathEvent(suspendContext, null); @@ -307,7 +305,7 @@ public class DebugProcessEvents extends DebugProcessImpl { if(myState.compareAndSet(STATE_INITIAL, STATE_ATTACHED)) { final VirtualMachineProxyImpl machineProxy = getVirtualMachineProxy(); final EventRequestManager requestManager = machineProxy.eventRequestManager(); - + if (machineProxy.canGetMethodReturnValues()) { myReturnValueWatcher = new MethodReturnValueWatcher(requestManager); } @@ -378,7 +376,7 @@ public class DebugProcessEvents extends DebugProcessImpl { RequestHint hint = (RequestHint)event.request().getProperty("hint"); deleteStepRequests(event.thread()); - + boolean shouldResume = false; final Project project = getProject(); @@ -426,8 +424,9 @@ public class DebugProcessEvents extends DebugProcessImpl { preprocessEvent(suspendContext, thread); //we use schedule to allow processing other events during processing this one - //this is especially nesessary if a method is breakpoint condition + //this is especially necessary if a method is breakpoint condition getManagerThread().schedule(new SuspendContextCommandImpl(suspendContext) { + @Override public void contextAction() throws Exception { final SuspendManager suspendManager = getSuspendManager(); SuspendContextImpl evaluatingContext = SuspendManagerUtil.getEvaluatingContext(suspendManager, getSuspendContext().getThread()); @@ -441,7 +440,7 @@ public class DebugProcessEvents extends DebugProcessImpl { final LocatableEventRequestor requestor = (LocatableEventRequestor) getRequestsManager().findRequestor(event.request()); boolean resumePreferred = requestor != null && DebuggerSettings.SUSPEND_NONE.equals(requestor.getSuspendPolicy()); - boolean requestHit = false; + boolean requestHit; try { requestHit = (requestor != null) && requestor.processLocatableEvent(this, event); } @@ -451,6 +450,7 @@ public class DebugProcessEvents extends DebugProcessImpl { } final boolean[] considerRequestHit = new boolean[]{true}; DebuggerInvocationUtil.invokeAndWait(getProject(), new Runnable() { + @Override public void run() { DebuggerPanelsManager.getInstance(getProject()).toFront(mySession); final String displayName = requestor instanceof Breakpoint? ((Breakpoint)requestor).getDisplayName() : requestor.getClass().getSimpleName(); 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 613217f93ac2..4f10e68440b9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -17,6 +17,7 @@ package com.intellij.debugger.engine; import com.intellij.Patches; import com.intellij.debugger.*; +import com.intellij.debugger.actions.DebuggerAction; import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.apiAdapters.ConnectionServiceWrapper; import com.intellij.debugger.engine.evaluation.*; @@ -43,10 +44,7 @@ import com.intellij.execution.CantRunException; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; import com.intellij.execution.configurations.RemoteConnection; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessListener; -import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.process.*; import com.intellij.execution.runners.ExecutionUtil; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.Disposable; @@ -170,10 +168,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb final DebuggerSession session = mySession; if (session != null && session.isAttached()) { session.refresh(true); - XDebugSession xDebugSession = mySession.getXDebugSession(); - if (xDebugSession != null) { - xDebugSession.rebuildViews(); - } + DebuggerAction.refreshViews(mySession.getXDebugSession()); } } }); @@ -354,10 +349,16 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb return new CompoundPositionManager(new PositionManagerImpl(this)); } + @Override public void printToConsole(final String text) { myExecutionResult.getProcessHandler().notifyTextAvailable(text, ProcessOutputTypes.SYSTEM); } + @Override + public ProcessHandler getProcessHandler() { + return myExecutionResult.getProcessHandler(); + } + /** * * @param suspendContext @@ -653,8 +654,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb public void addProcessListener(ProcessListener processListener) { synchronized(myProcessListeners) { - if(getExecutionResult() != null) { - getExecutionResult().getProcessHandler().addProcessListener(processListener); + if(getProcessHandler() != null) { + getProcessHandler().addProcessListener(processListener); } else { myProcessListeners.add(processListener); @@ -664,8 +665,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb public void removeProcessListener(ProcessListener processListener) { synchronized (myProcessListeners) { - if(getExecutionResult() != null) { - getExecutionResult().getProcessHandler().removeProcessListener(processListener); + if(getProcessHandler() != null) { + getProcessHandler().removeProcessListener(processListener); } else { myProcessListeners.remove(processListener); @@ -917,11 +918,32 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb ClassNotLoadedException, IncompatibleThreadStateException, InvalidTypeException; - public E start(EvaluationContextImpl evaluationContext, Method method) throws EvaluateException { - return start(evaluationContext, method, false); + + + E start(EvaluationContextImpl evaluationContext, Method method, boolean internalEvaluate) throws EvaluateException { + while (true) { + try { + return startInternal(evaluationContext, method, internalEvaluate); + } + catch (ClassNotLoadedException e) { + ReferenceType loadedClass = null; + try { + if (evaluationContext.isAutoLoadClasses()) { + loadedClass = loadClass(evaluationContext, e.className(), evaluationContext.getClassLoader()); + } + } + catch (Exception ignored) { + loadedClass = null; + } + if (loadedClass == null) { + throw EvaluateExceptionUtil.createEvaluateException(e); + } + } + } } - public E start(EvaluationContextImpl evaluationContext, Method method, boolean internalEvaluate) throws EvaluateException { + E startInternal(EvaluationContextImpl evaluationContext, Method method, boolean internalEvaluate) + throws EvaluateException, ClassNotLoadedException { DebuggerManagerThreadImpl.assertIsManagerThread(); SuspendContextImpl suspendContext = evaluationContext.getSuspendContext(); SuspendManagerUtil.assertSuspendContext(suspendContext); @@ -956,26 +978,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb getVirtualMachineProxy().clearCaches(); - while (true) { - try { - return invokeMethodAndFork(suspendContext); - } - catch (ClassNotLoadedException e) { - ReferenceType loadedClass; - try { - loadedClass = evaluationContext.isAutoLoadClasses() ? loadClass(evaluationContext, e.className(), evaluationContext.getClassLoader()) : null; - } - catch (EvaluateException ignored) { - loadedClass = null; - } - if (loadedClass == null) { - throw EvaluateExceptionUtil.createEvaluateException(e); - } - } - } - } - catch (ClassNotLoadedException e) { - throw EvaluateExceptionUtil.createEvaluateException(e); + return invokeMethodAndFork(suspendContext); } catch (InvocationException e) { throw EvaluateExceptionUtil.createEvaluateException(e); @@ -1115,7 +1118,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } return objRef.invokeMethod(thread, method, args, invokePolicy | invocationOptions); } - }.start((EvaluationContextImpl)evaluationContext, method); + }.start((EvaluationContextImpl)evaluationContext, method, false); } private static ThreadReference getEvaluationThread(final EvaluationContext evaluationContext) throws EvaluateException { @@ -1182,7 +1185,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb return classType.newInstance(thread, method, args, invokePolicy); } }; - return invokeCommand.start((EvaluationContextImpl)evaluationContext, method); + return invokeCommand.start((EvaluationContextImpl)evaluationContext, method, false); } public void clearCashes(int suspendPolicy) { @@ -1711,15 +1714,17 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb createVirtualMachine(environment.getSessionName(), environment.isPollConnection()); + ExecutionResult executionResult; try { synchronized (myProcessListeners) { - myExecutionResult = environment.createExecutionResult(); - if (myExecutionResult == null) { + executionResult = environment.createExecutionResult(); + myExecutionResult = executionResult; + if (executionResult == null) { fail(); return null; } for (ProcessListener processListener : myProcessListeners) { - myExecutionResult.getProcessHandler().addProcessListener(processListener); + executionResult.getProcessHandler().addProcessListener(processListener); } myProcessListeners.clear(); } @@ -1732,7 +1737,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb // writing to volatile field ensures the other threads will see the right values in non-volatile fields if (ApplicationManager.getApplication().isUnitTestMode()) { - return myExecutionResult; + return executionResult; } /* @@ -1760,7 +1765,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb }); */ - return myExecutionResult; + return executionResult; } private void fail() { @@ -1885,8 +1890,8 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } MyProcessAdapter processListener = new MyProcessAdapter(); addProcessListener(processListener); - if(myExecutionResult != null) { - if(myExecutionResult.getProcessHandler().isStartNotified()) { + if (myExecutionResult != null) { + if (myExecutionResult.getProcessHandler().isStartNotified()) { processListener.run(); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JVMNameUtil.java b/java/debugger/impl/src/com/intellij/debugger/engine/JVMNameUtil.java index 13e8f155dff4..eeaa1c21015e 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JVMNameUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JVMNameUtil.java @@ -285,13 +285,20 @@ public class JVMNameUtil { return DebuggerManager.getInstance(aClass.getProject()).getVMClassQualifiedName(aClass); } + public static JVMName getJVMConstructorSignature(@Nullable PsiMethod method, @Nullable PsiClass declaringClass) { + return getJVMSignature(method, true, declaringClass); + } + + public static JVMName getJVMSignature(@NotNull PsiMethod method) { + return getJVMSignature(method, method.isConstructor(), method.getContainingClass()); + } + @SuppressWarnings({"HardCodedStringLiteral"}) - public static JVMName getJVMSignature(PsiMethod method) { + private static JVMName getJVMSignature(@Nullable PsiMethod method, boolean constructor, @Nullable PsiClass declaringClass) { JVMNameBuffer signature = new JVMNameBuffer(); signature.append("("); - if (method.isConstructor()) { - final PsiClass declaringClass = method.getContainingClass(); + if (constructor) { if (declaringClass != null) { final PsiClass outerClass = declaringClass.getContainingClass(); if (outerClass != null) { @@ -302,11 +309,13 @@ public class JVMNameUtil { } } } - for (PsiParameter psiParameter : method.getParameterList().getParameters()) { - appendJVMSignature(signature, psiParameter.getType()); + if (method != null) { + for (PsiParameter psiParameter : method.getParameterList().getParameters()) { + appendJVMSignature(signature, psiParameter.getType()); + } } signature.append(")"); - if (!method.isConstructor()) { + if (!constructor && method != null) { appendJVMSignature(signature, method.getReturnType()); } else { 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 37ee00b94eaf..af55182e3607 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -18,20 +18,18 @@ package com.intellij.debugger.engine; import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.actions.DebuggerActions; import com.intellij.debugger.engine.evaluation.EvaluationContext; -import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.*; +import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.DebuggerContentInfo; import com.intellij.debugger.ui.breakpoints.Breakpoint; import com.intellij.debugger.ui.impl.ThreadsPanel; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.MessageDescriptor; -import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.NodeManagerImpl; import com.intellij.debugger.ui.tree.NodeDescriptor; -import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.ExecutionConsoleEx; @@ -150,29 +148,40 @@ public class JavaDebugProcess extends XDebugProcess { }; session.addSessionListener(new XDebugSessionAdapter() { @Override - public void beforeSessionResume() { - myJavaSession.getProcess().getManagerThread().schedule(new DebuggerCommandImpl() { - @Override - protected void action() throws Exception { - myNodeManager.setHistoryByContext(getDebuggerStateManager().getContext()); - } - @Override - public Priority getPriority() { - return Priority.NORMAL; - } - }); + public void sessionPaused() { + saveNodeHistory(); } @Override public void stackFrameChanged() { XStackFrame frame = session.getCurrentStackFrame(); if (frame instanceof JavaStackFrame) { - DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), ((JavaStackFrame)frame).getStackFrameProxy()); + StackFrameProxyImpl frameProxy = ((JavaStackFrame)frame).getStackFrameProxy(); + DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), frameProxy); + saveNodeHistory(frameProxy); } } }); } + public void saveNodeHistory() { + saveNodeHistory(getDebuggerStateManager().getContext().getFrameProxy()); + } + + private void saveNodeHistory(final StackFrameProxyImpl frameProxy) { + myJavaSession.getProcess().getManagerThread().invoke(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + myNodeManager.setHistoryByContext(frameProxy); + } + + @Override + public Priority getPriority() { + return Priority.NORMAL; + } + }); + } + private DebuggerStateManager getDebuggerStateManager() { return myJavaSession.getContextManager(); } @@ -243,7 +252,7 @@ public class JavaDebugProcess extends XDebugProcess { @Nullable @Override protected ProcessHandler doGetProcessHandler() { - return myJavaSession.getProcess().getExecutionResult().getProcessHandler(); + return myJavaSession.getProcess().getProcessHandler(); } @NotNull @@ -302,23 +311,16 @@ public class JavaDebugProcess extends XDebugProcess { } @Override - public void registerAdditionalActions(@NotNull DefaultActionGroup leftToolbar, @NotNull DefaultActionGroup topToolbar) { + public void registerAdditionalActions(@NotNull DefaultActionGroup leftToolbar, @NotNull DefaultActionGroup topToolbar, @NotNull DefaultActionGroup settings) { Constraints beforeRunner = new Constraints(Anchor.BEFORE, "Runner.Layout"); leftToolbar.add(Separator.getInstance(), beforeRunner); leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.EXPORT_THREADS), beforeRunner); leftToolbar.add(ActionManager.getInstance().getAction(DebuggerActions.DUMP_THREADS), beforeRunner); leftToolbar.add(Separator.getInstance(), beforeRunner); - for (AnAction action : leftToolbar.getChildren(null)) { - //TODO: maybe introduce API for extra settings? - if (action instanceof DefaultActionGroup && "DebuggerSettings".equals(action.getTemplatePresentation().getText())) { - DefaultActionGroup settings = (DefaultActionGroup)action; - addActionToGroup(settings, XDebuggerActions.AUTO_TOOLTIP); - settings.addAction(new AutoVarsSwitchAction(), Constraints.FIRST); - settings.addAction(new WatchLastMethodReturnValueAction(), Constraints.FIRST); - break; - } - } + addActionToGroup(settings, XDebuggerActions.AUTO_TOOLTIP); + settings.addAction(new AutoVarsSwitchAction(), Constraints.FIRST); + settings.addAction(new WatchLastMethodReturnValueAction(), Constraints.FIRST); } private static class AutoVarsSwitchAction extends ToggleAction { 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 f2178c1d4fb5..2eab90666967 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java @@ -82,9 +82,11 @@ public class JavaDebuggerEvaluator extends XDebuggerEvaluator { return; } JavaDebugProcess process = myDebugProcess.getXdebugProcess(); - if (process != null) { - callback.evaluated(JavaValue.create(null, descriptor, evalContext, process.getNodeManager(), true)); + if (process == null) { + callback.errorOccurred("No debug process"); + return; } + callback.evaluated(JavaValue.create(null, descriptor, evalContext, process.getNodeManager(), true)); } }); } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java index 1293a0fdd0c0..60d0b708befb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java @@ -17,7 +17,9 @@ package com.intellij.debugger.engine; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.xdebugger.frame.*; import com.sun.jdi.Field; import com.sun.jdi.ReferenceType; @@ -57,8 +59,14 @@ public class JavaStaticGroup extends XValueGroup implements NodeDescriptorProvid final ReferenceType refType = myStaticDescriptor.getType(); List<Field> fields = refType.allFields(); + + final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer(); for (Field field : fields) { if (field.isStatic()) { + boolean isSynthetic = DebuggerUtils.isSynthetic(field); + if (!classRenderer.SHOW_SYNTHETICS && isSynthetic) { + continue; + } final FieldDescriptorImpl fieldDescriptor = myNodeManager.getFieldDescriptor(myStaticDescriptor, null, field); children.add(JavaValue.create(fieldDescriptor, myEvaluationContext, myNodeManager)); //final DebuggerTreeNodeImpl node = myNodeManager.createNode(fieldDescriptor, myEvaluationContext); 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 7b0ffffe98d5..b678cf30d661 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -15,6 +15,7 @@ */ package com.intellij.debugger.engine; +import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerInvocationUtil; import com.intellij.debugger.SourcePosition; import com.intellij.debugger.actions.JavaReferringObjectsValue; @@ -102,6 +103,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV } @Override + @NotNull public ValueDescriptorImpl getDescriptor() { return myValueDescriptor; } @@ -273,7 +275,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV @Override public void computeChildren(@NotNull final XCompositeNode node) { - if (myEvaluationContext.getSuspendContext().isResumed()) return; + if (checkContextNotResumed(node)) return; myEvaluationContext.getDebugProcess().getManagerThread().schedule(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) { @Override public Priority getPriority() { @@ -335,6 +337,14 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV }); } + protected boolean checkContextNotResumed(XCompositeNode node) { + if (myEvaluationContext.getSuspendContext().isResumed()) { + node.setErrorMessage(DebuggerBundle.message("error.context.has.changed")); + return true; + } + return false; + } + @Override public void computeSourcePosition(@NotNull final XNavigatable navigatable) { if (myEvaluationContext.getSuspendContext().isResumed()) return; @@ -419,6 +429,7 @@ public class JavaValue extends XNamedValue implements NodeDescriptorProvider, XV public String getEvaluationExpression() { if (evaluationExpression == null) { // TODO: change API to allow to calculate it asynchronously + if (myEvaluationContext.getSuspendContext().isResumed()) return null; DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess(); debugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { @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 c7e59106beb8..5aa037191c17 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueModifier.java @@ -34,6 +34,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.util.ProgressIndicatorListenerAdapter; import com.intellij.openapi.progress.util.ProgressWindowWithNotification; import com.intellij.openapi.ui.Messages; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.ui.SimpleColoredComponent; @@ -62,9 +63,12 @@ public class JavaValueModifier extends XValueModifier { @Override public String getInitialValueEditorText() { Value value = myJavaValue.getDescriptor().getValue(); - if (value instanceof PrimitiveValue || value instanceof StringReference) { + if (value instanceof PrimitiveValue) { return myJavaValue.getValueString(); } + else if (value instanceof StringReference) { + return StringUtil.wrapWithDoubleQuote(DebuggerUtils.translateStringValue(myJavaValue.getValueString())); + } return null; } @@ -96,10 +100,12 @@ public class JavaValueModifier extends XValueModifier { @Override public void setValue(@NotNull String expression, @NotNull XModificationCallback callback) { final NodeDescriptorImpl descriptor = myJavaValue.getDescriptor(); - if (!(descriptor instanceof ValueDescriptorImpl)) { + if(!((ValueDescriptorImpl)descriptor).canSetValue()) { return; } - if(!((ValueDescriptorImpl)descriptor).canSetValue()) { + + if (myJavaValue.getEvaluationContext().getSuspendContext().isResumed()) { + callback.errorOccurred(DebuggerBundle.message("error.context.has.changed")); return; } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java index b6ca9eafe1f1..759d92fd57a8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/EvaluationContextImpl.java @@ -30,6 +30,7 @@ public final class EvaluationContextImpl implements EvaluationContext{ private final SuspendContextImpl mySuspendContext; private final StackFrameProxyImpl myFrameProxy; private boolean myAutoLoadClasses = true; + private ClassLoaderReference myClassLoader; public EvaluationContextImpl(@NotNull SuspendContextImpl suspendContext, StackFrameProxyImpl frameProxy, @Nullable Value thisObject) { myThisObject = thisObject; @@ -77,9 +78,16 @@ public final class EvaluationContextImpl implements EvaluationContext{ @Override public ClassLoaderReference getClassLoader() throws EvaluateException { DebuggerManagerThreadImpl.assertIsManagerThread(); + if (myClassLoader != null) { + return myClassLoader; + } return myFrameProxy != null ? myFrameProxy.getClassLoader() : null; } + public void setClassLoader(ClassLoaderReference classLoader) { + myClassLoader = classLoader; + } + public boolean isAutoLoadClasses() { return myAutoLoadClasses; } 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 83ad91b4e27d..7d0a4aeb0989 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 @@ -31,7 +31,7 @@ import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.JVMName; import com.intellij.debugger.engine.JVMNameUtil; import com.intellij.debugger.engine.evaluation.*; -import com.intellij.debugger.ui.DebuggerEditorImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.psi.*; @@ -66,8 +66,8 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { final Project project = contextElement.getProject(); - CodeFragmentFactory factory = DebuggerEditorImpl.findAppropriateFactory(text, contextElement); - PsiCodeFragment codeFragment = new CodeFragmentFactoryContextWrapper(factory).createCodeFragment(text, contextElement, project); + CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, contextElement); + PsiCodeFragment codeFragment = factory.createCodeFragment(text, contextElement, project); if (codeFragment == null) { throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", text.getText())); } @@ -185,6 +185,11 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } @Override + public void visitTryStatement(PsiTryStatement statement) { + throw new EvaluateRuntimeException(new UnsupportedExpressionException(statement.getText())); + } + + @Override public void visitStatement(PsiStatement statement) { throwEvaluateException(DebuggerBundle.message("evaluation.error.statement.not.supported", statement.getText())); } @@ -741,24 +746,28 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } private int calcIterationCount(final PsiJavaCodeReferenceElement qualifier) { - int iterationCount = 0; if (qualifier != null) { - PsiElement targetClass = qualifier.resolve(); - if (targetClass == null || getContextPsiClass() == null) { - throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", qualifier.getText())); - } - try { - PsiClass aClass = getContextPsiClass(); - while (aClass != null && !aClass.equals(targetClass)) { - iterationCount++; - aClass = getOuterClass(aClass); - } - } - catch (Exception e) { - //noinspection ThrowableResultOfMethodCallIgnored - throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(e)); + return calcIterationCount(qualifier.resolve(), qualifier.getText()); + } + return 0; + } + + private int calcIterationCount(PsiElement targetClass, String name) { + int iterationCount = 0; + if (targetClass == null || getContextPsiClass() == null) { + throwEvaluateException(DebuggerBundle.message("evaluation.error.invalid.expression", name)); + } + try { + PsiClass aClass = getContextPsiClass(); + while (aClass != null && !aClass.equals(targetClass)) { + iterationCount++; + aClass = getOuterClass(aClass); } } + catch (Exception e) { + //noinspection ThrowableResultOfMethodCallIgnored + throw new EvaluateRuntimeException(EvaluateExceptionUtil.createEvaluateException(e)); + } return iterationCount; } @@ -962,12 +971,16 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } } + boolean defaultInterfaceMethod = false; + if (psiMethod != null) { processBoxingConversions(psiMethod.getParameterList().getParameters(), argExpressions, resolveResult.getSubstitutor(), argumentEvaluators); argumentEvaluators = wrapVarargs(psiMethod.getParameterList().getParameters(), argExpressions, resolveResult.getSubstitutor(), argumentEvaluators); + defaultInterfaceMethod = psiMethod.hasModifierProperty(PsiModifier.DEFAULT); } - myResult = new MethodEvaluator(objectEvaluator, contextClass, methodExpr.getReferenceName(), psiMethod != null ? JVMNameUtil.getJVMSignature(psiMethod) : null, argumentEvaluators); + myResult = new MethodEvaluator(objectEvaluator, contextClass, methodExpr.getReferenceName(), + psiMethod != null ? JVMNameUtil.getJVMSignature(psiMethod) : null, argumentEvaluators, defaultInterfaceMethod); } @Override @@ -1082,6 +1095,16 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } @Override + public void visitLambdaExpression(PsiLambdaExpression expression) { + throw new EvaluateRuntimeException(new UnsupportedExpressionException(DebuggerBundle.message("evaluation.error.lambda.evaluation.not.supported"))); + } + + @Override + public void visitMethodReferenceExpression(PsiMethodReferenceExpression expression) { + throw new EvaluateRuntimeException(new UnsupportedExpressionException(DebuggerBundle.message("evaluation.error.method.reference.evaluation.not.supported"))); + } + + @Override public void visitNewExpression(final PsiNewExpression expression) { PsiType expressionPsiType = expression.getType(); if (expressionPsiType instanceof PsiArrayType) { @@ -1142,7 +1165,7 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { else if (expressionPsiType instanceof PsiClassType){ // must be a class ref PsiClass aClass = ((PsiClassType)expressionPsiType).resolve(); if(aClass instanceof PsiAnonymousClass) { - throwEvaluateException(DebuggerBundle.message("evaluation.error.anonymous.class.evaluation.not.supported")); + throw new EvaluateRuntimeException(new UnsupportedExpressionException(DebuggerBundle.message("evaluation.error.anonymous.class.evaluation.not.supported"))); } PsiExpressionList argumentList = expression.getArgumentList(); if (argumentList == null) { @@ -1173,8 +1196,11 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { argumentEvaluators = wrapVarargs(constructor.getParameterList().getParameters(), argExpressions, constructorResolveResult.getSubstitutor(), argumentEvaluators); } - //noinspection HardCodedStringLiteral - JVMName signature = constructor != null ? JVMNameUtil.getJVMSignature(constructor) : JVMNameUtil.getJVMRawText("()V"); + if (aClass != null && aClass.getContainingClass() != null && !aClass.hasModifierProperty(PsiModifier.STATIC)) { + argumentEvaluators = addThisEvaluator(argumentEvaluators, aClass.getContainingClass()); + } + + JVMName signature = JVMNameUtil.getJVMConstructorSignature(constructor, aClass); myResult = new NewClassInstanceEvaluator( new TypeEvaluator(JVMNameUtil.getJVMQualifiedName(expressionPsiType)), signature, @@ -1191,6 +1217,14 @@ public class EvaluatorBuilderImpl implements EvaluatorBuilder { } } + private Evaluator[] addThisEvaluator(Evaluator[] argumentEvaluators, PsiClass cls) { + Evaluator[] res = new Evaluator[argumentEvaluators.length+1]; + int depth = calcIterationCount(cls, "this"); + res[0] = new ThisEvaluator(depth); + System.arraycopy(argumentEvaluators, 0, res, 1, argumentEvaluators.length); + return res; + } + @Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { PsiExpression[] initializers = expression.getInitializers(); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java index 6ba88653749b..80e42e3b61e2 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/MethodEvaluator.java @@ -43,13 +43,19 @@ public class MethodEvaluator implements Evaluator { private final String myMethodName; private final Evaluator[] myArgumentEvaluators; private final Evaluator myObjectEvaluator; + private final boolean myCheckDefaultInterfaceMethod; public MethodEvaluator(Evaluator objectEvaluator, JVMName className, String methodName, JVMName signature, Evaluator[] argumentEvaluators) { + this(objectEvaluator, className, methodName, signature, argumentEvaluators, false); + } + + public MethodEvaluator(Evaluator objectEvaluator, JVMName className, String methodName, JVMName signature, Evaluator[] argumentEvaluators, boolean checkDefaultInterfaceMethod) { myObjectEvaluator = new DisableGC(objectEvaluator); myClassName = className; myMethodName = methodName; myMethodSignature = signature; myArgumentEvaluators = argumentEvaluators; + myCheckDefaultInterfaceMethod = checkDefaultInterfaceMethod; } @Override @@ -148,7 +154,7 @@ public class MethodEvaluator implements Evaluator { return debugProcess.invokeInstanceMethod(context, objRef, jdiMethod, args, ObjectReference.INVOKE_NONVIRTUAL); } // fix for default methods in interfaces, see IDEA-124066 - if (Boolean.valueOf(System.getProperty("debugger.invoke.default")) && jdiMethod.declaringType() instanceof InterfaceType) { + if (myCheckDefaultInterfaceMethod && jdiMethod.declaringType() instanceof InterfaceType) { return invokeDefaultMethod(debugProcess, context, objRef, myMethodName); } else { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java index c3e7f8173322..3bbb0c633cd6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/NewClassInstanceEvaluator.java @@ -21,13 +21,13 @@ */ package com.intellij.debugger.engine.evaluation.expression; +import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.JVMName; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; -import com.intellij.debugger.impl.DebuggerUtilsEx; -import com.intellij.debugger.DebuggerBundle; import com.sun.jdi.ClassType; import com.sun.jdi.Method; import com.sun.jdi.ObjectReference; @@ -55,7 +55,7 @@ class NewClassInstanceEvaluator implements Evaluator { } ClassType classType = (ClassType)obj; // find constructor - Method method = DebuggerUtilsEx.findMethod(classType, "<init>", myConstructorSignature.getName(debugProcess)); + Method method = DebuggerUtils.findMethod(classType, "<init>", myConstructorSignature.getName(debugProcess)); if (method == null) { throw EvaluateExceptionUtil.createEvaluateException( DebuggerBundle.message("evaluation.error.cannot.resolve.constructor", myConstructorSignature.getDisplayName(debugProcess))); diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnsupportedExpressionException.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnsupportedExpressionException.java new file mode 100644 index 000000000000..f4c513d4036c --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/UnsupportedExpressionException.java @@ -0,0 +1,28 @@ +/* + * 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.DebuggerBundle; +import com.intellij.debugger.engine.evaluation.EvaluateException; + +/** + * @author egor + */ +public class UnsupportedExpressionException extends EvaluateException { + public UnsupportedExpressionException(String message) { + super(message); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java index 8408364f7e73..f36c9f14cee6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextUtil.java @@ -23,11 +23,12 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.ui.impl.watch.ThreadDescriptorImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; +import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl; import com.intellij.openapi.util.Couple; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiUtilBase; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XSourcePosition; import org.jetbrains.annotations.NotNull; @@ -75,7 +76,9 @@ public class DebuggerContextUtil { final XDebugSession debugSession = session.getXDebugSession(); if (debugSession != null) { final XSourcePosition position = debugSession.getCurrentPosition(); - final Editor editor = PsiUtilBase.findEditor(psi); + Editor editor = ((FileEditorManagerImpl)FileEditorManager.getInstance(file.getProject())).getSelectedTextEditor(true); + + //final Editor editor = fileEditor instanceof TextEditorImpl ? ((TextEditorImpl)fileEditor).getEditor() : null; if (editor != null && position != null && file.getVirtualFile().equals(position.getFile())) { final Couple<Collection<TextRange>> usages = IdentifierHighlighterPass.getHighlightUsages(psi, file); final List<TextRange> ranges = new ArrayList<TextRange>(); diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java index 60c0d2dded3d..392a14b78bbf 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java @@ -607,8 +607,7 @@ public class DebuggerManagerImpl extends DebuggerManagerEx implements Persistent } private void dispose(DebuggerSession session) { - ProcessHandler processHandler = session.getProcess().getExecutionResult().getProcessHandler(); - + ProcessHandler processHandler = session.getProcess().getProcessHandler(); synchronized (mySessions) { DebuggerSession removed = mySessions.remove(processHandler); LOG.assertTrue(removed != null); diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java index 0a5210f16c36..dbcf43fd6168 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerSession.java @@ -15,7 +15,10 @@ */ package com.intellij.debugger.impl; -import com.intellij.debugger.*; +import com.intellij.debugger.DebugEnvironment; +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationListener; @@ -29,14 +32,11 @@ import com.intellij.debugger.ui.breakpoints.BreakpointWithHighlighter; import com.intellij.debugger.ui.breakpoints.LineBreakpoint; import com.intellij.execution.ExecutionException; import com.intellij.execution.ExecutionResult; -import com.intellij.execution.Executor; -import com.intellij.execution.configurations.ModuleRunProfile; import com.intellij.execution.configurations.RemoteConnection; import com.intellij.execution.configurations.RemoteState; import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.process.ProcessOutputTypes; -import com.intellij.execution.runners.ExecutionEnvironmentBuilder; -import com.intellij.execution.runners.ProgramRunner; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; @@ -199,6 +199,7 @@ public class DebuggerSession implements AbstractDebuggerSession { ValueLookupManager.getInstance(getProject()).startListening(); } + @NotNull public DebuggerStateManager getContextManager() { return myContextManager; } @@ -251,7 +252,7 @@ public class DebuggerSession implements AbstractDebuggerSession { case STATE_DISPOSED: return DebuggerBundle.message("status.debug.stopped"); } - return myState.myDescription; + return null; } /* Stepping */ @@ -371,7 +372,7 @@ public class DebuggerSession implements AbstractDebuggerSession { } public boolean isRunning() { - return getState() == STATE_RUNNING && !getProcess().getExecutionResult().getProcessHandler().isProcessTerminated(); + return getState() == STATE_RUNNING && !getProcess().getProcessHandler().isProcessTerminated(); } private SuspendContextImpl getSuspendContext() { @@ -380,19 +381,6 @@ public class DebuggerSession implements AbstractDebuggerSession { } @Nullable - protected ExecutionResult attach(@NotNull Executor executor, - @NotNull ProgramRunner runner, - @NotNull ModuleRunProfile profile, - @NotNull RunProfileState state, - RemoteConnection remoteConnection, - boolean pollConnection) throws ExecutionException { - return attach(new DefaultDebugEnvironment(new ExecutionEnvironmentBuilder(myDebugProcess.getProject(), executor).runProfile(profile).runner(runner).build(), - state, - remoteConnection, - pollConnection)); - } - - @Nullable protected ExecutionResult attach(DebugEnvironment environment) throws ExecutionException { RemoteConnection remoteConnection = environment.getRemoteConnection(); final String addressDisplayName = DebuggerBundle.getAddressDisplayName(remoteConnection); @@ -603,7 +591,7 @@ public class DebuggerSession implements AbstractDebuggerSession { final String transportName = DebuggerBundle.getTransportName(connection); final String message = DebuggerBundle.message("status.connected", addressDisplayName, transportName); - process.getExecutionResult().getProcessHandler().notifyTextAvailable(message + "\n", ProcessOutputTypes.SYSTEM); + process.printToConsole(message + "\n"); DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { @Override public void run() { @@ -630,12 +618,12 @@ public class DebuggerSession implements AbstractDebuggerSession { @Override public void processDetached(final DebugProcessImpl debugProcess, boolean closedByUser) { if (!closedByUser) { - ExecutionResult executionResult = debugProcess.getExecutionResult(); - if(executionResult != null) { + ProcessHandler processHandler = debugProcess.getProcessHandler(); + if(processHandler != null) { final RemoteConnection connection = getProcess().getConnection(); final String addressDisplayName = DebuggerBundle.getAddressDisplayName(connection); final String transportName = DebuggerBundle.getTransportName(connection); - executionResult.getProcessHandler().notifyTextAvailable(DebuggerBundle.message("status.disconnected", addressDisplayName, transportName) + "\n", ProcessOutputTypes.SYSTEM); + processHandler.notifyTextAvailable(DebuggerBundle.message("status.disconnected", addressDisplayName, transportName) + "\n", ProcessOutputTypes.SYSTEM); } } DebuggerInvocationUtil.invokeLater(getProject(), new Runnable() { @@ -659,7 +647,7 @@ public class DebuggerSession implements AbstractDebuggerSession { public void threadStopped(DebugProcess proc, ThreadReference thread) { notifyThreadsRefresh(); } - + private void notifyThreadsRefresh() { if (!myUpdateAlarm.isDisposed()) { myUpdateAlarm.cancelAllRequests(); diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java index 026b7111d18f..ae6bb5dd7b27 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -37,6 +37,7 @@ import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.*; @@ -403,17 +404,25 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { public abstract CompletionEditor createEditor(Project project, PsiElement context, @NonNls String recentsId); - @Nullable - public static CodeFragmentFactory getEffectiveCodeFragmentFactory(final PsiElement psiContext) { - final CodeFragmentFactory factory = ApplicationManager.getApplication().runReadAction(new Computable<CodeFragmentFactory>() { + @NotNull + public static CodeFragmentFactory findAppropriateCodeFragmentFactory(final TextWithImports text, final PsiElement context) { + CodeFragmentFactory factory = ApplicationManager.getApplication().runReadAction(new Computable<CodeFragmentFactory>() { @Override public CodeFragmentFactory compute() { - final List<CodeFragmentFactory> codeFragmentFactories = getCodeFragmentFactories(psiContext); - // the list always contains at least DefaultCodeFragmentFactory - return codeFragmentFactories.get(0); + final FileType fileType = text.getFileType(); + final List<CodeFragmentFactory> factories = getCodeFragmentFactories(context); + if (fileType == null) { + return factories.get(0); + } + for (CodeFragmentFactory factory : factories) { + if (factory.getFileType().equals(fileType)) { + return factory; + } + } + return DefaultCodeFragmentFactory.getInstance(); } }); - return factory != null? new CodeFragmentFactoryContextWrapper(factory) : null; + return new CodeFragmentFactoryContextWrapper(factory); } private static class SigReader { 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 02f4ee44fd53..4c8fb08ef09d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/JavaEditorTextProviderImpl.java @@ -86,6 +86,10 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { public Pair<PsiElement, TextRange> findExpression(PsiElement element, boolean allowMethodCalls) { PsiElement expression = null; PsiElement parent = element.getParent(); + if (parent instanceof PsiLiteralExpression) { + element = parent; + parent = parent.getParent(); + } if (parent instanceof PsiVariable) { expression = element; } @@ -107,12 +111,7 @@ public class JavaEditorTextProviderImpl implements EditorTextProvider { else if (parent instanceof PsiThisExpression) { expression = parent; } - else if (parent instanceof PsiInstanceOfExpression - || parent instanceof PsiBinaryExpression - || parent instanceof PsiPolyadicExpression - || parent instanceof PsiPrefixExpression - || parent instanceof PsiConditionalExpression - ) { + else if (parent instanceof PsiExpression && !(parent instanceof PsiNewExpression)) { if (allowMethodCalls || !DebuggerUtils.hasSideEffects(parent)) { expression = parent; } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/PositionUtil.java b/java/debugger/impl/src/com/intellij/debugger/impl/PositionUtil.java index 2b23f371f528..47558e8c4da8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/PositionUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/PositionUtil.java @@ -41,6 +41,7 @@ public class PositionUtil extends ContextUtil { return ContextUtil.getSourcePosition(context); } + @Nullable public static PsiElement getContextElement(final StackFrameContext context) { if(context instanceof DebuggerContextImpl) return ((DebuggerContextImpl) context).getContextElement(); diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java index 452a924aed00..8785e687eff3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerDataViewsConfigurable.java @@ -53,7 +53,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { private JCheckBox myCbShowObjectId; private StateRestoringCheckBox myCbShowStaticFinalFields; - private final ArrayRendererConfigurable myArrayRendererConfigurable; + //private final ArrayRendererConfigurable myArrayRendererConfigurable; private JCheckBox myCbEnableAlternateViews; private JCheckBox myCbEnableToString; @@ -66,12 +66,12 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { public DebuggerDataViewsConfigurable(@Nullable Project project) { myProject = project; - myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer()); + //myArrayRendererConfigurable = new ArrayRendererConfigurable(NodeRendererSettings.getInstance().getArrayRenderer()); } @Override public void disposeUIResources() { - myArrayRendererConfigurable.disposeUIResources(); + //myArrayRendererConfigurable.disposeUIResources(); myToStringFilterEditor = null; myProject = null; } @@ -165,13 +165,14 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { panel.add(showPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(4, 0, 0, 0), 0, 0)); - final JPanel arraysPanel = new JPanel(new BorderLayout(0, UIUtil.DEFAULT_VGAP)); - final JComponent arraysComponent = myArrayRendererConfigurable.createComponent(); - assert arraysComponent != null; - arraysPanel.add(arraysComponent, BorderLayout.CENTER); - arraysPanel.add(myCbHideNullArrayElements, BorderLayout.SOUTH); - arraysPanel.setBorder(IdeBorderFactory.createTitledBorder("Arrays", true)); - panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + //final JPanel arraysPanel = new JPanel(new BorderLayout(0, UIUtil.DEFAULT_VGAP)); + //final JComponent arraysComponent = myArrayRendererConfigurable.createComponent(); + //assert arraysComponent != null; + //arraysPanel.add(arraysComponent, BorderLayout.CENTER); + //arraysPanel.add(myCbHideNullArrayElements, BorderLayout.SOUTH); + //arraysPanel.setBorder(IdeBorderFactory.createTitledBorder("Arrays", true)); + //panel.add(arraysPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); + panel.add(myCbHideNullArrayElements, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTH, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); panel.add(myCbEnableAlternateViews, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(4, 0, 0, 10), 0, 0)); // starting 4-th row @@ -209,7 +210,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myAutoTooltip.save(); - myArrayRendererConfigurable.apply(); + //myArrayRendererConfigurable.apply(); rendererSettings.fireRenderersChanged(); } @@ -250,7 +251,7 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { myRbFromList.setEnabled(toStringEnabled); myRbAllThatOverride.setEnabled(toStringEnabled); - myArrayRendererConfigurable.reset(); + //myArrayRendererConfigurable.reset(); } @Override @@ -266,9 +267,9 @@ public class DebuggerDataViewsConfigurable implements SearchableConfigurable { } private boolean areDefaultRenderersModified() { - if (myArrayRendererConfigurable.isModified()) { - return true; - } + //if (myArrayRendererConfigurable.isModified()) { + // return true; + //} final NodeRendererSettings rendererSettings = NodeRendererSettings.getInstance(); diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java index bb3fafed746f..2855ab4dfc1f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSettings.java @@ -20,6 +20,7 @@ import com.intellij.openapi.components.*; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.InvalidDataException; import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.containers.hash.LinkedHashMap; import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; @@ -55,6 +56,10 @@ public class DebuggerSettings implements Cloneable, PersistentStateComponent<Ele @NonNls public static final String RUN_HOTSWAP_NEVER = "RunHotswapNever"; @NonNls public static final String RUN_HOTSWAP_ASK = "RunHotswapAsk"; + @NonNls public static final String EVALUATE_FINALLY_ALWAYS = "EvaluateFinallyAlways"; + @NonNls public static final String EVALUATE_FINALLY_NEVER = "EvaluateFinallyNever"; + @NonNls public static final String EVALUATE_FINALLY_ASK = "EvaluateFinallyAsk"; + public boolean TRACING_FILTERS_ENABLED; public int DEBUGGER_TRANSPORT; public boolean FORCE_CLASSIC_VM; @@ -74,6 +79,8 @@ public class DebuggerSettings implements Cloneable, PersistentStateComponent<Ele public volatile boolean AUTO_VARIABLES_MODE = false; public volatile boolean SHOW_LIBRARY_STACKFRAMES = true; + public String EVALUATE_FINALLY_ON_POP_FRAME = EVALUATE_FINALLY_ASK; + private ClassFilter[] mySteppingFilters = ClassFilter.EMPTY_ARRAY; private Map<String, ContentState> myContentStates = new LinkedHashMap<String, ContentState>(); @@ -142,6 +149,7 @@ public class DebuggerSettings implements Cloneable, PersistentStateComponent<Ele return TRACING_FILTERS_ENABLED == secondSettings.TRACING_FILTERS_ENABLED && DEBUGGER_TRANSPORT == secondSettings.DEBUGGER_TRANSPORT && + StringUtil.equals(EVALUATE_FINALLY_ON_POP_FRAME, secondSettings.EVALUATE_FINALLY_ON_POP_FRAME) && FORCE_CLASSIC_VM == secondSettings.FORCE_CLASSIC_VM && DISABLE_JIT == secondSettings.DISABLE_JIT && HOTSWAP_IN_BACKGROUND == secondSettings.HOTSWAP_IN_BACKGROUND && diff --git a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java index cf7e367f1ce8..914df8b14a83 100644 --- a/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java +++ b/java/debugger/impl/src/com/intellij/debugger/settings/DebuggerSteppingConfigurable.java @@ -22,6 +22,7 @@ import com.intellij.ui.classFilter.ClassFilterEditor; import org.jetbrains.annotations.NotNull; import javax.swing.*; +import javax.swing.border.Border; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -33,6 +34,9 @@ class DebuggerSteppingConfigurable implements ConfigurableUi<DebuggerSettings> { private JCheckBox myCbSkipClassLoaders; private ClassFilterEditor mySteppingFilterEditor; private JCheckBox myCbSkipSimpleGetters; + private JRadioButton myRbEvaluateFinallyAlways; + private JRadioButton myRbEvaluateFinallyNever; + private JRadioButton myRbEvaluateFinallyAsk; @Override public void reset(@NotNull DebuggerSettings settings) { @@ -45,6 +49,16 @@ class DebuggerSteppingConfigurable implements ConfigurableUi<DebuggerSettings> { mySteppingFilterEditor.setFilters(settings.getSteppingFilters()); mySteppingFilterEditor.setEnabled(settings.TRACING_FILTERS_ENABLED); + + if (DebuggerSettings.EVALUATE_FINALLY_ALWAYS.equals(settings.EVALUATE_FINALLY_ON_POP_FRAME)) { + myRbEvaluateFinallyAlways.setSelected(true); + } + else if (DebuggerSettings.EVALUATE_FINALLY_NEVER.equals(settings.EVALUATE_FINALLY_ON_POP_FRAME)) { + myRbEvaluateFinallyNever.setSelected(true); + } + else { + myRbEvaluateFinallyAsk.setSelected(true); + } } @Override @@ -59,6 +73,16 @@ class DebuggerSteppingConfigurable implements ConfigurableUi<DebuggerSettings> { settings.SKIP_CLASSLOADERS = myCbSkipClassLoaders.isSelected(); settings.TRACING_FILTERS_ENABLED = myCbStepInfoFiltersEnabled.isSelected(); + if (myRbEvaluateFinallyAlways.isSelected()) { + settings.EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ALWAYS; + } + else if (myRbEvaluateFinallyNever.isSelected()) { + settings.EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_NEVER; + } + else { + settings.EVALUATE_FINALLY_ON_POP_FRAME = DebuggerSettings.EVALUATE_FINALLY_ASK; + } + mySteppingFilterEditor.stopEditing(); settings.setSteppingFilters(mySteppingFilterEditor.getFilters()); } @@ -94,6 +118,33 @@ class DebuggerSteppingConfigurable implements ConfigurableUi<DebuggerSettings> { mySteppingFilterEditor.setEnabled(myCbStepInfoFiltersEnabled.isSelected()); } }); + + myRbEvaluateFinallyAlways = new JRadioButton(DebuggerBundle.message("label.debugger.general.configurable.evaluate.finally.always")); + myRbEvaluateFinallyNever = new JRadioButton(DebuggerBundle.message("label.debugger.general.configurable.evaluate.finally.never")); + myRbEvaluateFinallyAsk = new JRadioButton(DebuggerBundle.message("label.debugger.general.configurable.evaluate.finally.ask")); + + int cbLeftOffset = 0; + final Border border = myCbSkipSimpleGetters.getBorder(); + if (border != null) { + final Insets insets = border.getBorderInsets(myCbSkipSimpleGetters); + if (insets != null) { + cbLeftOffset = insets.left; + } + } + + final ButtonGroup group = new ButtonGroup(); + group.add(myRbEvaluateFinallyAlways); + group.add(myRbEvaluateFinallyNever); + group.add(myRbEvaluateFinallyAsk); + final Box box = Box.createHorizontalBox(); + box.add(myRbEvaluateFinallyAlways); + box.add(myRbEvaluateFinallyNever); + box.add(myRbEvaluateFinallyAsk); + final JPanel evalFinallyPanel = new JPanel(new BorderLayout()); + evalFinallyPanel.add(box, BorderLayout.CENTER); + evalFinallyPanel.add(new JLabel(DebuggerBundle.message("label.debugger.general.configurable.evaluate.finally.on.pop")), BorderLayout.WEST); + panel.add(evalFinallyPanel, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(4, cbLeftOffset, 0, 0), 0, 0)); + return panel; } }
\ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java index deff5fbd2ae5..8805341c5c46 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerEditorImpl.java @@ -294,7 +294,7 @@ public abstract class DebuggerEditorImpl extends CompletionEditor{ } @NotNull - public static CodeFragmentFactory findAppropriateFactory(@NotNull TextWithImports text, @NotNull PsiElement context) { + private static CodeFragmentFactory findAppropriateFactory(@NotNull TextWithImports text, @Nullable PsiElement context) { for (CodeFragmentFactory factory : DebuggerUtilsEx.getCodeFragmentFactories(context)) { if (factory.getFileType().equals(text.getFileType())) { return factory; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java index 47fc217751a4..0855ed3c1cc4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -41,7 +41,6 @@ import com.intellij.execution.filters.TextConsoleBuilder; import com.intellij.execution.filters.TextConsoleBuilderFactory; import com.intellij.execution.ui.ConsoleView; import com.intellij.execution.ui.ExecutionConsoleEx; -import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunnerLayoutUi; import com.intellij.execution.ui.layout.PlaceInGrid; import com.intellij.icons.AllIcons; @@ -109,7 +108,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos if (XDebuggerSettingsManager.getInstanceImpl().getGeneralSettings().isHideDebuggerOnProcessTermination()) { try { - ExecutionManager.getInstance(getProject()).getContentManager().hideRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor); + ExecutionManager.getInstance(project).getContentManager().hideRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), myRunContentDescriptor); } catch (NullPointerException e) { //if we can get closeProcess after the project have been closed @@ -130,8 +129,8 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos topToolbar.add(Separator.getInstance(), new Constraints(Anchor.AFTER, DebuggerActions.POP_FRAME)); myUi.getOptions().setTopToolbar(topToolbar, ActionPlaces.DEBUGGER_TOOLBAR); - myWatchPanel = new MainWatchPanel(getProject(), getContextManager()); - myFramesPanel = new FramesPanel(getProject(), getContextManager()); + myWatchPanel = new MainWatchPanel(project, getContextManager()); + myFramesPanel = new FramesPanel(project, getContextManager()); final AlertIcon breakpointAlert = new AlertIcon(AllIcons.Debugger.BreakpointAlert); @@ -151,7 +150,7 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos myUi.addContent(framesContent, 0, PlaceInGrid.left, false); // variables - myVariablesPanel = new VariablesPanel(getProject(), myStateManager, this); + myVariablesPanel = new VariablesPanel(project, myStateManager, this); myVariablesPanel.getFrameTree().setAutoVariablesMode(debuggerSettings.AUTO_VARIABLES_MODE); Content vars = myUi.createContent(DebuggerContentInfo.VARIABLES_CONTENT, myVariablesPanel, XDebuggerBundle.message("debugger.session.tab.variables.title"), AllIcons.Debugger.Value, null); @@ -200,11 +199,11 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos } }); - ExecutionResult executionResult = debuggerSession.getProcess().getExecutionResult(); - myConsole = executionResult.getExecutionConsole(); - myRunContentDescriptor = new RunContentDescriptor(myConsole, executionResult.getProcessHandler(), myUi.getComponent(), getSessionName(), - environment.getIcon()); - initUI(executionResult); +// ExecutionResult executionResult = debuggerSession.getProcess().getExecutionResult(); +// myConsole = executionResult.getExecutionConsole(); +// myRunContentDescriptor = new RunContentDescriptor(myConsole, executionResult.getProcessHandler(), myUi.getComponent(), getSessionName(), +// environment.getIcon()); +// initUI(executionResult); } private static void updateStatus(final Content content) { @@ -226,11 +225,6 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos return myWatchPanel; } - @Override - public RunContentDescriptor getRunContentDescriptor() { - return myRunContentDescriptor; - } - private void initUI(ExecutionResult executionResult) { if (ApplicationManager.getApplication().isUnitTestMode()) { return; @@ -270,18 +264,16 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos } console.setActions(consoleActions, ActionPlaces.DEBUGGER_TOOLBAR, myConsole.getPreferredFocusableComponent()); - myDebugUIEnvironment.initLogs(myRunContentDescriptor, myManager); +// myDebugUIEnvironment.initLogs(myRunContentDescriptor, myManager); DefaultActionGroup leftToolbar = new DefaultActionGroup(); if (executionResult instanceof DefaultExecutionResult) { final AnAction[] actions = ((DefaultExecutionResult)executionResult).getRestartActions(); - if (actions != null) { leftToolbar.addAll(actions); if (actions.length > 0) { leftToolbar.addSeparator(); } - } } final AnAction[] profileActions = executionResult.getActions(); leftToolbar.addAll(profileActions); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/EvaluationDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/EvaluationDialog.java index 6359af31e5a3..0acaf8779e1f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/EvaluationDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/EvaluationDialog.java @@ -30,7 +30,6 @@ import com.intellij.debugger.ui.impl.ValueNodeDnD; import com.intellij.debugger.ui.impl.WatchDebuggerTree; import com.intellij.debugger.ui.impl.WatchPanel; import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; -import com.intellij.debugger.ui.impl.watch.EvaluationDescriptor; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.*; @@ -110,10 +109,10 @@ public abstract class EvaluationDialog extends DialogWrapper { try { setOKActionEnabled(false); NodeDescriptorImpl descriptor = myEvaluationPanel.getWatchTree().addWatch(codeToEvaluate, "result").getDescriptor(); - if (descriptor instanceof EvaluationDescriptor) { - final EvaluationDescriptor evalDescriptor = (EvaluationDescriptor)descriptor; - evalDescriptor.setCodeFragmentFactory(myEditor.getCurrentFactory()); - } + //if (descriptor instanceof EvaluationDescriptor) { + // final EvaluationDescriptor evalDescriptor = (EvaluationDescriptor)descriptor; + // evalDescriptor.setCodeFragmentFactory(myEditor.getCurrentFactory()); + //} myEvaluationPanel.getWatchTree().rebuild(getDebuggerContext()); descriptor.myIsExpanded = true; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java index ec2288fa7a57..e01b8742c4b6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/JavaDebuggerSupport.java @@ -61,7 +61,7 @@ public class JavaDebuggerSupport extends DebuggerSupport { private final PauseActionHandler myPauseActionHandler = new PauseActionHandler(); private final ShowExecutionPointActionHandler myShowExecutionPointActionHandler = new ShowExecutionPointActionHandler(); //private final EvaluateActionHandler myEvaluateActionHandler = new EvaluateActionHandler(); - private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler(); + //private final QuickEvaluateActionHandler myQuickEvaluateHandler = new QuickEvaluateActionHandler(); private final DebuggerActionHandler mySmartStepIntoHandler = new JvmSmartStepIntoActionHandler(); private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler(); private final JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler(); @@ -156,12 +156,6 @@ public class JavaDebuggerSupport extends DebuggerSupport { return DISABLED; } - @Override - @NotNull - public QuickEvaluateHandler getQuickEvaluateHandler() { - return myQuickEvaluateHandler; - } - @NotNull @Override public DebuggerActionHandler getAddToWatchesActionHandler() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java b/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java index 8a0877273335..9034e5c82b13 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java @@ -94,9 +94,8 @@ public class ValueHint extends AbstractValueHint { return EvaluatorBuilderImpl.getInstance().build(myCurrentExpression, debuggerContext.getSourcePosition()); } - CodeFragmentFactory factory = DebuggerUtilsEx.getEffectiveCodeFragmentFactory(myCurrentExpression); TextWithImportsImpl textWithImports = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myCurrentExpression.getText()); - if (factory == null) return null; + CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(textWithImports, myCurrentExpression); JavaCodeFragment codeFragment = factory.createCodeFragment(textWithImports, myCurrentExpression.getContext(), getProject()); codeFragment.forceResolveScope(GlobalSearchScope.allScope(getProject())); return factory.getEvaluatorBuilder().build(codeFragment, debuggerContext.getSourcePosition()); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ArgumentValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ArgumentValueDescriptorImpl.java index 7adee9d7c0eb..525abba6613f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ArgumentValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ArgumentValueDescriptorImpl.java @@ -50,6 +50,11 @@ public class ArgumentValueDescriptorImpl extends ValueDescriptorImpl{ setLvalue(true); } + @Override + public boolean canSetValue() { + return false; + } + public boolean isPrimitive() { return myValue instanceof PrimitiveValue; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java index 042216c40f05..467cf985f04c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java @@ -15,28 +15,57 @@ */ package com.intellij.debugger.ui.impl.watch; +import com.intellij.debugger.DebuggerInvocationUtil; +import com.intellij.debugger.EvaluatingComputable; +import com.intellij.debugger.engine.ContextUtil; import com.intellij.debugger.engine.DebugProcess; -import com.intellij.debugger.engine.evaluation.EvaluateException; -import com.intellij.debugger.engine.evaluation.EvaluationContext; -import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.debugger.engine.evaluation.expression.Modifier; +import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiCodeFragment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiJavaFile; +import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; import com.sun.jdi.*; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.org.objectweb.asm.ClassReader; +import org.jetbrains.org.objectweb.asm.ClassVisitor; +import org.jetbrains.org.objectweb.asm.ClassWriter; +import org.jetbrains.org.objectweb.asm.Opcodes; import javax.tools.*; import java.io.ByteArrayOutputStream; import java.net.URI; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; /** * @author egor */ -class CompilingEvaluator implements ExpressionEvaluator { +public class CompilingEvaluator implements ExpressionEvaluator { private final TextWithImports myText; - - public CompilingEvaluator(TextWithImports text) { + private final PsiCodeFragment myCodeFragment; + private final PsiElement myPsiContext; + @NotNull private final ExtractLightMethodObjectHandler.ExtractedData myData; + private final EvaluationDescriptor myDescriptor; + + public CompilingEvaluator(TextWithImports text, + PsiCodeFragment codeFragment, + PsiElement context, + @NotNull ExtractLightMethodObjectHandler.ExtractedData data, + EvaluationDescriptor descriptor) { myText = text; + myCodeFragment = codeFragment; + myPsiContext = context; + myData = data; + myDescriptor = descriptor; } @Override @@ -49,20 +78,41 @@ class CompilingEvaluator implements ExpressionEvaluator { return null; } + private TextWithImports getCallCode() { + return new TextWithImportsImpl(CodeFragmentKind.CODE_BLOCK, myData.getGeneratedCallText()); + } + @Override - public Value evaluate(EvaluationContext context) throws EvaluateException { + public Value evaluate(final EvaluationContext evaluationContext) throws EvaluateException { try { - DebugProcess process = context.getDebugProcess(); - ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference(); + DebugProcess process = evaluationContext.getDebugProcess(); + ThreadReference threadReference = evaluationContext.getSuspendContext().getThread().getThreadReference(); - ClassLoaderReference classLoader = getClassLoader(context); + ClassLoaderReference classLoader = getClassLoader(evaluationContext); Collection<OutputFileObject> classes = compile(); - ClassType mainClass = defineClasses(classes, context, process, threadReference, classLoader); - - Method foo = mainClass.methodsByName(GEN_METHOD_NAME).get(0); - return mainClass.invokeMethod(threadReference, foo, Collections.<Value>emptyList() ,ClassType.INVOKE_SINGLE_THREADED); + ClassType mainClass = defineClasses(classes, evaluationContext, process, threadReference, classLoader); + + //Method foo = mainClass.methodsByName(GEN_METHOD_NAME).get(0); + //return mainClass.invokeMethod(threadReference, foo, Collections.<Value>emptyList() ,ClassType.INVOKE_SINGLE_THREADED); + + // invoke base evaluator on call code + final Project project = myPsiContext.getProject(); + ExpressionEvaluator evaluator = + DebuggerInvocationUtil.commitAndRunReadAction(project, new EvaluatingComputable<ExpressionEvaluator>() { + @Override + public ExpressionEvaluator compute() throws EvaluateException { + final TextWithImports callCode = getCallCode(); + PsiElement copyContext = myData.getAnchor(); + final CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(callCode, copyContext); + return factory.getEvaluatorBuilder(). + build(factory.createCodeFragment(callCode, copyContext, project), + ContextUtil.getSourcePosition(evaluationContext)); + } + }); + ((EvaluationContextImpl)evaluationContext).setClassLoader(classLoader); + return evaluator.evaluate(evaluationContext); } catch (Exception e) { throw new EvaluateException(e.getMessage()); @@ -74,13 +124,13 @@ class CompilingEvaluator implements ExpressionEvaluator { // TODO: cache DebugProcess process = context.getDebugProcess(); ClassType loaderClass = (ClassType)process.findClass(context, "java.net.URLClassLoader", context.getClassLoader()); - Method ctorMethod = loaderClass.concreteMethodByName("<init>", "([Ljava/net/URL;)V"); + Method ctorMethod = loaderClass.concreteMethodByName("<init>", "([Ljava/net/URL;Ljava/lang/ClassLoader;)V"); ThreadReference threadReference = context.getSuspendContext().getThread().getThreadReference(); return (ClassLoaderReference)loaderClass.newInstance(threadReference, ctorMethod, - Arrays.asList(createURLArray(context)), ClassType.INVOKE_SINGLE_THREADED); + Arrays.asList(createURLArray(context), context.getClassLoader()), ClassType.INVOKE_SINGLE_THREADED); } - private static ClassType defineClasses(Collection<OutputFileObject> classes, + private ClassType defineClasses(Collection<OutputFileObject> classes, EvaluationContext context, DebugProcess process, ThreadReference threadReference, @@ -89,16 +139,34 @@ class CompilingEvaluator implements ExpressionEvaluator { VirtualMachineProxyImpl proxy = (VirtualMachineProxyImpl)process.getVirtualMachineProxy(); for (OutputFileObject cls : classes) { - Method defineMethod = ((ClassType)classLoader.referenceType()).concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;"); - byte[] bytes = cls.toByteArray(); - ArrayList<Value> args = new ArrayList<Value>(); - args.add(proxy.mirrorOf(cls.myOrigName)); - args.add(mirrorOf(bytes, context, process)); - args.add(proxy.mirrorOf(0)); - args.add(proxy.mirrorOf(bytes.length)); - classLoader.invokeMethod(threadReference, defineMethod, args, ClassType.INVOKE_SINGLE_THREADED); + if (cls.getName().contains(getGenClassName())) { + Method defineMethod = + ((ClassType)classLoader.referenceType()).concreteMethodByName("defineClass", "(Ljava/lang/String;[BII)Ljava/lang/Class;"); + byte[] bytes = changeSuperToMagicAccessor(cls.toByteArray()); + ArrayList<Value> args = new ArrayList<Value>(); + args.add(proxy.mirrorOf(cls.myOrigName)); + args.add(mirrorOf(bytes, context, process)); + args.add(proxy.mirrorOf(0)); + args.add(proxy.mirrorOf(bytes.length)); + classLoader.invokeMethod(threadReference, defineMethod, args, ClassType.INVOKE_SINGLE_THREADED); + } } - return (ClassType)process.findClass(context, GEN_CLASS_FULL_NAME, classLoader); + return (ClassType)process.findClass(context, getGenClassFullName(), classLoader); + } + + private static byte[] changeSuperToMagicAccessor(byte[] bytes) { + ClassWriter classWriter = new ClassWriter(0); + ClassVisitor classVisitor = new ClassVisitor(Opcodes.ASM5, classWriter) { + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + if ("java/lang/Object".equals(superName)) { + superName = "sun/reflect/MagicAccessorImpl"; + } + super.visit(version, access, name, signature, superName, interfaces); + } + }; + new ClassReader(bytes).accept(classVisitor, 0); + return classWriter.toByteArray(); } private static ArrayReference mirrorOf(byte[] bytes, EvaluationContext context, DebugProcess process) @@ -112,10 +180,90 @@ class CompilingEvaluator implements ExpressionEvaluator { return reference; } - private static final String GEN_CLASS_NAME = "Evaluator"; + public static String getGeneratedClassName() { + return GEN_CLASS_NAME; + } + + private static final String GEN_CLASS_NAME = "GeneratedEvaluationClass"; private static final String GEN_CLASS_PACKAGE = "dummy"; private static final String GEN_CLASS_FULL_NAME = GEN_CLASS_PACKAGE + '.' + GEN_CLASS_NAME; - private static final String GEN_METHOD_NAME = "eval"; + private static final String GEN_METHOD_NAME = "invoke"; + + private String getClassCode() { + if (myData != null) { + return ApplicationManager.getApplication().runReadAction(new Computable<String>() { + @Override + public String compute() { + //String text = myData.getGeneratedInnerClass().getText(); + ////TODO: remove + //String prefix = "public static"; + //if (text.startsWith(prefix)) { + // text = "public" + text.substring(prefix.length()); + //} + //PsiElement[] children = ((PsiJavaFile)myPsiContext.getContainingFile()).getImportList().getChildren(); + //StringBuilder imports = new StringBuilder(); + //for (PsiElement child : children) { + // if (child instanceof PsiImportStatement) { + // String name = ((PsiImportStatement)child).getImportReference().getQualifiedName(); + // imports.append("import ").append(name).append(";"); + // } + //} + //text = text.replace("class " + GEN_CLASS_NAME, "class " + getGenClassName()); + //text = text.replace(GEN_CLASS_NAME + "(", getGenClassName() + "("); + //text = text.replace(((PsiClass)myData.getGeneratedInnerClass().getParent()).getName() + "." + GEN_CLASS_NAME, getGenClassName()); + //return "package " + getGenPackageName() + "; " + imports.toString() + text; + return myData.getGeneratedInnerClass().getContainingFile().getText(); + } + }); + } + return null; + } + + private String getGenPackageName() { + return ApplicationManager.getApplication().runReadAction(new Computable<String>() { + @Override + public String compute() { + return ((PsiJavaFile)myData.getGeneratedInnerClass().getContainingFile()).getPackageName(); + } + }); + } + + private String getMainClassName() { + return ApplicationManager.getApplication().runReadAction(new Computable<String>() { + @Override + public String compute() { + return ((PsiClass)myData.getGeneratedInnerClass().getParent()).getName(); + } + }); + } + + private String getGenClassName() { + return getMainClassName() + '$' + GEN_CLASS_NAME; + } + + private String getGenClassFullName() { + String packageName = getGenPackageName(); + if (packageName.isEmpty()) { + return getGenClassName(); + } + return packageName + '.' + getGenClassName(); + } + + //private String createClassCode() { + // return ApplicationManager.getApplication().runReadAction(new Computable<String>() { + // @Override + // public String compute() { + // try { + // myExtractedData = + // ExtractLightMethodObjectHandler.extractLightMethodObject(myCodeFragment.getProject(), myFile , myCodeFragment, "test"); + // } + // catch (PrepareFailedException e) { + // e.printStackTrace(); + // } + // return null; + // } + // }); + //} private static String createClassCode(TextWithImports body) { StringBuilder text = new StringBuilder(); @@ -155,9 +303,9 @@ class CompilingEvaluator implements ExpressionEvaluator { MemoryFileManager manager = new MemoryFileManager(compiler); DiagnosticCollector<JavaFileObject> diagnostic = new DiagnosticCollector<JavaFileObject>(); if (!compiler.getTask(null, manager, diagnostic, null, null, Arrays - .asList(new SourceFileObject(GEN_CLASS_NAME, JavaFileObject.Kind.SOURCE, createClassCode(myText)))).call()) { + .asList(new SourceFileObject(getMainClassName(), JavaFileObject.Kind.SOURCE, getClassCode()))).call()) { // TODO: show only errors - throw new EvaluateException(diagnostic.getDiagnostics().get(0).getMessage(Locale.getDefault())); + throw new EvaluateException(diagnostic.getDiagnostics().get(0).toString()); } return manager.classes; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java index 1f880513cacd..05e0a1fe6aec 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java @@ -21,22 +21,26 @@ import com.intellij.debugger.DebuggerInvocationUtil; import com.intellij.debugger.EvaluatingComputable; import com.intellij.debugger.engine.ContextUtil; import com.intellij.debugger.engine.StackFrameContext; -import com.intellij.debugger.engine.evaluation.*; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.evaluation.expression.UnsupportedExpressionException; import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator; import com.intellij.debugger.engine.evaluation.expression.Modifier; import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.impl.PositionUtil; import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.registry.Registry; -import com.intellij.psi.PsiCodeFragment; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiExpression; -import com.intellij.psi.PsiExpressionCodeFragment; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.refactoring.extractMethod.PrepareFailedException; +import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler; +import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ObjectReference; import com.sun.jdi.Value; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; /** * @author lex @@ -44,7 +48,6 @@ import org.jetbrains.annotations.Nullable; public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ private Modifier myModifier; protected TextWithImports myText; - private CodeFragmentFactory myCodeFragmentFactory = null; // used to force specific context, e.g. from evaluation protected EvaluationDescriptor(TextWithImports text, Project project, Value value) { super(project, value); @@ -57,44 +60,60 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ myText = text; } - public final void setCodeFragmentFactory(CodeFragmentFactory codeFragmentFactory) { - myCodeFragmentFactory = codeFragmentFactory != null? new CodeFragmentFactoryContextWrapper(codeFragmentFactory) : null; - } - - @Nullable - public final CodeFragmentFactory getCodeFragmentFactory() { - return myCodeFragmentFactory; - } - - protected final @NotNull CodeFragmentFactory getEffectiveCodeFragmentFactory(final PsiElement psiContext) { - if (myCodeFragmentFactory != null) { - return myCodeFragmentFactory; - } - return DebuggerUtilsEx.getEffectiveCodeFragmentFactory(psiContext); - } - protected abstract EvaluationContextImpl getEvaluationContext (EvaluationContextImpl evaluationContext); protected abstract PsiCodeFragment getEvaluationCode(StackFrameContext context) throws EvaluateException; + public PsiCodeFragment createCodeFragment(PsiElement context) { + TextWithImports text = getEvaluationText(); + final PsiCodeFragment fragment = + DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createCodeFragment(text, context, myProject); + fragment.forceResolveScope(GlobalSearchScope.allScope(myProject)); + return fragment; + } + public final Value calcValue(final EvaluationContextImpl evaluationContext) throws EvaluateException { try { final EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext); - final ExpressionEvaluator evaluator; - if (Registry.is("debugger.compiling.evaluator")) { - evaluator = new CompilingEvaluator(getEvaluationText()); - } - else { + ExpressionEvaluator evaluator = null; + try { evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable<ExpressionEvaluator>() { public ExpressionEvaluator compute() throws EvaluateException { final PsiElement psiContext = PositionUtil.getContextElement(evaluationContext); - return getEffectiveCodeFragmentFactory(psiContext).getEvaluatorBuilder().build(getEvaluationCode(thisEvaluationContext), - ContextUtil - .getSourcePosition(thisEvaluationContext)); + return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(getEvaluationText(), psiContext).getEvaluatorBuilder() + .build(getEvaluationCode(thisEvaluationContext), ContextUtil.getSourcePosition(thisEvaluationContext)); } }); } + catch (UnsupportedExpressionException ex) { + if (Registry.is("debugger.compiling.evaluator")) { + evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable<ExpressionEvaluator>() { + public ExpressionEvaluator compute() throws EvaluateException { + final PsiElement psiContext = PositionUtil.getContextElement(evaluationContext); + if (psiContext == null) { + return null; + } + PsiFile psiFile = psiContext.getContainingFile(); + PsiCodeFragment fragment = createCodeFragment(psiContext); + try { + ExtractLightMethodObjectHandler.ExtractedData data = ExtractLightMethodObjectHandler.extractLightMethodObject(myProject, + psiFile, fragment, CompilingEvaluator.getGeneratedClassName()); + if (data != null) { + return new CompilingEvaluator(getEvaluationText(), getEvaluationCode(thisEvaluationContext), psiContext, data, + EvaluationDescriptor.this); + } + } + catch (PrepareFailedException ignored) { + } + return null; + } + }); + } + if (evaluator == null) { + throw ex; + } + } if (!thisEvaluationContext.getDebugProcess().isAttached()) { throw EvaluateExceptionUtil.PROCESS_EXITED; @@ -106,7 +125,11 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ final Value value = evaluator.evaluate(thisEvaluationContext); if (value instanceof ObjectReference) { - thisEvaluationContext.getSuspendContext().keep(((ObjectReference)value)); + ObjectReference objRef = (ObjectReference)value; + if (VirtualMachineProxyImpl.isCollected(objRef)) { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } + thisEvaluationContext.getSuspendContext().keep(objRef); } myModifier = evaluator.getModifier(); setLvalue(myModifier != null); @@ -116,6 +139,9 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl{ catch (final EvaluateException ex) { throw new EvaluateException(ex.getLocalizedMessage(), ex); } + catch (ObjectCollectedException ex) { + throw EvaluateExceptionUtil.OBJECT_WAS_COLLECTED; + } } public String calcValueName() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java index 3455672fa4dc..0a94548338d4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorFactoryImpl.java @@ -93,6 +93,10 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { } public void deriveHistoryTree(DescriptorTree tree, final StackFrameContext context) { + deriveHistoryTree(tree, context.getFrameProxy()); + } + + public void deriveHistoryTree(DescriptorTree tree, final StackFrameProxy frameProxy) { final MarkedDescriptorTree descriptorTree = new MarkedDescriptorTree(); final MarkedDescriptorTree displayDescriptorTree = new MarkedDescriptorTree(); @@ -109,13 +113,12 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { myDescriptorSearcher = new DescriptorTreeSearcher(descriptorTree); myDisplayDescriptorSearcher = new DisplayDescriptorTreeSearcher(displayDescriptorTree); - myCurrentHistoryTree = createDescriptorTree(context, tree); + myCurrentHistoryTree = createDescriptorTree(frameProxy, tree); } - private static DescriptorTree createDescriptorTree(final StackFrameContext context, final DescriptorTree fromTree) { + private static DescriptorTree createDescriptorTree(final StackFrameProxy frameProxy, final DescriptorTree fromTree) { int frameCount = -1; int frameIndex = -1; - final StackFrameProxy frameProxy = context.getFrameProxy(); if (frameProxy != null) { try { final ThreadReferenceProxy threadReferenceProxy = frameProxy.threadProxy(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java index 53e820da02fd..b76022122594 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java @@ -75,11 +75,15 @@ public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeMa } public void setHistoryByContext(final DebuggerContextImpl context) { + setHistoryByContext(context.getFrameProxy()); + } + + public void setHistoryByContext(StackFrameProxyImpl frameProxy) { if (myHistoryKey != null) { myHistories.put(myHistoryKey, getCurrentHistoryTree()); } - final String historyKey = getContextKey(context.getFrameProxy()); + final String historyKey = getContextKey(frameProxy); final DescriptorTree descriptorTree; if (historyKey != null) { final DescriptorTree historyTree = myHistories.get(historyKey); @@ -89,7 +93,7 @@ public class NodeManagerImpl extends NodeDescriptorFactoryImpl implements NodeMa descriptorTree = new DescriptorTree(true); } - deriveHistoryTree(descriptorTree, context); + deriveHistoryTree(descriptorTree, frameProxy); myHistoryKey = historyKey; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java index c3dbed6c7fbb..35e73c2b6378 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/UserExpressionDescriptorImpl.java @@ -21,19 +21,18 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.StackFrameContext; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluateExceptionUtil; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.evaluation.TextWithImports; -import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.tree.UserExpressionDescriptor; import com.intellij.debugger.ui.tree.render.ClassRenderer; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiCodeFragment; -import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.StringBuilderSpinAllocator; import com.sun.jdi.ObjectReference; import com.sun.jdi.Value; @@ -78,16 +77,13 @@ public class UserExpressionDescriptorImpl extends EvaluationDescriptor implement if(value instanceof ObjectReference) { final String typeName = value.type().name(); - final PsiClass psiClass = DebuggerUtilsEx.findClass(myTypeName, myProject, context.getDebugProcess().getSearchScope()); + final PsiClass psiClass = DebuggerUtils.findClass(myTypeName, myProject, context.getDebugProcess().getSearchScope()); if (psiClass == null) { throw EvaluateExceptionUtil.createEvaluateException(DebuggerBundle.message("evaluation.error.invalid.type.name", typeName)); } - final PsiCodeFragment fragment = - getEffectiveCodeFragmentFactory(psiClass).createCodeFragment(getEvaluationText(), psiClass, myProject); - fragment.forceResolveScope(GlobalSearchScope.allScope(myProject)); - return fragment; + return createCodeFragment(psiClass); } else { throw EvaluateExceptionUtil.createEvaluateException( diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java index 30f5169fbd1e..f60825cee24c 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/WatchItemDescriptor.java @@ -28,8 +28,6 @@ import com.intellij.debugger.impl.PositionUtil; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Comparing; import com.intellij.psi.PsiCodeFragment; -import com.intellij.psi.PsiElement; -import com.intellij.psi.search.GlobalSearchScope; import com.sun.jdi.Value; import org.jetbrains.annotations.Nullable; @@ -85,9 +83,6 @@ public class WatchItemDescriptor extends EvaluationDescriptor { } protected PsiCodeFragment getEvaluationCode(StackFrameContext context) throws EvaluateException { - final PsiElement psiContext = PositionUtil.getContextElement(context); - final PsiCodeFragment fragment = getEffectiveCodeFragmentFactory(psiContext).createCodeFragment(getEvaluationText(), psiContext, myProject); - fragment.forceResolveScope(GlobalSearchScope.allScope(myProject)); - return fragment; + return createCodeFragment(PositionUtil.getContextElement(context)); } }
\ No newline at end of file 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 9615aae98233..f7f05fcc496f 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 @@ -65,6 +65,8 @@ public class ArrayRenderer extends NodeRendererImpl{ public int ENTRIES_LIMIT = 101; private final static String MORE_ELEMENTS = "..."; + private boolean myForced = false; + public ArrayRenderer() { myProperties.setEnabled(true); } @@ -97,13 +99,19 @@ public class ArrayRenderer extends NodeRendererImpl{ return ClassRenderer.calcLabel(descriptor); } + public void setForced(boolean forced) { + myForced = forced; + } + public void buildChildren(Value value, ChildrenBuilder builder, EvaluationContext evaluationContext) { DebuggerManagerThreadImpl.assertIsManagerThread(); List<DebuggerTreeNode> children = new ArrayList<DebuggerTreeNode>(); NodeManagerImpl nodeManager = (NodeManagerImpl)builder.getNodeManager(); NodeDescriptorFactory descriptorFactory = builder.getDescriptorManager(); - builder.initChildrenArrayRenderer(this); + if (!myForced) { + builder.initChildrenArrayRenderer(this); + } ArrayReference array = (ArrayReference)value; if (array.length() > 0) { @@ -182,7 +190,7 @@ public class ArrayRenderer extends NodeRendererImpl{ // children.add(0, nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); //} - if(END_INDEX < array.length() - 1) { + if(!myForced && END_INDEX < array.length() - 1) { //children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); builder.setRemaining(array.length()-END_INDEX); } |