diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java index 61bfd7354378..01d6fcc6e7e8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/CustomizeContextViewAction.java @@ -16,12 +16,10 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.settings.DebuggerDataViewsConfigurable; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.settings.UserRenderersConfigurable; -import com.intellij.debugger.ui.impl.FrameVariablesTree; -import com.intellij.debugger.ui.impl.WatchDebuggerTree; -import com.intellij.debugger.ui.impl.watch.DebuggerTree; import com.intellij.idea.ActionsBundle; import com.intellij.openapi.Disposable; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -33,6 +31,12 @@ import com.intellij.openapi.options.TabbedConfigurable; import com.intellij.openapi.options.ex.SingleConfigurableEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; +import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; +import org.jetbrains.annotations.NotNull; import javax.swing.*; import javax.swing.border.EmptyBorder; @@ -44,9 +48,15 @@ import java.util.List; * Date: Sep 26, 2003 * Time: 4:39:53 PM */ -public class CustomizeContextViewAction extends DebuggerAction{ +public class CustomizeContextViewAction extends XDebuggerTreeActionBase { + @Override public void actionPerformed(AnActionEvent e) { + perform(null, "", e); + } + + @Override + protected void perform(XValueNodeImpl node, @NotNull String nodeName, AnActionEvent e) { final Project project = CommonDataKeys.PROJECT.getData(e.getDataContext()); Disposable disposable = Disposer.newDisposable(); @@ -92,8 +102,13 @@ public class CustomizeContextViewAction extends DebuggerAction{ @Override public void update(AnActionEvent e) { - DebuggerTree tree = getTree(e.getDataContext()); - e.getPresentation().setVisible(tree instanceof FrameVariablesTree || tree instanceof WatchDebuggerTree); - e.getPresentation().setText(ActionsBundle.actionText(DebuggerActions.CUSTOMIZE_VIEWS)); + final XDebuggerManager debuggerManager = XDebuggerManager.getInstance(getEventProject(e)); + final XDebugSession currentSession = debuggerManager.getCurrentSession(); + if (currentSession != null) { + final XDebugProcess process = currentSession.getDebugProcess(); + e.getPresentation().setVisible(process instanceof JavaDebugProcess); + e.getPresentation().setEnabled(process instanceof JavaDebugProcess); + e.getPresentation().setText(ActionsBundle.actionText(DebuggerActions.CUSTOMIZE_VIEWS)); + } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JavaValueModifier.java similarity index 69% rename from java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java rename to java/debugger/impl/src/com/intellij/debugger/actions/JavaValueModifier.java index b8de9e654fd6..89235a143b33 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/SetValueAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JavaValueModifier.java @@ -19,6 +19,7 @@ import com.intellij.debugger.DebuggerBundle; import com.intellij.debugger.DebuggerInvocationUtil; import com.intellij.debugger.DebuggerManagerEx; import com.intellij.debugger.engine.ContextUtil; +import com.intellij.debugger.engine.JavaValue; import com.intellij.debugger.engine.evaluation.*; import com.intellij.debugger.engine.evaluation.expression.*; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; @@ -30,21 +31,18 @@ import com.intellij.debugger.ui.DebuggerExpressionComboBox; import com.intellij.debugger.ui.EditorEvaluationCommand; import com.intellij.debugger.ui.impl.DebuggerTreeRenderer; import com.intellij.debugger.ui.impl.watch.*; -import com.intellij.debugger.ui.tree.render.HexRenderer; -import com.intellij.debugger.ui.tree.render.NodeRenderer; -import com.intellij.debugger.ui.tree.render.ValueLabelRenderer; -import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.util.ProgressIndicatorListenerAdapter; import com.intellij.openapi.progress.util.ProgressWindowWithNotification; -import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; import com.intellij.ui.SimpleColoredComponent; import com.intellij.util.IJSwingUtilities; +import com.intellij.xdebugger.frame.XValueModifier; import com.sun.jdi.*; +import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -52,20 +50,26 @@ import javax.swing.*; * Class SetValueAction * @author Jeka */ -public class SetValueAction extends DebuggerAction { - public void update(AnActionEvent e) { - boolean enable = false; - DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); - if (node != null) { - NodeDescriptorImpl descriptor = node.getDescriptor(); - if(descriptor instanceof ValueDescriptorImpl){ - ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl)descriptor); - enable = valueDescriptor.canSetValue(); - } - } - e.getPresentation().setVisible(enable); +public class JavaValueModifier extends XValueModifier { + private final JavaValue myJavaValue; + + public JavaValueModifier(JavaValue javaValue) { + myJavaValue = javaValue; } + //public void update(AnActionEvent e) { + // boolean enable = false; + // DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext()); + // if (node != null) { + // NodeDescriptorImpl descriptor = node.getDescriptor(); + // if(descriptor instanceof ValueDescriptorImpl){ + // ValueDescriptorImpl valueDescriptor = ((ValueDescriptorImpl)descriptor); + // enable = valueDescriptor.canSetValue(); + // } + // } + // e.getPresentation().setVisible(enable); + //} + // private void update(final DebuggerContextImpl context) { DebuggerInvocationUtil.swingInvokeLater(context.getProject(), new Runnable() { public void run() { @@ -78,12 +82,9 @@ public class SetValueAction extends DebuggerAction { //node.setState(context); } - public void actionPerformed(final AnActionEvent event) { - final DebuggerTreeNodeImpl node = getSelectedNode(event.getDataContext()); - if (node == null) { - return; - } - final NodeDescriptorImpl descriptor = node.getDescriptor(); + @Override + public void setValue(@NotNull String expression, @NotNull XModificationCallback callback) { + final NodeDescriptorImpl descriptor = myJavaValue.getDescriptor(); if (!(descriptor instanceof ValueDescriptorImpl)) { return; } @@ -91,9 +92,10 @@ public class SetValueAction extends DebuggerAction { return; } - final DebuggerTree tree = getTree(event.getDataContext()); - final DebuggerContextImpl debuggerContext = getDebuggerContext(event.getDataContext()); - tree.saveState(node); + //final DebuggerTree tree = getTree(event.getDataContext()); + //final DebuggerContextImpl debuggerContext = getDebuggerContext(event.getDataContext()); + final DebuggerContextImpl debuggerContext = DebuggerManagerEx.getInstanceEx(myJavaValue.getProject()).getContext(); + //tree.saveState(node); if (descriptor instanceof FieldDescriptorImpl) { FieldDescriptorImpl fieldDescriptor = (FieldDescriptorImpl)descriptor; @@ -101,17 +103,19 @@ public class SetValueAction extends DebuggerAction { if (!field.isStatic()) { final ObjectReference object = fieldDescriptor.getObject(); if (object != null) { - askAndSet(node, debuggerContext, new SetValueRunnable() { - public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + set(expression, callback, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) + throws ClassNotLoadedException, InvalidTypeException, EvaluateException { object.setValue(field, preprocessValue(evaluationContext, newValue, field.type())); update(debuggerContext); } - public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvalidTypeException, - EvaluateException { + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws + InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, field.declaringType().classLoader()); } }); @@ -122,17 +126,19 @@ public class SetValueAction extends DebuggerAction { ReferenceType refType = field.declaringType(); if (refType instanceof ClassType) { final ClassType classType = (ClassType)refType; - askAndSet(node, debuggerContext, new SetValueRunnable() { - public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + set(expression, callback, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) + throws ClassNotLoadedException, InvalidTypeException, EvaluateException { classType.setValue(field, preprocessValue(evaluationContext, newValue, field.type())); update(debuggerContext); } - public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvalidTypeException, - EvaluateException { + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws + InvocationException, + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, field.declaringType().classLoader()); } @@ -144,19 +150,19 @@ public class SetValueAction extends DebuggerAction { LocalVariableDescriptorImpl localDescriptor = (LocalVariableDescriptorImpl)descriptor; final LocalVariableProxyImpl local = localDescriptor.getLocalVariable(); if (local != null) { - askAndSet(node, debuggerContext, new SetValueRunnable() { + set(expression, callback, debuggerContext, new SetValueRunnable() { public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, - InvalidTypeException, - EvaluateException { + InvalidTypeException, + EvaluateException { debuggerContext.getFrameProxy().setValue(local, preprocessValue(evaluationContext, newValue, local.getType())); update(debuggerContext); } public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvalidTypeException, - EvaluateException { + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, evaluationContext.getClassLoader()); } @@ -169,22 +175,23 @@ public class SetValueAction extends DebuggerAction { if (array != null) { if (VirtualMachineProxyImpl.isCollected(array)) { // will only be the case if debugger does not use ObjectReference.disableCollection() because of Patches.IBM_JDK_DISABLE_COLLECTION_BUG - Messages.showWarningDialog(tree, DebuggerBundle.message("evaluation.error.array.collected") + "\n"+ DebuggerBundle.message("warning.recalculate"), DebuggerBundle.message("title.set.value")); - node.getParent().calcValue(); + Messages.showWarningDialog(myJavaValue.getProject(), DebuggerBundle.message("evaluation.error.array.collected") + "\n"+ DebuggerBundle.message("warning.recalculate"), DebuggerBundle.message("title.set.value")); + //node.getParent().calcValue(); return; } final ArrayType arrType = (ArrayType)array.referenceType(); - askAndSet(node, debuggerContext, new SetValueRunnable() { - public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + set(expression, callback, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) + throws ClassNotLoadedException, InvalidTypeException, EvaluateException { array.setValue(elementDescriptor.getIndex(), preprocessValue(evaluationContext, newValue, arrType.componentType())); update(debuggerContext); } public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvalidTypeException, - EvaluateException { + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, arrType.classLoader()); } }); @@ -193,18 +200,19 @@ public class SetValueAction extends DebuggerAction { else if (descriptor instanceof EvaluationDescriptor) { final EvaluationDescriptor evaluationDescriptor = (EvaluationDescriptor)descriptor; if (evaluationDescriptor.canSetValue()) { - askAndSet(node, debuggerContext, new SetValueRunnable() { - public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, InvalidTypeException, EvaluateException { + set(expression, callback, debuggerContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) + throws ClassNotLoadedException, InvalidTypeException, EvaluateException { final Modifier modifier = evaluationDescriptor.getModifier(); modifier.setValue(preprocessValue(evaluationContext, newValue, modifier.getExpectedType())); update(debuggerContext); } public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - IncompatibleThreadStateException, - InvalidTypeException, - EvaluateException { + ClassNotLoadedException, + IncompatibleThreadStateException, + InvalidTypeException, + EvaluateException { return evaluationContext.getDebugProcess().loadClass(evaluationContext, className, evaluationContext.getClassLoader()); } @@ -300,8 +308,9 @@ public class SetValueAction extends DebuggerAction { } } - private void askAndSet(final DebuggerTreeNodeImpl node, final DebuggerContextImpl debuggerContext, final SetValueRunnable setValueRunnable) { - ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, debuggerContext.getProject()); + private void set(@NotNull final String expression, final XModificationCallback callback, final DebuggerContextImpl debuggerContext, final SetValueRunnable setValueRunnable) { + final ProgressWindowWithNotification progressWindow = new ProgressWindowWithNotification(true, debuggerContext.getProject()); + final EvaluationContextImpl evaluationContext = myJavaValue.getEvaluationContext(); SuspendContextCommandImpl askSetAction = new DebuggerContextCommandImpl(debuggerContext) { public Priority getPriority() { @@ -309,27 +318,62 @@ public class SetValueAction extends DebuggerAction { } public void threadAction() { - final NodeDescriptorImpl descriptor = node.getDescriptor(); - String initialString = ""; - if (descriptor instanceof ValueDescriptorImpl) { - Value currentValue = ((ValueDescriptorImpl) descriptor).getValue(); - if (currentValue instanceof StringReference) { - initialString = DebuggerUtilsEx.getValueOrErrorAsString(debuggerContext.createEvaluationContext(), currentValue); - initialString = initialString == null ? "" : "\"" + DebuggerUtilsEx.translateStringValue(initialString) + "\""; - } - else if (currentValue instanceof PrimitiveValue) { - ValueLabelRenderer renderer = ((ValueDescriptorImpl) descriptor).getRenderer(debuggerContext.getDebugProcess()); - initialString = getDisplayableString((PrimitiveValue) currentValue, renderer instanceof NodeRenderer && HexRenderer.UNIQUE_ID.equals(renderer.getUniqueId())); - } + ExpressionEvaluator evaluator = null; + try { + evaluator = DebuggerInvocationUtil + .commitAndRunReadAction(evaluationContext.getProject(), new com.intellij.debugger.EvaluatingComputable() { + public ExpressionEvaluator compute() throws EvaluateException { + return EvaluatorBuilderImpl + .build(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, expression), ContextUtil.getContextElement(evaluationContext), + ContextUtil.getSourcePosition(evaluationContext)); + } + }); - final String initialString1 = initialString; - final Project project = debuggerContext.getProject(); - DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() { - public void run() { - showEditor(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, initialString1), node, debuggerContext, setValueRunnable); + + setValue(expression, evaluator, evaluationContext, new SetValueRunnable() { + public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, + InvalidTypeException, + EvaluateException, + IncompatibleThreadStateException { + if (!progressWindow.isCanceled()) { + setValueRunnable.setValue(evaluationContext, newValue); + //node.calcValue(); + } + } + + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws + InvocationException, + ClassNotLoadedException, + EvaluateException, + IncompatibleThreadStateException, + InvalidTypeException { + return setValueRunnable.loadClass(evaluationContext, className); } }); + callback.valueModified(); + } catch (EvaluateException e) { + callback.errorOccurred(e.getMessage()); } + //String initialString = ""; + //if (descriptor instanceof ValueDescriptorImpl) { + // Value currentValue = ((ValueDescriptorImpl) descriptor).getValue(); + // if (currentValue instanceof StringReference) { + // initialString = DebuggerUtilsEx.getValueOrErrorAsString(debuggerContext.createEvaluationContext(), currentValue); + // initialString = initialString == null ? "" : "\"" + DebuggerUtilsEx.translateStringValue(initialString) + "\""; + // } + // else if (currentValue instanceof PrimitiveValue) { + // ValueLabelRenderer renderer = ((ValueDescriptorImpl) descriptor).getRenderer(debuggerContext.getDebugProcess()); + // initialString = getDisplayableString((PrimitiveValue) currentValue, renderer instanceof NodeRenderer && HexRenderer.UNIQUE_ID.equals(renderer.getUniqueId())); + // } + // + // final String initialString1 = initialString; + // final Project project = debuggerContext.getProject(); + // DebuggerInvocationUtil.swingInvokeLater(project, new Runnable() { + // public void run() { + // showEditor(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, initialString1), node, debuggerContext, setValueRunnable); + // } + // }); + //} } }; @@ -418,22 +462,23 @@ public class SetValueAction extends DebuggerAction { } }); - SetValueAction.setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() { + setValue(text.getText(), evaluator, evaluationContext, new SetValueRunnable() { public void setValue(EvaluationContextImpl evaluationContext, Value newValue) throws ClassNotLoadedException, - InvalidTypeException, - EvaluateException, - IncompatibleThreadStateException { - if(!progressWindow.isCanceled()) { + InvalidTypeException, + EvaluateException, + IncompatibleThreadStateException { + if (!progressWindow.isCanceled()) { setValueRunnable.setValue(evaluationContext, newValue); node.calcValue(); } } - public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws InvocationException, - ClassNotLoadedException, - EvaluateException, - IncompatibleThreadStateException, - InvalidTypeException { + public ReferenceType loadClass(EvaluationContextImpl evaluationContext, String className) throws + InvocationException, + ClassNotLoadedException, + EvaluateException, + IncompatibleThreadStateException, + InvalidTypeException { return setValueRunnable.loadClass(evaluationContext, className); } }); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java index 17379560e107..7b402a1b17f9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/JumpToObjectAction.java @@ -30,6 +30,7 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiClass; import com.sun.jdi.*; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -133,7 +134,7 @@ public class JumpToObjectAction extends DebuggerAction{ return null; } - private static class NavigateCommand extends SourcePositionCommand { + public static class NavigateCommand extends SourcePositionCommand { public NavigateCommand(final DebuggerContextImpl debuggerContext, final ValueDescriptor descriptor, final DebugProcessImpl debugProcess, final AnActionEvent e) { super(debuggerContext, descriptor, debugProcess, e); } @@ -195,7 +196,7 @@ public class JumpToObjectAction extends DebuggerAction{ protected abstract SourcePositionCommand createRetryCommand(); - protected abstract void doAction(SourcePosition sourcePosition); + protected abstract void doAction(@Nullable SourcePosition sourcePosition); private ReferenceType loadClass(final String className) { final EvaluationContextImpl eContext = myDebuggerContext.createEvaluationContext(); 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 7d15c05e0a4b..f5aa685c7994 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/PopFrameAction.java @@ -21,6 +21,7 @@ package com.intellij.debugger.actions; import com.intellij.debugger.DebuggerBundle; 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; @@ -30,9 +31,11 @@ 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.actionSystem.PlatformDataKeys; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.frame.XStackFrame; import com.sun.jdi.InvalidStackFrameException; import com.sun.jdi.NativeMethodException; import com.sun.jdi.VMDisconnectedException; @@ -78,6 +81,19 @@ public class PopFrameAction extends DebuggerAction { return null; } } + + Project project = e.getProject(); + if (project != null) { + XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); + if (session != null) { + XStackFrame frame = session.getCurrentStackFrame(); + if (frame instanceof JavaStackFrame) { + StackFrameProxyImpl proxy = ((JavaStackFrame)frame).getStackFrameProxy(); + return !proxy.isBottom() ? proxy : null; + } + } + } + DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); StackFrameProxyImpl frameProxy = debuggerContext.getFrameProxy(); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ShowLibraryFramesAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ShowLibraryFramesAction.java new file mode 100644 index 000000000000..972cfef48661 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ShowLibraryFramesAction.java @@ -0,0 +1,57 @@ +/* + * 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.actions; + +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.Presentation; +import com.intellij.openapi.actionSystem.ToggleAction; +import com.intellij.xdebugger.impl.XDebuggerUtilImpl; + +/** + * @author egor + */ +public class ShowLibraryFramesAction extends ToggleAction { + private volatile boolean myShouldShow; + private static final String ourTextWhenShowIsOn = "Hide Frames from Libraries"; + private static final String ourTextWhenShowIsOff = "Show All Frames"; + + public ShowLibraryFramesAction() { + super("", "", AllIcons.Debugger.Class_filter); + myShouldShow = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES; + } + + @Override + public void update(final AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + final boolean shouldShow = !(Boolean)presentation.getClientProperty(SELECTED_PROPERTY); + presentation.setText(shouldShow ? ourTextWhenShowIsOn : ourTextWhenShowIsOff); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return !myShouldShow; + } + + @Override + public void setSelected(AnActionEvent e, boolean enabled) { + myShouldShow = !enabled; + DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES = myShouldShow; + XDebuggerUtilImpl.rebuildAllSessionsViews(e.getProject()); + } +} \ No newline at end of file diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java index a4fe426088f7..c840854b10d5 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ThreadDumpAction.java @@ -28,7 +28,6 @@ import com.intellij.debugger.engine.events.DebuggerCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerSession; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; -import com.intellij.debugger.ui.DebuggerPanelsManager; import com.intellij.debugger.ui.DebuggerSessionTab; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -40,6 +39,7 @@ import com.intellij.openapi.project.Project; import com.intellij.unscramble.ThreadDumpParser; import com.intellij.unscramble.ThreadState; import com.intellij.util.SmartList; +import com.intellij.xdebugger.XDebugSession; import com.sun.jdi.*; import gnu.trove.TIntObjectHashMap; @@ -68,9 +68,9 @@ public class ThreadDumpAction extends AnAction implements AnAction.TransparentUp final List threads = buildThreadStates(vm); ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - final DebuggerSessionTab sessionTab = DebuggerPanelsManager.getInstance(project).getSessionTab(); - if (sessionTab != null) { - sessionTab.addThreadDump(threads); + XDebugSession xSession = session.getProcess().getXDebugSession(); + if (xSession != null) { + DebuggerSessionTab.addThreadDump(project, threads, xSession.getUI(), session); } } }, ModalityState.NON_MODAL); 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 d8e957295d21..bd8efab637ac 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewAsGroup.java @@ -16,16 +16,21 @@ package com.intellij.debugger.actions; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaValue; import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.settings.NodeRendererSettings; -import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; +import com.intellij.debugger.ui.tree.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; import org.jetbrains.annotations.Nullable; @@ -55,15 +60,14 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { } public boolean isSelected(AnActionEvent e) { - DebuggerTreeNodeImpl[] nodes = DebuggerAction.getSelectedNodes(e.getDataContext()); - if (nodes == null) { + XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); + if (node == null) { return false; } - for (DebuggerTreeNodeImpl node : nodes) { - if (node.getDescriptor() instanceof ValueDescriptorImpl) { - if (((ValueDescriptorImpl)node.getDescriptor()).getLastRenderer() != myNodeRenderer) { - return false; - } + XValue container = node.getValueContainer(); + if (container instanceof JavaValue) { + if (((ValueDescriptorImpl)((JavaValue)container).getDescriptor()).getLastRenderer() != myNodeRenderer) { + return false; } } return true; @@ -71,23 +75,24 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { public void setSelected(final AnActionEvent e, final boolean state) { final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(e.getDataContext()); - final DebuggerTreeNodeImpl[] nodes = DebuggerAction.getSelectedNodes(e.getDataContext()); + final XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(e.getDataContext()); - LOG.assertTrue(debuggerContext != null && nodes != null); + LOG.assertTrue(debuggerContext != null && node != null); debuggerContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) { public void threadAction() { - for (final DebuggerTreeNodeImpl node : nodes) { - if (node.getDescriptor() instanceof ValueDescriptorImpl) { - final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)node.getDescriptor(); - if (state) { - valueDescriptor.setRenderer(myNodeRenderer); - node.calcRepresentation(); - } + XValue container = node.getValueContainer(); + if (container instanceof JavaValue) { + final ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)((JavaValue)container).getDescriptor(); + if (state) { + valueDescriptor.setRenderer(myNodeRenderer); + valueDescriptor.updateRepresentation(debuggerContext.createEvaluationContext(), DescriptorLabelListener.DUMMY_LISTENER); + container.computePresentation(node, XValuePlace.TREE); } } } - }); + } + ); } } @@ -96,7 +101,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { return myChildren; } - private static AnAction [] calcChildren(DebuggerTreeNodeImpl[] nodes) { + private static AnAction [] calcChildren(NodeDescriptorImpl[] descriptors) { List renderers = new ArrayList(); List allRenderers = NodeRendererSettings.getInstance().getAllRenderers(); @@ -106,8 +111,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { for (NodeRenderer nodeRenderer : allRenderers) { boolean allApp = true; - for (DebuggerTreeNodeImpl node : nodes) { - NodeDescriptorImpl descriptor = node.getDescriptor(); + for (NodeDescriptorImpl descriptor : descriptors) { if (descriptor instanceof ValueDescriptorImpl) { anyValueDescriptor = true; ValueDescriptorImpl valueDescriptor = (ValueDescriptorImpl)descriptor; @@ -155,7 +159,15 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { } final DebuggerContextImpl debuggerContext = DebuggerAction.getDebuggerContext(event.getDataContext()); - final DebuggerTreeNodeImpl[] selectedNodes = DebuggerAction.getSelectedNodes(event.getDataContext()); + XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(event.getDataContext()); + if (node == null) { + return; + } + final XValue container = node.getValueContainer(); + if (!(container instanceof JavaValue)) { + event.getPresentation().setEnabled(false); + return; + } final DebugProcessImpl process = debuggerContext.getDebugProcess(); if (process == null) { @@ -165,7 +177,7 @@ public class ViewAsGroup extends ActionGroup implements DumbAware { process.getManagerThread().schedule(new DebuggerContextCommandImpl(debuggerContext) { public void threadAction() { - myChildren = calcChildren(selectedNodes); + myChildren = calcChildren(new NodeDescriptorImpl[]{((JavaValue)container).getDescriptor()}); DebuggerAction.enableAction(event, myChildren.length > 0); } }); diff --git a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java index 52cc1b1441f8..45e2cef4b883 100644 --- a/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java +++ b/java/debugger/impl/src/com/intellij/debugger/actions/ViewTextAction.java @@ -15,14 +15,11 @@ */ package com.intellij.debugger.actions; -import com.intellij.debugger.impl.DebuggerContextImpl; -import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; -import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; -import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.ui.EditorTextField; import com.intellij.xdebugger.impl.ui.TextViewer; +import com.intellij.xdebugger.impl.ui.tree.actions.XFetchValueActionBase; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -31,17 +28,25 @@ import java.awt.*; /* * @author Jeka */ -public class ViewTextAction extends BaseValueAction { +public class ViewTextAction extends XFetchValueActionBase { @Override - protected void processText(final Project project, final String text, DebuggerTreeNodeImpl node, DebuggerContextImpl debuggerContext) { - final NodeDescriptorImpl descriptor = node.getDescriptor(); - final String labelText = descriptor instanceof ValueDescriptorImpl? ((ValueDescriptorImpl)descriptor).getValueLabel() : null; + protected void handle(Project project, String value) { final MyDialog dialog = new MyDialog(project); - dialog.setTitle(labelText != null? "View Text for: " + labelText : "View Text"); - dialog.setText(text); + dialog.setTitle("View Text"); + dialog.setText(value); dialog.show(); } + //@Override + //protected void processText(final Project project, final String text, DebuggerTreeNodeImpl node, DebuggerContextImpl debuggerContext) { + // final NodeDescriptorImpl descriptor = node.getDescriptor(); + // final String labelText = descriptor instanceof ValueDescriptorImpl? ((ValueDescriptorImpl)descriptor).getValueLabel() : null; + // final MyDialog dialog = new MyDialog(project); + // dialog.setTitle(labelText != null? "View Text for: " + labelText : "View Text"); + // dialog.setText(text); + // dialog.show(); + //} + private static class MyDialog extends DialogWrapper { private final EditorTextField myTextViewer; diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java index 4ad9b0004266..7467f997ffde 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/ContextUtil.java @@ -37,7 +37,7 @@ public class ContextUtil { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.impl.PositionUtil"); @Nullable - public static SourcePosition getSourcePosition(final StackFrameContext context) { + public static SourcePosition getSourcePosition(@Nullable final StackFrameContext context) { if (context == null) { return null; } 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 d924822bf9ef..16d274166517 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java @@ -73,6 +73,8 @@ import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.concurrency.Semaphore; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.HashMap; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; import com.sun.jdi.*; import com.sun.jdi.connect.*; import com.sun.jdi.request.EventRequest; @@ -171,6 +173,10 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb final DebuggerSession session = mySession; if (session != null && session.isAttached()) { session.refresh(true); + XDebugSession xDebugSession = getXDebugSession(); + if (xDebugSession != null) { + xDebugSession.rebuildViews(); + } } } }); @@ -1531,7 +1537,7 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb public ResumeCommand(SuspendContextImpl suspendContext) { super(suspendContext); - final ThreadReferenceProxyImpl contextThread = mySession.getContextManager().getContext().getThreadProxy(); + final ThreadReferenceProxyImpl contextThread = getDebuggerContext().getThreadProxy(); myContextThread = contextThread != null ? contextThread : (suspendContext != null? suspendContext.getThread() : null); } @@ -1969,9 +1975,23 @@ public abstract class DebugProcessImpl extends UserDataHolderBase implements Deb } } + public DebuggerContextImpl getDebuggerContext() { + return mySession.getContextManager().getContext(); + } + + @Nullable + public XDebugSession getXDebugSession() { + return XDebuggerManager.getInstance(myProject).getDebugSession(getExecutionResult().getExecutionConsole()); + } + + @Nullable + public JavaDebugProcess getXdebugProcess() { + XDebugSession session = getXDebugSession(); + return session != null ? (JavaDebugProcess)session.getDebugProcess() : null; + } public boolean areBreakpointsMuted() { - return myBreakpointsMuted.get(); + XDebugSession session = getXDebugSession(); + return session != null && session.areBreakpointsMuted(); } } - diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java new file mode 100644 index 000000000000..3496894177d8 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandler.java @@ -0,0 +1,98 @@ +/* + * 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; + +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.ui.breakpoints.*; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointHandler; +import com.intellij.xdebugger.breakpoints.XBreakpointType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author egor + */ +public class JavaBreakpointHandler extends XBreakpointHandler { + protected final DebugProcessImpl myProcess; + + public JavaBreakpointHandler(@NotNull Class> breakpointTypeClass, DebugProcessImpl process) { + super(breakpointTypeClass); + myProcess = process; + } + + @Nullable + protected Breakpoint createJavaBreakpoint(@NotNull XBreakpoint xBreakpoint) { + return BreakpointManager.getJavaBreakpoint(xBreakpoint); + } + + @Override + public void registerBreakpoint(@NotNull XBreakpoint breakpoint) { + final Breakpoint javaBreakpoint = createJavaBreakpoint(breakpoint); + if (javaBreakpoint != null) { + BreakpointManager.addBreakpointInt(javaBreakpoint); + myProcess.getManagerThread().invoke(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + javaBreakpoint.createRequest(myProcess); + } + }); + } + } + + @Override + public void unregisterBreakpoint(@NotNull final XBreakpoint breakpoint, boolean temporary) { + final Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint); + if (javaBreakpoint != null) { + myProcess.getManagerThread().invoke(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + javaBreakpoint.delete(); + } + }); + } + } + + public static class JavaLineBreakpointHandler extends JavaBreakpointHandler { + public JavaLineBreakpointHandler(DebugProcessImpl process) { + super(JavaLineBreakpointType.class, process); + } + } + + public static class JavaExceptionBreakpointHandler extends JavaBreakpointHandler { + public JavaExceptionBreakpointHandler(DebugProcessImpl process) { + super(JavaExceptionBreakpointType.class, process); + } + } + + public static class JavaMethodBreakpointHandler extends JavaBreakpointHandler { + public JavaMethodBreakpointHandler(DebugProcessImpl process) { + super(JavaMethodBreakpointType.class, process); + } + } + + public static class JavaWildcardBreakpointHandler extends JavaBreakpointHandler { + public JavaWildcardBreakpointHandler(DebugProcessImpl process) { + super(JavaWildcardMethodBreakpointType.class, process); + } + } + + public static class JavaFieldBreakpointHandler extends JavaBreakpointHandler { + public JavaFieldBreakpointHandler(DebugProcessImpl process) { + super(JavaFieldBreakpointType.class, process); + } + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandlerFactory.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandlerFactory.java new file mode 100644 index 000000000000..cee4786fb29d --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaBreakpointHandlerFactory.java @@ -0,0 +1,27 @@ +/* + * 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; + +import com.intellij.openapi.extensions.ExtensionPointName; + +/** +* @author egor +*/ +public interface JavaBreakpointHandlerFactory { + ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.debugger.javaBreakpointHandlerFactory"); + + JavaBreakpointHandler createHandler(DebugProcessImpl process); +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java new file mode 100644 index 000000000000..380c2fe4edef --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebugProcess.java @@ -0,0 +1,400 @@ +/* + * 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; + +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.impl.DebuggerContextUtil; +import com.intellij.debugger.impl.DebuggerSession; +import com.intellij.debugger.impl.DebuggerStateManager; +import com.intellij.debugger.impl.DebuggerUtilsEx; +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.RunnerLayoutUi; +import com.intellij.execution.ui.layout.PlaceInGrid; +import com.intellij.icons.AllIcons; +import com.intellij.idea.ActionsBundle; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Disposer; +import com.intellij.openapi.util.Pair; +import com.intellij.ui.content.Content; +import com.intellij.ui.content.ContentManagerAdapter; +import com.intellij.ui.content.ContentManagerEvent; +import com.intellij.xdebugger.*; +import com.intellij.xdebugger.breakpoints.XBreakpoint; +import com.intellij.xdebugger.breakpoints.XBreakpointHandler; +import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.frame.XValueMarkerProvider; +import com.intellij.xdebugger.impl.XDebuggerUtilImpl; +import com.intellij.xdebugger.impl.actions.XDebuggerActions; +import com.intellij.xdebugger.ui.XDebugTabLayouter; +import com.sun.jdi.event.Event; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.java.debugger.JavaDebuggerEditorsProvider; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author egor + */ +public class JavaDebugProcess extends XDebugProcess { + private final DebuggerSession myJavaSession; + private final JavaDebuggerEditorsProvider myEditorsProvider; + private final XBreakpointHandler[] myBreakpointHandlers; + private final NodeManagerImpl myNodeManager; + + public JavaDebugProcess(@NotNull final XDebugSession session, final DebuggerSession javaSession) { + super(session); + myJavaSession = javaSession; + myEditorsProvider = new JavaDebuggerEditorsProvider(); + DebugProcessImpl process = javaSession.getProcess(); + + List handlers = new ArrayList(); + handlers.add(new JavaBreakpointHandler.JavaLineBreakpointHandler(process)); + handlers.add(new JavaBreakpointHandler.JavaExceptionBreakpointHandler(process)); + handlers.add(new JavaBreakpointHandler.JavaFieldBreakpointHandler(process)); + handlers.add(new JavaBreakpointHandler.JavaMethodBreakpointHandler(process)); + handlers.add(new JavaBreakpointHandler.JavaWildcardBreakpointHandler(process)); + + for (JavaBreakpointHandlerFactory factory : Extensions.getExtensions(JavaBreakpointHandlerFactory.EP_NAME)) { + handlers.add(factory.createHandler(process)); + } + + myBreakpointHandlers = handlers.toArray(new XBreakpointHandler[handlers.size()]); + + process.addDebugProcessListener(new DebugProcessAdapter() { + @Override + public void paused(final SuspendContext suspendContext) { + SuspendContextImpl context = (SuspendContextImpl)suspendContext; + context.initExecutionStacks(); + + List> descriptors = DebuggerUtilsEx.getEventDescriptors(context); + if (!descriptors.isEmpty()) { + Breakpoint breakpoint = descriptors.get(0).getFirst(); + XBreakpoint xBreakpoint = breakpoint.getXBreakpoint(); + if (xBreakpoint != null) { + getSession().breakpointReached(xBreakpoint, null, context); + return; + } + } + getSession().positionReached(context); + } + }); + + myNodeManager = new NodeManagerImpl(session.getProject(), null) { + @Override + public DebuggerTreeNodeImpl createNode(final NodeDescriptor descriptor, EvaluationContext evaluationContext) { + ((NodeDescriptorImpl)descriptor).setContext((EvaluationContextImpl)evaluationContext); + final DebuggerTreeNodeImpl node = new DebuggerTreeNodeImpl(null, descriptor); + ((NodeDescriptorImpl)descriptor).updateRepresentation((EvaluationContextImpl)evaluationContext, DescriptorLabelListener.DUMMY_LISTENER); + return node; + } + + @Override + public DebuggerTreeNodeImpl createMessageNode(MessageDescriptor descriptor) { + return new DebuggerTreeNodeImpl(null, descriptor); + } + }; + 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; + } + }); + } + + @Override + public void stackFrameChanged() { + XStackFrame frame = session.getCurrentStackFrame(); + if (frame instanceof JavaStackFrame) { + DebuggerContextUtil.setStackFrame(javaSession.getContextManager(), ((JavaStackFrame)frame).getStackFrameProxy()); + } + } + }); + } + + private DebuggerStateManager getDebuggerStateManager() { + return myJavaSession.getContextManager(); + } + + public DebuggerSession getDebuggerSession() { + return myJavaSession; + } + + @NotNull + @Override + public XDebuggerEditorsProvider getEditorsProvider() { + return myEditorsProvider; + } + + @Override + public void startStepOver() { + myJavaSession.stepOver(false); + } + + @Override + public void startStepInto() { + myJavaSession.stepInto(false, null); + } + + @Override + public void startForceStepInto() { + myJavaSession.stepInto(true, null); + } + + @Override + public void startStepOut() { + myJavaSession.stepOut(); + } + + @Override + public void stop() { + myJavaSession.getProcess().dispose(); + } + + @Override + public void startPausing() { + myJavaSession.pause(); + } + + @Override + public void resume() { + myJavaSession.resume(); + } + + @Override + public void runToPosition(@NotNull XSourcePosition position) { + Document document = FileDocumentManager.getInstance().getDocument(position.getFile()); + myJavaSession.runToCursor(document, position.getLine(), false); + } + + @NotNull + @Override + public XBreakpointHandler[] getBreakpointHandlers() { + return myBreakpointHandlers; + } + + @Override + public boolean checkCanInitBreakpoints() { + return false; + } + + @Nullable + @Override + protected ProcessHandler doGetProcessHandler() { + return myJavaSession.getProcess().getExecutionResult().getProcessHandler(); + } + + @NotNull + @Override + public ExecutionConsole createConsole() { + return myJavaSession.getProcess().getExecutionResult().getExecutionConsole(); + } + + @NotNull + @Override + public XDebugTabLayouter createTabLayouter() { + return new XDebugTabLayouter() { + @Override + public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) { + final ThreadsPanel panel = new ThreadsPanel(myJavaSession.getProject(), getDebuggerStateManager()); + final Content threadsContent = ui.createContent( + DebuggerContentInfo.THREADS_CONTENT, panel, XDebuggerBundle.message("debugger.session.tab.threads.title"), + AllIcons.Debugger.Threads, null); + Disposer.register(threadsContent, panel); + threadsContent.setCloseable(false); + ui.addContent(threadsContent, 0, PlaceInGrid.left, true); + ui.addListener(new ContentManagerAdapter() { + @Override + public void selectionChanged(ContentManagerEvent event) { + if (event.getContent() == threadsContent) { + if (threadsContent.isSelected()) { + panel.setUpdateEnabled(true); + if (panel.isRefreshNeeded()) { + panel.rebuildIfVisible(DebuggerSession.EVENT_CONTEXT); + } + } + else { + panel.setUpdateEnabled(false); + } + } + } + }, threadsContent); + } + }; + } + + @Override + public void registerAdditionalActions(@NotNull DefaultActionGroup leftToolbar, @NotNull DefaultActionGroup topToolbar) { + 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); + + final DefaultActionGroup settings = new DefaultActionGroup("DebuggerSettings", true) { + @Override + public void update(AnActionEvent e) { + e.getPresentation().setText(ActionsBundle.message("group.XDebugger.settings.text")); + e.getPresentation().setIcon(AllIcons.General.SecondaryGroup); + } + + @Override + public boolean isDumbAware() { + return true; + } + }; + settings.add(new WatchLastMethodReturnValueAction()); + settings.add(new AutoVarsSwitchAction()); + settings.add(new UnmuteOnStopAction()); + settings.addSeparator(); + addActionToGroup(settings, XDebuggerActions.AUTO_TOOLTIP); + + leftToolbar.add(settings, new Constraints(Anchor.AFTER, "Runner.Layout")); + } + + private static class AutoVarsSwitchAction extends ToggleAction { + private volatile boolean myAutoModeEnabled; + + public AutoVarsSwitchAction() { + super("", "", AllIcons.Debugger.AutoVariablesMode); + myAutoModeEnabled = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE; + } + + @Override + public void update(final AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + final boolean autoModeEnabled = (Boolean)presentation.getClientProperty(SELECTED_PROPERTY); + presentation.setText(autoModeEnabled ? "All-Variables Mode" : "Auto-Variables Mode"); + } + + @Override + public boolean isSelected(AnActionEvent e) { + return myAutoModeEnabled; + } + + @Override + public void setSelected(AnActionEvent e, boolean enabled) { + myAutoModeEnabled = enabled; + DebuggerSettings.getInstance().AUTO_VARIABLES_MODE = enabled; + XDebuggerUtilImpl.rebuildAllSessionsViews(e.getProject()); + } + } + + private static class WatchLastMethodReturnValueAction extends ToggleAction { + private volatile boolean myWatchesReturnValues; + private final String myTextEnable; + private final String myTextUnavailable; + private final String myMyTextDisable; + + public WatchLastMethodReturnValueAction() { + super("", DebuggerBundle.message("action.watch.method.return.value.description"), null); + myWatchesReturnValues = DebuggerSettings.getInstance().WATCH_RETURN_VALUES; + myTextEnable = DebuggerBundle.message("action.watches.method.return.value.enable"); + myMyTextDisable = DebuggerBundle.message("action.watches.method.return.value.disable"); + myTextUnavailable = DebuggerBundle.message("action.watches.method.return.value.unavailable.reason"); + } + + @Override + public void update(final AnActionEvent e) { + super.update(e); + final Presentation presentation = e.getPresentation(); + final boolean watchValues = (Boolean)presentation.getClientProperty(SELECTED_PROPERTY); + DebugProcessImpl process = getCurrentDebugProcess(e.getProject()); + final String actionText = watchValues ? myMyTextDisable : myTextEnable; + if (process == null || process.canGetMethodReturnValue()) { + presentation.setEnabled(true); + presentation.setText(actionText); + } + else { + presentation.setEnabled(false); + presentation.setText(myTextUnavailable); + } + } + + @Override + public boolean isSelected(AnActionEvent e) { + return myWatchesReturnValues; + } + + @Override + public void setSelected(AnActionEvent e, boolean watch) { + myWatchesReturnValues = watch; + DebuggerSettings.getInstance().WATCH_RETURN_VALUES = watch; + DebugProcessImpl process = getCurrentDebugProcess(e.getProject()); + if (process != null) { + process.setWatchMethodReturnValuesEnabled(watch); + } + } + } + + @Nullable + private static DebugProcessImpl getCurrentDebugProcess(@Nullable Project project) { + if (project != null) { + XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); + if (session != null) { + XDebugProcess process = session.getDebugProcess(); + if (process instanceof JavaDebugProcess) { + return ((JavaDebugProcess)process).getDebuggerSession().getProcess(); + } + } + } + return null; + } + + private static void addActionToGroup(final DefaultActionGroup group, final String actionId) { + AnAction action = ActionManager.getInstance().getAction(actionId); + if (action != null) group.add(action); + } + + public NodeManagerImpl getNodeManager() { + return myNodeManager; + } + + @Nullable + @Override + public XValueMarkerProvider createValueMarkerProvider() { + return new JavaValueMarker(); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java new file mode 100644 index 000000000000..539fbc94aab1 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaDebuggerEvaluator.java @@ -0,0 +1,114 @@ +/* + * 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; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.EditorTextProvider; +import com.intellij.debugger.ui.impl.watch.WatchItemDescriptor; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author egor + */ +public class JavaDebuggerEvaluator extends XDebuggerEvaluator { + private final DebugProcessImpl myDebugProcess; + private final JavaStackFrame myStackFrame; + + public JavaDebuggerEvaluator(DebugProcessImpl debugProcess, JavaStackFrame stackFrame) { + myDebugProcess = debugProcess; + myStackFrame = stackFrame; + } + + @Override + public void evaluate(@NotNull final String expression, + @NotNull final XEvaluationCallback callback, + @Nullable XSourcePosition expressionPosition) { + evaluate(XExpressionImpl.fromText(expression), callback, expressionPosition); + } + + @Override + public void evaluate(@NotNull final XExpression expression, + @NotNull final XEvaluationCallback callback, + @Nullable XSourcePosition expressionPosition) { + myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) { + @Override + public void threadAction() { + WatchItemDescriptor descriptor = new WatchItemDescriptor(myDebugProcess.getProject(), TextWithImportsImpl.fromXExpression( + expression)); + EvaluationContextImpl evalContext = myStackFrame.getFrameDebuggerContext().createEvaluationContext(); + if (evalContext == null) { + callback.errorOccurred("Context is not available"); + return; + } + descriptor.setContext(evalContext); + descriptor.updateRepresentation(evalContext, DescriptorLabelListener.DUMMY_LISTENER); + JavaDebugProcess process = myDebugProcess.getXdebugProcess(); + if (process != null) { + callback.evaluated(new JavaValue(descriptor, evalContext, process.getNodeManager())); + } + } + }); + } + + @Nullable + @Override + public TextRange getExpressionRangeAtOffset(final Project project, final Document document, final int offset, final boolean sideEffectsAllowed) { + final Ref currentRange = Ref.create(null); + PsiDocumentManager.getInstance(project).commitAndRunReadAction(new Runnable() { + @Override + public void run() { + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (psiFile == null) { + return; + } + PsiElement elementAtCursor = psiFile.findElementAt(offset); + if (elementAtCursor == null) { + return; + } + Pair pair = findExpression(elementAtCursor, sideEffectsAllowed); + if (pair != null) { + currentRange.set(pair.getSecond()); + } + } + }); + return currentRange.get(); + } + + @Nullable + private static Pair findExpression(PsiElement element, boolean allowMethodCalls) { + final EditorTextProvider textProvider = EditorTextProvider.EP.forLanguage(element.getLanguage()); + if (textProvider != null) { + return textProvider.findExpression(element, allowMethodCalls); + } + return null; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java new file mode 100644 index 000000000000..925c9d55170d --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java @@ -0,0 +1,140 @@ +/* + * 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; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.StackFrameProxyImpl; +import com.intellij.debugger.jdi.ThreadGroupReferenceProxyImpl; +import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.ui.impl.watch.MethodsTracker; +import com.intellij.icons.AllIcons; +import com.intellij.xdebugger.frame.XExecutionStack; +import com.sun.jdi.ThreadReference; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * @author egor + */ +public class JavaExecutionStack extends XExecutionStack { + private final ThreadReferenceProxyImpl myThreadProxy; + private final DebugProcessImpl myDebugProcess; + private volatile JavaStackFrame myTopFrame; + private boolean myTopFrameReady = false; + private final MethodsTracker myTracker = new MethodsTracker(); + + public JavaExecutionStack(@NotNull ThreadReferenceProxyImpl threadProxy, @NotNull DebugProcessImpl debugProcess, boolean current) { + super(calcRepresentation(threadProxy), current ? AllIcons.Debugger.ThreadCurrent : AllIcons.Debugger.ThreadSuspended); + myThreadProxy = threadProxy; + myDebugProcess = debugProcess; + if (current) { + myTopFrame = calcTopFrame(); + } + } + + @NotNull + public ThreadReferenceProxyImpl getThreadProxy() { + return myThreadProxy; + } + + private JavaStackFrame calcTopFrame() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + try { + StackFrameProxyImpl frame = myThreadProxy.frame(0); + if (frame != null) { + return new JavaStackFrame(frame, myDebugProcess, myTracker); + } + } + catch (EvaluateException e) { + e.printStackTrace(); + } + finally { + myTopFrameReady = true; + } + return null; + } + + @Nullable + @Override + public JavaStackFrame getTopFrame() { + if (!myTopFrameReady) { + //TODO: remove sync calculation + myDebugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + myTopFrame = calcTopFrame(); + } + }); + } + return myTopFrame; + } + + @Override + public void computeStackFrames(final int firstFrameIndex, final XStackFrameContainer container) { + myDebugProcess.getManagerThread().schedule(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + boolean showLibraryStackframes = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES; + List frames = new ArrayList(); + if (!myThreadProxy.isCollected() && myDebugProcess.getSuspendManager().isSuspended(myThreadProxy)) { + int status = myThreadProxy.status(); + if (!(status == ThreadReference.THREAD_STATUS_UNKNOWN) && + !(status == ThreadReference.THREAD_STATUS_NOT_STARTED) && + !(status == ThreadReference.THREAD_STATUS_ZOMBIE)) { + try { + int framesToSkip = firstFrameIndex; + for (StackFrameProxyImpl stackFrame : myThreadProxy.frames()) { + JavaStackFrame frame = new JavaStackFrame(stackFrame, myDebugProcess, myTracker); + if (showLibraryStackframes || (!frame.getDescriptor().isSynthetic() && !frame.getDescriptor().isInLibraryContent())) { + if (framesToSkip > 0) { + framesToSkip--; + continue; + } + frames.add(frame); + } + } + } + catch (EvaluateException e) { + container.errorOccurred(e.getMessage()); + return; + } + } + } + container.addStackFrames(frames, true); + } + }); + } + + private static String calcRepresentation(ThreadReferenceProxyImpl thread) { + DebuggerManagerThreadImpl.assertIsManagerThread(); + String name = thread.name(); + ThreadGroupReferenceProxyImpl gr = thread.threadGroupProxy(); + final String grname = (gr != null)? gr.name() : null; + final String threadStatusText = DebuggerUtilsEx.getThreadStatusText(thread.status()); + //noinspection HardCodedStringLiteral + if (grname != null && !"SYSTEM".equalsIgnoreCase(grname)) { + return DebuggerBundle.message("label.thread.node.in.group", name, thread.uniqueID(), threadStatusText, grname); + } + return DebuggerBundle.message("label.thread.node", name, thread.uniqueID(), threadStatusText); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaFramesListRenderer.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaFramesListRenderer.java new file mode 100644 index 000000000000..ed2bb7499e90 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaFramesListRenderer.java @@ -0,0 +1,115 @@ +/* + * 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; + +import com.intellij.debugger.ui.impl.watch.StackFrameDescriptorImpl; +import com.intellij.openapi.editor.colors.EditorColorsManager; +import com.intellij.openapi.editor.colors.EditorColorsScheme; +import com.intellij.openapi.util.Comparing; +import com.intellij.ui.ColoredTextContainer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; +import com.sun.jdi.Method; +import org.jetbrains.annotations.NotNull; + +// Copied from FramesListRenderer +class JavaFramesListRenderer /*extends ColoredListCellRenderer*/ { + private final EditorColorsScheme myColorScheme; + + public JavaFramesListRenderer() { + myColorScheme = EditorColorsManager.getInstance().getGlobalScheme(); + } + + public void customizePresentation(StackFrameDescriptorImpl descriptor, @NotNull ColoredTextContainer component) { + component.setIcon(descriptor.getIcon()); + //final Object selectedValue = list.getSelectedValue(); + //final boolean shouldHighlightAsRecursive = (selectedValue instanceof StackFrameDescriptorImpl) && + // isOccurrenceOfSelectedFrame((StackFrameDescriptorImpl)selectedValue, descriptor); + + final ValueMarkup markup = descriptor.getValueMarkup(); + if (markup != null) { + component.append("["+ markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor())); + } + + boolean needSeparator = false; + //if (index > 0) { + // final int currentFrameIndex = descriptor.getUiIndex(); + // final Object elementAt = list.getModel().getElementAt(index - 1); + // if (elementAt instanceof StackFrameDescriptorImpl) { + // StackFrameDescriptorImpl previousDescriptor = (StackFrameDescriptorImpl)elementAt; + // final int previousFrameIndex = previousDescriptor.getUiIndex(); + // needSeparator = (currentFrameIndex - previousFrameIndex != 1); + // } + //} + + //if (selected) { + // setBackground(UIUtil.getListSelectionBackground()); + //} + //else { + // Color bg = descriptor.getBackgroundColor(); + // if (bg == null) bg = UIUtil.getListBackground(); + // if (shouldHighlightAsRecursive) bg = myColorScheme.getColor(DebuggerColors.RECURSIVE_CALL_ATTRIBUTES); + // setBackground(bg); + //} + // + //if (needSeparator) { + // final MatteBorder border = BorderFactory.createMatteBorder(1, 0, 0, 0, JBColor.GRAY); + // setBorder(border); + //} + //else { + // setBorder(null); + //} + + final String label = descriptor.getLabel(); + final int openingBrace = label.indexOf("{"); + final int closingBrace = (openingBrace < 0) ? -1 : label.indexOf("}"); + final SimpleTextAttributes attributes = getAttributes(descriptor); + if (openingBrace < 0 || closingBrace < 0) { + component.append(label, attributes); + } + else { + component.append(label.substring(0, openingBrace - 1), attributes); + component.append(" (" + label.substring(openingBrace + 1, closingBrace) + ")", SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES); + + component.append(label.substring(closingBrace + 1, label.length()), attributes); + //if (shouldHighlightAsRecursive && descriptor.isRecursiveCall()) { + // component.append(" [" + descriptor.getOccurrenceIndex() + "]", SimpleTextAttributes.REGULAR_BOLD_ATTRIBUTES); + //} + } + } + + private static boolean isOccurrenceOfSelectedFrame(final StackFrameDescriptorImpl selectedDescriptor, StackFrameDescriptorImpl descriptor) { + final Method currentMethod = descriptor.getMethod(); + if (currentMethod != null) { + if (selectedDescriptor != null) { + final Method selectedMethod = selectedDescriptor.getMethod(); + if (selectedMethod != null) { + if (Comparing.equal(selectedMethod, currentMethod)) { + return true; + } + } + } + } + return false; + } + + private static SimpleTextAttributes getAttributes(final StackFrameDescriptorImpl descriptor) { + if (descriptor.isSynthetic() || descriptor.isInLibraryContent()) { + return SimpleTextAttributes.GRAYED_ATTRIBUTES; + } + return SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java new file mode 100644 index 000000000000..1310a75c5e79 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStackFrame.java @@ -0,0 +1,358 @@ +/* + * 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; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImports; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.jdi.*; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.settings.ViewsGeneralSettings; +import com.intellij.debugger.ui.breakpoints.Breakpoint; +import com.intellij.debugger.ui.impl.FrameVariablesTree; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.render.ClassRenderer; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.ui.ColoredTextContainer; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; +import com.intellij.xdebugger.frame.XCompositeNode; +import com.intellij.xdebugger.frame.XStackFrame; +import com.intellij.xdebugger.frame.XValueChildrenList; +import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; +import com.sun.jdi.*; +import com.sun.jdi.event.Event; +import com.sun.jdi.event.ExceptionEvent; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * @author egor + */ +public class JavaStackFrame extends XStackFrame { + private static final Logger LOG = Logger.getInstance(JavaStackFrame.class); + + private final DebugProcessImpl myDebugProcess; + private final XSourcePosition myXSourcePosition; + private final SourcePosition mySourcePosition; + private final NodeManagerImpl myNodeManager; + private final StackFrameDescriptorImpl myDescriptor; + private final JavaFramesListRenderer myRenderer = new JavaFramesListRenderer(); + private JavaDebuggerEvaluator myEvaluator = null; + + public JavaStackFrame(@NotNull StackFrameProxyImpl stackFrameProxy, @NotNull DebugProcessImpl debugProcess, MethodsTracker tracker) { + myDebugProcess = debugProcess; + Pair positions = calcSourcePosition(stackFrameProxy); + mySourcePosition = positions.getFirst(); + myXSourcePosition = positions.getSecond(); + myNodeManager = debugProcess.getXdebugProcess().getNodeManager(); + myDescriptor = new StackFrameDescriptorImpl(stackFrameProxy, tracker); + myDescriptor.setContext(null); + myDescriptor.updateRepresentation(null, DescriptorLabelListener.DUMMY_LISTENER); + } + + public StackFrameDescriptorImpl getDescriptor() { + return myDescriptor; + } + + private Pair calcSourcePosition(StackFrameProxyImpl stackFrameProxy) { + final CompoundPositionManager positionManager = myDebugProcess.getPositionManager(); + if (positionManager == null) { + // process already closed + return null; + } + Location location = null; + try { + location = stackFrameProxy.location(); + } + catch (Throwable e) { + LOG.info(e); + } + final Location loc = location; + return ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public Pair compute() { + SourcePosition position = positionManager.getSourcePosition(loc); + XSourcePosition xSourcePosition = position != null ? DebuggerUtilsEx.toXSourcePosition(position) : null; + return new Pair(position, xSourcePosition); + } + }); + } + + @Nullable + @Override + public XDebuggerEvaluator getEvaluator() { + if (myEvaluator == null) { + myEvaluator = new JavaDebuggerEvaluator(myDebugProcess, this); + } + return myEvaluator; + } + + @Nullable + @Override + public XSourcePosition getSourcePosition() { + return myXSourcePosition; + } + + @Override + public void customizePresentation(@NotNull ColoredTextContainer component) { + myRenderer.customizePresentation(myDescriptor, component); + } + + @Override + public void computeChildren(@NotNull final XCompositeNode node) { + XStackFrame xFrame = getDescriptor().getXStackFrame(); + if (xFrame != null) { + xFrame.computeChildren(node); + return; + } + myDebugProcess.getManagerThread().schedule(new DebuggerContextCommandImpl(myDebugProcess.getDebuggerContext()) { + @Override + public void threadAction() { + XValueChildrenList children = new XValueChildrenList(); + buildVariablesThreadAction(getFrameDebuggerContext(), children, node); + node.addChildren(children, true); + } + }); + } + + DebuggerContextImpl getFrameDebuggerContext() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + DebuggerContextImpl context = myDebugProcess.getDebuggerContext(); + if (context.getFrameProxy() != getStackFrameProxy()) { + context = DebuggerContextImpl.createDebuggerContext( + myDebugProcess.mySession, + context.getSuspendContext(), + getStackFrameProxy().threadProxy(), + getStackFrameProxy()); + context.setPositionCache(mySourcePosition); + context.initCaches(); + } + return context; + } + + // copied from DebuggerTree + private void buildVariablesThreadAction(DebuggerContextImpl debuggerContext, XValueChildrenList children, XCompositeNode node) { + try { + final StackFrameDescriptorImpl stackDescriptor = myDescriptor; + final StackFrameProxyImpl frame = getStackFrameProxy(); + + final EvaluationContextImpl evaluationContext = debuggerContext.createEvaluationContext(); + if (!debuggerContext.isEvaluationPossible()) { + node.setErrorMessage(MessageDescriptor.EVALUATION_NOT_POSSIBLE.getLabel()); + //myChildren.add(myNodeManager.createNode(MessageDescriptor.EVALUATION_NOT_POSSIBLE, evaluationContext)); + } + + final Location location = frame.location(); + LOG.assertTrue(location != null); + + final ObjectReference thisObjectReference = frame.thisObject(); + if (thisObjectReference != null) { + ValueDescriptorImpl thisDescriptor = myNodeManager.getThisDescriptor(stackDescriptor, thisObjectReference); + children.add(new JavaValue(thisDescriptor, evaluationContext, myNodeManager)); + } + else { + StaticDescriptorImpl staticDecriptor = myNodeManager.getStaticDescriptor(stackDescriptor, location.method().declaringType()); + if (staticDecriptor.isExpandable()) { + children.addTopGroup(new JavaStaticGroup(staticDecriptor, evaluationContext, myNodeManager)); + } + } + + // add last method return value if any + final Pair methodValuePair = debuggerContext.getDebugProcess().getLastExecutedMethod(); + if (methodValuePair != null) { + ValueDescriptorImpl returnValueDescriptor = myNodeManager.getMethodReturnValueDescriptor(stackDescriptor, methodValuePair.getFirst(), methodValuePair.getSecond()); + children.add(new JavaValue(returnValueDescriptor, evaluationContext, myNodeManager)); + } + // add context exceptions + for (Pair pair : DebuggerUtilsEx.getEventDescriptors(debuggerContext.getSuspendContext())) { + final Event debugEvent = pair.getSecond(); + if (debugEvent instanceof ExceptionEvent) { + final ObjectReference exception = ((ExceptionEvent)debugEvent).exception(); + if (exception != null) { + final ValueDescriptorImpl exceptionDescriptor = myNodeManager.getThrownExceptionObjectDescriptor(stackDescriptor, exception); + children.add(new JavaValue(exceptionDescriptor, evaluationContext, myNodeManager)); + } + } + } + + final ClassRenderer classRenderer = NodeRendererSettings.getInstance().getClassRenderer(); + if (classRenderer.SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) { + if (thisObjectReference != null && evaluationContext.getDebugProcess().getVirtualMachineProxy().canGetSyntheticAttribute()) { + final ReferenceType thisRefType = thisObjectReference.referenceType(); + if (thisRefType instanceof ClassType && thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only + final ClassType clsType = (ClassType)thisRefType; + final DebugProcessImpl debugProcess = debuggerContext.getDebugProcess(); + final VirtualMachineProxyImpl vm = debugProcess.getVirtualMachineProxy(); + for (Field field : clsType.fields()) { + if ((!vm.canGetSyntheticAttribute() || field.isSynthetic()) && StringUtil + .startsWith(field.name(), FieldDescriptorImpl.OUTER_LOCAL_VAR_FIELD_PREFIX)) { + final FieldDescriptorImpl fieldDescriptor = myNodeManager.getFieldDescriptor(stackDescriptor, thisObjectReference, field); + children.add(new JavaValue(fieldDescriptor, evaluationContext, myNodeManager)); + } + } + } + } + } + + try { + buildVariables(debuggerContext, evaluationContext, children, node); + //if (classRenderer.SORT_ASCENDING) { + // Collections.sort(myChildren, NodeManagerImpl.getNodeComparator()); + //} + } + catch (EvaluateException e) { + node.setErrorMessage(e.getMessage()); + //myChildren.add(myNodeManager.createMessageNode(new MessageDescriptor(e.getMessage()))); + } + } + catch (EvaluateException e) { + node.setErrorMessage(e.getMessage()); + //myChildren.clear(); + //myChildren.add(myNodeManager.createMessageNode(new MessageDescriptor(e.getMessage()))); + } + catch (InvalidStackFrameException e) { + LOG.info(e); + //myChildren.clear(); + //notifyCancelled(); + } + catch (InternalException e) { + if (e.errorCode() == 35) { + node.setErrorMessage(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage())); + //myChildren.add( + // myNodeManager.createMessageNode(new MessageDescriptor(DebuggerBundle.message("error.corrupt.debug.info", e.getMessage())))); + } + else { + throw e; + } + } + } + + // copied from FrameVariablesTree + private void buildVariables(DebuggerContextImpl debuggerContext, EvaluationContextImpl evaluationContext, XValueChildrenList children, XCompositeNode node) throws EvaluateException { + boolean myAutoWatchMode = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE; + if (evaluationContext == null) { + return; + } + final SourcePosition sourcePosition = debuggerContext.getSourcePosition(); + if (sourcePosition == null) { + return; + } + + try { + if (!ViewsGeneralSettings.getInstance().ENABLE_AUTO_EXPRESSIONS && !myAutoWatchMode) { + // optimization + superBuildVariables(evaluationContext, children); + } + else { + final Map visibleVariables = FrameVariablesTree.getVisibleVariables(getStackFrameProxy()); + final EvaluationContextImpl evalContext = evaluationContext; + final Pair, Set> usedVars = + ApplicationManager.getApplication().runReadAction(new Computable, Set>>() { + @Override + public Pair, Set> compute() { + return FrameVariablesTree.findReferencedVars(visibleVariables.keySet(), sourcePosition, evalContext); + } + }); + // add locals + if (myAutoWatchMode) { + for (String var : usedVars.first) { + final LocalVariableDescriptorImpl descriptor = myNodeManager.getLocalVariableDescriptor(null, visibleVariables.get(var)); + children.add(new JavaValue(descriptor, evaluationContext, myNodeManager)); + } + } + else { + superBuildVariables(evaluationContext, children); + } + // add expressions + final EvaluationContextImpl evalContextCopy = evaluationContext.createEvaluationContext(evaluationContext.getThisObject()); + evalContextCopy.setAutoLoadClasses(false); + for (TextWithImports text : usedVars.second) { + WatchItemDescriptor descriptor = myNodeManager.getWatchItemDescriptor(null, text, null); + children.add(new JavaValue(descriptor, evaluationContext, myNodeManager)); + } + } + } + catch (EvaluateException e) { + if (e.getCause() instanceof AbsentInformationException) { + final StackFrameProxyImpl frame = getStackFrameProxy(); + + final Collection argValues = frame.getArgumentValues(); + int index = 0; + for (Value argValue : argValues) { + final ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, index++, argValue, null); + children.add(new JavaValue(descriptor, evaluationContext, myNodeManager)); + } + node.setMessage(MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE.getLabel(), XDebuggerUIConstants.INFORMATION_MESSAGE_ICON, SimpleTextAttributes.REGULAR_ATTRIBUTES, null); + //myChildren.add(myNodeManager.createMessageNode(MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE)); + + // trying to collect values from variable slots + final List decompiled = FrameVariablesTree.collectVariablesFromBytecode(frame, argValues.size()); + if (!decompiled.isEmpty()) { + try { + final Map values = LocalVariablesUtil.fetchValues(frame.getStackFrame(), decompiled); + for (DecompiledLocalVariable var : decompiled) { + final Value value = values.get(var); + final ArgumentValueDescriptorImpl descriptor = myNodeManager.getArgumentValueDescriptor(null, var.getSlot(), value, var.getName()); + children.add(new JavaValue(descriptor, evaluationContext, myNodeManager)); + } + } + catch (Exception ex) { + LOG.info(ex); + } + } + } + else { + throw e; + } + } + } + + protected void superBuildVariables(final EvaluationContextImpl evaluationContext, XValueChildrenList children) throws EvaluateException { + final StackFrameProxyImpl frame = getStackFrameProxy(); + for (final LocalVariableProxyImpl local : frame.visibleVariables()) { + final LocalVariableDescriptorImpl descriptor = myNodeManager.getLocalVariableDescriptor(null, local); + children.add(new JavaValue(descriptor, evaluationContext, myNodeManager)); + } + } + + public StackFrameProxyImpl getStackFrameProxy() { + return myDescriptor.getFrameProxy(); + } + + @Nullable + @Override + public Object getEqualityObject() { + return getStackFrameProxy(); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java new file mode 100644 index 000000000000..e61e77d29595 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaStaticGroup.java @@ -0,0 +1,73 @@ +/* + * 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; + +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.xdebugger.frame.*; +import com.sun.jdi.Field; +import com.sun.jdi.ReferenceType; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +/** + * @author egor + */ +public class JavaStaticGroup extends XValueGroup implements NodeDescriptorProvider { + private final StaticDescriptorImpl myStaticDescriptor; + private final EvaluationContextImpl myEvaluationContext; + private final NodeManagerImpl myNodeManager; + + public JavaStaticGroup(StaticDescriptorImpl staticDescriptor, + EvaluationContextImpl evaluationContext, + NodeManagerImpl nodeManager) { + super(staticDescriptor.getName()); + myStaticDescriptor = staticDescriptor; + myEvaluationContext = evaluationContext; + myNodeManager = nodeManager; + } + + @Override + public NodeDescriptorImpl getDescriptor() { + return myStaticDescriptor; + } + + @Override + public void computeChildren(@NotNull final XCompositeNode node) { + myEvaluationContext.getDebugProcess().getManagerThread().schedule( + new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) { + @Override + public void contextAction() throws Exception { + final XValueChildrenList children = new XValueChildrenList(); + + final ReferenceType refType = myStaticDescriptor.getType(); + List fields = refType.allFields(); + for (Field field : fields) { + if (field.isStatic()) { + final FieldDescriptorImpl fieldDescriptor = myNodeManager.getFieldDescriptor(myStaticDescriptor, null, field); + children.add(new JavaValue(fieldDescriptor, myEvaluationContext, myNodeManager)); + //final DebuggerTreeNodeImpl node = myNodeManager.createNode(fieldDescriptor, myEvaluationContext); + //myChildren.add(node); + } + } + + node.addChildren(children, true); + } + }); + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java new file mode 100644 index 000000000000..50ac525959bb --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValue.java @@ -0,0 +1,311 @@ +/* + * 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; + +import com.intellij.debugger.SourcePosition; +import com.intellij.debugger.actions.JavaValueModifier; +import com.intellij.debugger.actions.JumpToObjectAction; +import com.intellij.debugger.engine.evaluation.EvaluateException; +import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; +import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; +import com.intellij.debugger.engine.events.DebuggerCommandImpl; +import com.intellij.debugger.engine.events.DebuggerContextCommandImpl; +import com.intellij.debugger.engine.events.SuspendContextCommandImpl; +import com.intellij.debugger.impl.DebuggerContextImpl; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.impl.watch.*; +import com.intellij.debugger.ui.tree.*; +import com.intellij.debugger.ui.tree.render.ArrayRenderer; +import com.intellij.debugger.ui.tree.render.ChildrenBuilder; +import com.intellij.debugger.ui.tree.render.DescriptorLabelListener; +import com.intellij.debugger.ui.tree.render.NodeRenderer; +import com.intellij.icons.AllIcons; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; +import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.PlatformIcons; +import com.intellij.xdebugger.frame.*; +import com.intellij.xdebugger.frame.presentation.XRegularValuePresentation; +import com.intellij.xdebugger.frame.presentation.XStringValuePresentation; +import com.intellij.xdebugger.frame.presentation.XValuePresentation; +import com.sun.jdi.Type; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.util.List; + +/** +* @author egor +*/ +public class JavaValue extends XNamedValue implements NodeDescriptorProvider { + private final JavaValue myParent; + private final ValueDescriptorImpl myValueDescriptor; + private final EvaluationContextImpl myEvaluationContext; + private final NodeManagerImpl myNodeManager; + + JavaValue(ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) { + this(null, valueDescriptor, evaluationContext, nodeManager); + } + + JavaValue(JavaValue parent, ValueDescriptorImpl valueDescriptor, EvaluationContextImpl evaluationContext, NodeManagerImpl nodeManager) { + super(valueDescriptor.getName()); + myParent = parent; + myValueDescriptor = valueDescriptor; + myEvaluationContext = evaluationContext; + myNodeManager = nodeManager; + } + + public JavaValue getParent() { + return myParent; + } + + @Override + public ValueDescriptorImpl getDescriptor() { + return myValueDescriptor; + } + + public EvaluationContextImpl getEvaluationContext() { + return myEvaluationContext; + } + + @Override + public void computePresentation(@NotNull final XValueNode node, @NotNull XValuePlace place) { + if (myEvaluationContext.getSuspendContext().isResumed()) return; + myEvaluationContext.getDebugProcess().getManagerThread().schedule(new DebuggerContextCommandImpl(getDebuggerContext()) { + @Override + public void threadAction() { + myValueDescriptor.setContext(myEvaluationContext); + myValueDescriptor.updateRepresentation(myEvaluationContext, new DescriptorLabelListener() { + @Override + public void labelChanged() { + Type type = myValueDescriptor.getType(); + String typeName = type != null ? type.name() : null; + + Icon nodeIcon; + if (myValueDescriptor instanceof FieldDescriptorImpl && ((FieldDescriptorImpl)myValueDescriptor).isStatic()) { + nodeIcon = PlatformIcons.FIELD_ICON; + } + else if (myValueDescriptor.isArray()) { + nodeIcon = AllIcons.Debugger.Db_array; + } + else if (myValueDescriptor.isPrimitive()) { + nodeIcon = AllIcons.Debugger.Db_primitive; + } + else { + if (myValueDescriptor instanceof WatchItemDescriptor) { + nodeIcon = AllIcons.Debugger.Watch; + } + else { + nodeIcon = AllIcons.Debugger.Value; + } + } + final String[] strings = splitValue(myValueDescriptor.getValueLabel()); + XValuePresentation presentation = new XRegularValuePresentation(strings[1], strings[0]); + if (myValueDescriptor.isString()) { + presentation = new TypedStringValuePresentation(StringUtil.unquoteString(strings[1]), strings[0]); + } + node.setPresentation(nodeIcon, presentation, myValueDescriptor.isExpandable()); + } + }); + } + }); + } + + private static class TypedStringValuePresentation extends XStringValuePresentation { + private final String myType; + + public TypedStringValuePresentation(@NotNull String value, @Nullable String type) { + super(value); + myType = type; + } + + @Nullable + @Override + public String getType() { + return myType; + } + } + + private static String[] splitValue(String value) { + if (StringUtil.startsWithChar(value, '{')) { + int end = value.indexOf('}'); + if (end > 0) { + return new String[]{value.substring(1, end-1), value.substring(end+1)}; + } + } + return new String[]{null, value}; + } + + private int currentStart = 0; + + @Override + public void computeChildren(@NotNull final XCompositeNode node) { + if (myEvaluationContext.getSuspendContext().isResumed()) return; + myEvaluationContext.getDebugProcess().getManagerThread().schedule(new SuspendContextCommandImpl(myEvaluationContext.getSuspendContext()) { + @Override + public void contextAction() throws Exception { + final XValueChildrenList children = new XValueChildrenList(); + final NodeRenderer renderer = myValueDescriptor.getRenderer(myEvaluationContext.getDebugProcess()); + if (renderer instanceof ArrayRenderer) { + ((ArrayRenderer)renderer).START_INDEX = currentStart; + ((ArrayRenderer)renderer).END_INDEX = currentStart + XCompositeNode.MAX_CHILDREN_TO_SHOW - 1; + currentStart += XCompositeNode.MAX_CHILDREN_TO_SHOW; + } + final Ref remainingNum = new Ref(0); + renderer.buildChildren(myValueDescriptor.getValue(), new ChildrenBuilder() { + @Override + public NodeDescriptorFactory getDescriptorManager() { + return myNodeManager; + } + + @Override + public NodeManager getNodeManager() { + return myNodeManager; + } + + @Override + public ValueDescriptor getParentDescriptor() { + return myValueDescriptor; + } + + @Override + public void setRemaining(int remaining) { + remainingNum.set(remaining); + } + + @Override + public void setChildren(List nodes) { + for (DebuggerTreeNode node : nodes) { + final NodeDescriptor descriptor = node.getDescriptor(); + if (descriptor instanceof ValueDescriptorImpl) { + children.add(new JavaValue(JavaValue.this, (ValueDescriptorImpl)descriptor, myEvaluationContext, myNodeManager)); + } + else if (descriptor instanceof MessageDescriptor) { + children.add("", new XValue() { + @Override + public void computePresentation(@NotNull XValueNode node, @NotNull XValuePlace place) { + node.setPresentation(null, new XValuePresentation() { + @NotNull + @Override + public String getSeparator() { + return ""; + } + + @Override + public void renderValue(@NotNull XValueTextRenderer renderer) { + renderer.renderValue(descriptor.getLabel()); + } + }, false); + } + }); + } + } + } + }, myEvaluationContext); + node.addChildren(children, true); + if (remainingNum.get() > 0) { + node.tooManyChildren(remainingNum.get()); + } + } + }); + } + + @Override + public void computeSourcePosition(@NotNull XNavigatable navigatable) { + if (myValueDescriptor instanceof FieldDescriptorImpl) { + SourcePosition position = ((FieldDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext()); + if (position != null) { + navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position)); + } + } + if (myValueDescriptor instanceof LocalVariableDescriptorImpl) { + SourcePosition position = ((LocalVariableDescriptorImpl)myValueDescriptor).getSourcePosition(getProject(), getDebuggerContext()); + if (position != null) { + navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(position)); + } + } + } + + private DebuggerContextImpl getDebuggerContext() { + return myEvaluationContext.getDebugProcess().getDebuggerContext(); + } + + public Project getProject() { + return myEvaluationContext.getProject(); + } + + @Override + public boolean canNavigateToTypeSource() { + return true; + } + + @Override + public void computeTypeSourcePosition(@NotNull final XNavigatable navigatable) { + if (myEvaluationContext.getSuspendContext().isResumed()) return; + DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess(); + debugProcess.getManagerThread().schedule(new JumpToObjectAction.NavigateCommand(getDebuggerContext(), myValueDescriptor, debugProcess, null) { + @Override + protected void doAction(@Nullable final SourcePosition sourcePosition) { + if (sourcePosition != null) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + navigatable.setSourcePosition(DebuggerUtilsEx.toXSourcePosition(sourcePosition)); + } + }); + } + } + }); + } + + @Nullable + @Override + public XValueModifier getModifier() { + return myValueDescriptor.canSetValue() ? new JavaValueModifier(this) : null; + } + + + private volatile String evaluationExpression = null; + @Nullable + @Override + public String getEvaluationExpression() { + if (evaluationExpression == null) { + // TODO: change API to allow to calculate it asynchronously + DebugProcessImpl debugProcess = myEvaluationContext.getDebugProcess(); + debugProcess.getManagerThread().invokeAndWait(new DebuggerCommandImpl() { + @Override + protected void action() throws Exception { + evaluationExpression = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + try { + return new TextWithImportsImpl(getDescriptor().getTreeEvaluation(JavaValue.this, getDebuggerContext())).getText(); + } + catch (EvaluateException e) { + e.printStackTrace(); + } + return null; + } + }); + } + }); + } + return evaluationExpression; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java new file mode 100644 index 000000000000..1791c24ed1b1 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaValueMarker.java @@ -0,0 +1,45 @@ +/* + * 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; + +import com.intellij.xdebugger.frame.XValueMarkerProvider; +import com.sun.jdi.ObjectReference; +import com.sun.jdi.Value; +import org.jetbrains.annotations.NotNull; + +/** + * @author egor + */ +public class JavaValueMarker extends XValueMarkerProvider { + public JavaValueMarker() { + super(JavaValue.class); + } + + @Override + public boolean canMark(@NotNull JavaValue value) { + Value obj = value.getDescriptor().getValue(); + return obj instanceof ObjectReference; + } + + @Override + public Long getMarker(@NotNull JavaValue value) { + Value obj = value.getDescriptor().getValue(); + if (obj instanceof ObjectReference) { + return ((ObjectReference)obj).uniqueID(); + } + return null; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java index a0a81d649040..a24e63ea18bd 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/SuspendContextImpl.java @@ -24,6 +24,8 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl; import com.intellij.debugger.jdi.ThreadReferenceProxyImpl; import com.intellij.openapi.diagnostic.Logger; import com.intellij.util.containers.HashSet; +import com.intellij.xdebugger.frame.XExecutionStack; +import com.intellij.xdebugger.frame.XSuspendContext; import com.sun.jdi.ObjectReference; import com.sun.jdi.ThreadReference; import com.sun.jdi.event.EventSet; @@ -31,13 +33,15 @@ import com.sun.jdi.request.EventRequest; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.Collection; import java.util.Set; import java.util.concurrent.ConcurrentLinkedQueue; /** * @author lex */ -public abstract class SuspendContextImpl implements SuspendContext { +public abstract class SuspendContextImpl extends XSuspendContext implements SuspendContext { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.engine.SuspendContextImpl"); private final DebugProcessImpl myDebugProcess; @@ -57,6 +61,8 @@ public abstract class SuspendContextImpl implements SuspendContext { private final HashSet myKeptReferences = new HashSet(); private EvaluationContextImpl myEvaluationContext = null; + private JavaExecutionStack[] myExecutionStacks; + SuspendContextImpl(@NotNull DebugProcessImpl debugProcess, int suspendPolicy, int eventVotes, EventSet set) { myDebugProcess = debugProcess; mySuspendPolicy = suspendPolicy; @@ -221,4 +227,30 @@ public abstract class SuspendContextImpl implements SuspendContext { public final SuspendContextCommandImpl pollPostponedCommand() { return myPostponedCommands.poll(); } + + @Nullable + @Override + public XExecutionStack getActiveExecutionStack() { + for (JavaExecutionStack stack : myExecutionStacks) { + if (stack.getThreadProxy().equals(myThread)) { + return stack; + } + } + return null; + } + + @Override + public XExecutionStack[] getExecutionStacks() { + return myExecutionStacks; + } + + public void initExecutionStacks() { + DebuggerManagerThreadImpl.assertIsManagerThread(); + Collection res = new ArrayList(); + Collection threads = getDebugProcess().getVirtualMachineProxy().allThreads(); + for (ThreadReferenceProxyImpl thread : threads) { + res.add(new JavaExecutionStack(thread, myDebugProcess, thread == myThread)); + } + myExecutionStacks = res.toArray(new JavaExecutionStack[res.size()]); + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/UnmuteOnStopAction.java b/java/debugger/impl/src/com/intellij/debugger/engine/UnmuteOnStopAction.java new file mode 100644 index 000000000000..310570d4ac73 --- /dev/null +++ b/java/debugger/impl/src/com/intellij/debugger/engine/UnmuteOnStopAction.java @@ -0,0 +1,44 @@ +/* + * 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; + +import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.settings.DebuggerSettings; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.ToggleAction; + +/** +* @author egor +*/ +class UnmuteOnStopAction extends ToggleAction { + private volatile boolean myUnmuteOnStop; + + UnmuteOnStopAction() { + super(DebuggerBundle.message("action.unmute.on.stop.text"), DebuggerBundle.message("action.unmute.on.stop.text"), null); + myUnmuteOnStop = DebuggerSettings.getInstance().UNMUTE_ON_STOP; + } + + @Override + public boolean isSelected(AnActionEvent e) { + return myUnmuteOnStop; + } + + @Override + public void setSelected(AnActionEvent e, boolean state) { + myUnmuteOnStop = state; + DebuggerSettings.getInstance().UNMUTE_ON_STOP = state; + } +} diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java index e8db7893e16a..dc6ba0ab438d 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/TextWithImportsImpl.java @@ -26,6 +26,10 @@ import com.intellij.psi.JavaCodeFragment; import com.intellij.psi.PsiExpression; import com.intellij.psi.PsiExpressionCodeFragment; import com.intellij.psi.PsiFile; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.evaluation.EvaluationMode; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; +import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -130,4 +134,45 @@ public final class TextWithImportsImpl implements TextWithImports{ public FileType getFileType() { return myFileType; } + + @Nullable + public static XExpression toXExpression(TextWithImports text) { + if (!text.getText().isEmpty()) { + return new XExpressionImpl(text.getText(), + XDebuggerEditorBase.getFileTypeLanguage(text.getFileType()), + StringUtil.nullize(text.getImports()), + getMode(text.getKind())); + } + return null; + } + + private static EvaluationMode getMode(CodeFragmentKind kind) { + switch (kind) { + case EXPRESSION: return EvaluationMode.EXPRESSION; + case CODE_BLOCK: return EvaluationMode.CODE_FRAGMENT; + } + throw new IllegalStateException("Unknown kind " + kind); + } + + private static CodeFragmentKind getKind(EvaluationMode mode) { + switch (mode) { + case EXPRESSION: return CodeFragmentKind.EXPRESSION; + case CODE_FRAGMENT: return CodeFragmentKind.CODE_BLOCK; + } + throw new IllegalStateException("Unknown mode " + mode); + } + + public static TextWithImports fromXExpression(@Nullable XExpression expression) { + if (expression == null) return null; + + if (expression.getCustomInfo() == null && expression.getLanguage() == null) { + return new TextWithImportsImpl(getKind(expression.getMode()), expression.getExpression()); + } + else { + return new TextWithImportsImpl(getKind(expression.getMode()), + expression.getExpression(), + StringUtil.notNullize(expression.getCustomInfo()), + expression.getLanguage() != null ? expression.getLanguage().getAssociatedFileType() : null); + } + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java index d20bad7fae99..cc9c2b3b6a03 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/requests/RequestManagerImpl.java @@ -28,7 +28,6 @@ import com.intellij.debugger.requests.RequestManager; import com.intellij.debugger.requests.Requestor; import com.intellij.debugger.settings.DebuggerSettings; import com.intellij.debugger.ui.breakpoints.Breakpoint; -import com.intellij.debugger.ui.breakpoints.BreakpointManager; import com.intellij.debugger.ui.breakpoints.FilteredRequestor; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; @@ -38,6 +37,7 @@ import com.intellij.openapi.util.Key; import com.intellij.psi.PsiClass; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.containers.HashMap; +import com.intellij.xdebugger.XDebugSession; import com.sun.jdi.*; import com.sun.jdi.event.ClassPrepareEvent; import com.sun.jdi.request.*; @@ -395,15 +395,24 @@ public class RequestManagerImpl extends DebugProcessAdapterImpl implements Reque // invoke later, so that requests are for sure created only _after_ 'processAttached()' methods of other listeners are executed process.getManagerThread().schedule(new DebuggerCommandImpl() { protected void action() throws Exception { - Project project = myDebugProcess.getProject(); - final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - for (final Breakpoint breakpoint : breakpointManager.getBreakpoints()) { - try { - breakpoint.createRequest(myDebugProcess); - } catch (Exception e) { - LOG.error(e); + ApplicationManager.getApplication().runReadAction(new Runnable() { + @Override + public void run() { + XDebugSession session = myDebugProcess.getXDebugSession(); + if (session != null) { + session.initBreakpoints(); + } } - } + }); + //Project project = myDebugProcess.getProject(); + //final BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); + //for (final Breakpoint breakpoint : breakpointManager.getBreakpoints()) { + // try { + // breakpoint.createRequest(myDebugProcess); + // } catch (Exception e) { + // LOG.error(e); + // } + //} //AccessToken token = ReadAction.start(); //try { diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java index 6c3568c29347..beadb422e9de 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerContextImpl.java @@ -127,6 +127,7 @@ public final class DebuggerContextImpl implements DebuggerContext { return new EvaluationContextImpl(getSuspendContext(), getFrameProxy(), thisObject); } + @Nullable public EvaluationContextImpl createEvaluationContext() { DebuggerManagerThreadImpl.assertIsManagerThread(); StackFrameProxyImpl frameProxy = getFrameProxy(); @@ -138,7 +139,8 @@ public final class DebuggerContextImpl implements DebuggerContext { LOG.info(e); objectReference = null; } - return new EvaluationContextImpl(getSuspendContext(), frameProxy, objectReference); + SuspendContextImpl context = getSuspendContext(); + return context != null ? new EvaluationContextImpl(context, frameProxy, objectReference) : null; } public static DebuggerContextImpl createDebuggerContext(@Nullable DebuggerSession session, @@ -178,7 +180,7 @@ public final class DebuggerContextImpl implements DebuggerContext { } public void setPositionCache(SourcePosition position) { - LOG.assertTrue(!myInitialized, "Debugger context is initialized. Cannot change caches"); + //LOG.assertTrue(!myInitialized, "Debugger context is initialized. Cannot change caches"); mySourcePosition = position; } 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 2c81eae90f72..e937aac836ef 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerUtilsEx.java @@ -21,6 +21,7 @@ package com.intellij.debugger.impl; import com.intellij.debugger.DebuggerBundle; +import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.DebuggerManagerThreadImpl; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.SuspendContextImpl; @@ -44,6 +45,8 @@ import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.SmartList; +import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.impl.XSourcePositionImpl; import com.sun.jdi.*; import com.sun.jdi.event.Event; import com.sun.jdi.event.EventSet; @@ -617,4 +620,8 @@ public abstract class DebuggerUtilsEx extends DebuggerUtils { return text.replace("\t", StringUtil.repeat(" ", tabSize)); } + @Nullable + public static XSourcePosition toXSourcePosition(@NotNull SourcePosition position) { + return XSourcePositionImpl.create(position.getFile().getVirtualFile(), position.getLine()); + } } diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java b/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java index cb280fc4f497..7f07a74463ad 100644 --- a/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java +++ b/java/debugger/impl/src/com/intellij/debugger/impl/GenericDebuggerRunner.java @@ -15,9 +15,14 @@ */ package com.intellij.debugger.impl; +import com.intellij.debugger.DebugEnvironment; +import com.intellij.debugger.DebuggerManagerEx; +import com.intellij.debugger.DefaultDebugUIEnvironment; +import com.intellij.debugger.engine.DebugProcessImpl; import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.settings.DebuggerSettings; -import com.intellij.debugger.ui.DebuggerPanelsManager; +import com.intellij.debugger.ui.tree.render.BatchEvaluator; import com.intellij.execution.ExecutionException; import com.intellij.execution.Executor; import com.intellij.execution.configurations.*; @@ -29,6 +34,10 @@ import com.intellij.openapi.fileEditor.FileDocumentManager; import com.intellij.openapi.options.SettingsEditor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugProcessStarter; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -77,12 +86,44 @@ public class GenericDebuggerRunner extends JavaPatchableProgramRunner result = new ArrayList(); - List recents = XDebuggerHistoryManager.getInstance(getProject()).getRecentExpressions(getRecentsId()); - for (String evaluationText : recents) { - if (evaluationText.indexOf('\n') == -1) { - result.add(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, evaluationText)); + List recents = XDebuggerHistoryManager.getInstance(getProject()).getRecentExpressions(getRecentsId()); + for (XExpression expression : recents) { + if (expression.getExpression().indexOf('\n') == -1) { + result.add(TextWithImportsImpl.fromXExpression(expression)); } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java index 4279e6ea7aad..3809431c21f8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerPanelsManager.java @@ -17,6 +17,7 @@ package com.intellij.debugger.ui; import com.intellij.debugger.*; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.impl.DebuggerContextListener; import com.intellij.debugger.impl.DebuggerSession; @@ -29,9 +30,9 @@ import com.intellij.execution.Executor; import com.intellij.execution.configurations.RemoteConnection; import com.intellij.execution.configurations.RunProfileState; import com.intellij.execution.executors.DefaultDebugExecutor; -import com.intellij.execution.process.ProcessHandler; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.execution.runners.ProgramRunner; +import com.intellij.execution.ui.ExecutionConsole; import com.intellij.execution.ui.RunContentDescriptor; import com.intellij.execution.ui.RunContentListener; import com.intellij.execution.ui.RunContentManager; @@ -43,49 +44,51 @@ import com.intellij.openapi.editor.colors.EditorColorsManager; import com.intellij.openapi.editor.colors.EditorColorsScheme; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugProcessStarter; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.HashMap; - public class DebuggerPanelsManager implements ProjectComponent { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.DebuggerPanelsManager"); private final Project myProject; private final ExecutionManager myExecutionManager; - private final PositionHighlighter myEditorManager; - private final HashMap mySessionTabs = new HashMap(); + //private final PositionHighlighter myEditorManager; + //private final HashMap mySessionTabs = new HashMap(); public DebuggerPanelsManager(Project project, final EditorColorsManager colorsManager, ExecutionManager executionManager) { myProject = project; myExecutionManager = executionManager; - myEditorManager = new PositionHighlighter(myProject, getContextManager()); - - final EditorColorsListener myColorsListener = new EditorColorsListener() { - public void globalSchemeChange(EditorColorsScheme scheme) { - myEditorManager.updateContextPointDescription(); - } - }; - colorsManager.addEditorColorsListener(myColorsListener); - Disposer.register(project, new Disposable() { - public void dispose() { - colorsManager.removeEditorColorsListener(myColorsListener); - } - }); - - getContextManager().addListener(new DebuggerContextListener() { - public void changeEvent(final DebuggerContextImpl newContext, int event) { - if (event == DebuggerSession.EVENT_PAUSE) { - DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { - public void run() { - toFront(newContext.getDebuggerSession()); - } - }); - } - } - }); + //myEditorManager = new PositionHighlighter(myProject, getContextManager()); + // + //final EditorColorsListener myColorsListener = new EditorColorsListener() { + // public void globalSchemeChange(EditorColorsScheme scheme) { + // myEditorManager.updateContextPointDescription(); + // } + //}; + //colorsManager.addEditorColorsListener(myColorsListener); + //Disposer.register(project, new Disposable() { + // public void dispose() { + // colorsManager.removeEditorColorsListener(myColorsListener); + // } + //}); + // + //getContextManager().addListener(new DebuggerContextListener() { + // public void changeEvent(final DebuggerContextImpl newContext, int event) { + // if (event == DebuggerSession.EVENT_PAUSE) { + // DebuggerInvocationUtil.invokeLater(myProject, new Runnable() { + // public void run() { + // toFront(newContext.getDebuggerSession()); + // } + // }); + // } + // } + //}); } private DebuggerStateManager getContextManager() { @@ -129,20 +132,15 @@ public class DebuggerPanelsManager implements ProjectComponent { debugProcess.putUserData(BatchEvaluator.REMOTE_SESSION_KEY, Boolean.TRUE); } - final DebuggerSessionTab sessionTab = new DebuggerSessionTab(myProject, modelEnvironment.getSessionName(), environment, debuggerSession); - RunContentDescriptor runContentDescriptor = sessionTab.getRunContentDescriptor(); - RunContentDescriptor reuseContent = environment.getReuseContent(); - if (reuseContent != null) { - final ProcessHandler prevHandler = reuseContent.getProcessHandler(); - if (prevHandler != null) { - final DebuggerSessionTab prevSession = mySessionTabs.get(prevHandler); - if (prevSession != null) { - sessionTab.reuse(prevSession); + XDebugSession debugSession = + XDebuggerManager.getInstance(myProject).startSessionAndShowTab(modelEnvironment.getSessionName(), environment.getReuseContent(), new XDebugProcessStarter() { + @Override + @NotNull + public XDebugProcess start(@NotNull XDebugSession session) { + return new JavaDebugProcess(session, debuggerSession); } - } - } - mySessionTabs.put(runContentDescriptor.getProcessHandler(), sessionTab); - return runContentDescriptor; + }); + return debugSession.getRunContentDescriptor(); } @@ -152,11 +150,11 @@ public class DebuggerPanelsManager implements ProjectComponent { final RunContentListener myContentListener = new RunContentListener() { public void contentSelected(RunContentDescriptor descriptor) { - DebuggerSessionTab sessionTab = descriptor != null ? getSessionTab(descriptor.getProcessHandler()) : null; + DebuggerSession session = getSession(myProject, descriptor.getExecutionConsole()); - if (sessionTab != null) { + if (session != null) { getContextManager() - .setState(sessionTab.getContextManager().getContext(), sessionTab.getSession().getState(), DebuggerSession.EVENT_CONTEXT, null); + .setState(session.getContextManager().getContext(), session.getState(), DebuggerSession.EVENT_CONTEXT, null); } else { getContextManager() @@ -165,11 +163,6 @@ public class DebuggerPanelsManager implements ProjectComponent { } public void contentRemoved(RunContentDescriptor descriptor) { - DebuggerSessionTab sessionTab = getSessionTab(descriptor.getProcessHandler()); - if (sessionTab != null) { - mySessionTabs.remove(descriptor.getProcessHandler()); - Disposer.dispose(sessionTab); - } } }; @@ -225,13 +218,21 @@ public class DebuggerPanelsManager implements ProjectComponent { } } - private DebuggerSessionTab getSessionTab(ProcessHandler processHandler) { - return mySessionTabs.get(processHandler); + private DebuggerSession getSession(Project project, ExecutionConsole console) { + XDebugSession session = XDebuggerManager.getInstance(project).getDebugSession(console); + if (session != null) { + XDebugProcess process = session.getDebugProcess(); + if (process instanceof JavaDebugProcess) { + return ((JavaDebugProcess)process).getDebuggerSession(); + } + } + return null; } @Nullable private DebuggerSessionTab getSessionTab(DebuggerSession session) { - return session != null ? getSessionTab(session.getProcess().getExecutionResult().getProcessHandler()) : null; + //return session != null ? getSessionTab(session.getProcess().getExecutionResult().getProcessHandler()) : null; + return null; } } 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 45cfa2e8a9f4..40359e434a02 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/DebuggerSessionTab.java @@ -42,6 +42,7 @@ 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; import com.intellij.idea.ActionsBundle; @@ -455,32 +456,31 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos myUi.selectAndFocus(myUi.findContent(DebuggerContentInfo.FRAME_CONTENT), true, false); } - private int myThreadDumpsCount = 0; - private int myCurrentThreadDumpId = 1; + private static int myThreadDumpsCount = 0; + private static int myCurrentThreadDumpId = 1; - public void addThreadDump(List threads) { - final Project project = getProject(); + public static void addThreadDump(Project project, List threads, final RunnerLayoutUi ui, DebuggerSession session) { final TextConsoleBuilder consoleBuilder = TextConsoleBuilderFactory.getInstance().createBuilder(project); - consoleBuilder.filters(ExceptionFilters.getFilters(myDebuggerSession.getSearchScope())); + consoleBuilder.filters(ExceptionFilters.getFilters(session.getSearchScope())); final ConsoleView consoleView = consoleBuilder.getConsole(); final DefaultActionGroup toolbarActions = new DefaultActionGroup(); consoleView.allowHeavyFilters(); final ThreadDumpPanel panel = new ThreadDumpPanel(project, consoleView, toolbarActions, threads); final String id = createThreadDumpContentId(); - final Content content = myUi.createContent(id, panel, id, null, null); + final Content content = ui.createContent(id, panel, id, null, null); content.setCloseable(true); content.setDescription("Thread Dump"); - myUi.addContent(content); - myUi.selectAndFocus(content, true, true); + ui.addContent(content); + ui.selectAndFocus(content, true, true); myThreadDumpsCount += 1; myCurrentThreadDumpId += 1; - Disposer.register(this, new Disposable() { - @Override - public void dispose() { - myUi.removeContent(content, true); - } - }); + //Disposer.register(this, new Disposable() { + // @Override + // public void dispose() { + // ui.removeContent(content, true); + // } + //}); Disposer.register(content, new Disposable() { @Override public void dispose() { @@ -491,13 +491,13 @@ public class DebuggerSessionTab extends DebuggerSessionTabBase implements Dispos } }); Disposer.register(content, consoleView); - myUi.selectAndFocus(content, true, false); + ui.selectAndFocus(content, true, false); if (threads.size() > 0) { panel.selectStackFrame(0); } } - private String createThreadDumpContentId() { + private static String createThreadDumpContentId() { return THREAD_DUMP_CONTENT_PREFIX + " #" + myCurrentThreadDumpId; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java index f3bbf9e9ddff..437cd85bedf8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByClassRule.java @@ -46,7 +46,7 @@ class XBreakpointGroupingByClassRule extends XBreakpointGroupingRule groups) { if (b instanceof XBreakpoint) { - Breakpoint javaBreakpoint = BreakpointManager.findBreakpoint((XBreakpoint)b); + Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint((XBreakpoint)b); if (javaBreakpoint == null) { return null; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java index 7644b87d0d3e..f06574569db8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/XBreakpointGroupingByPackageRule.java @@ -44,7 +44,7 @@ public class XBreakpointGroupingByPackageRule extends XBreakpointGroupingRule public XBreakpointPackageGroup getGroup(@NotNull B breakpoint, @NotNull Collection groups) { String packageName = null; if (breakpoint instanceof XBreakpoint) { - Breakpoint javaBreakpoint = BreakpointManager.findBreakpoint((XBreakpoint)breakpoint); + Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint((XBreakpoint)breakpoint); if (javaBreakpoint != null) { packageName = javaBreakpoint.getPackageName(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java index 0aeb93efa992..fdee459a1460 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java @@ -42,10 +42,12 @@ import com.intellij.ui.AppUIUtil; import com.intellij.ui.classFilter.ClassFilter; import com.intellij.util.StringBuilderSpinAllocator; import com.intellij.util.ThreeState; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.breakpoints.SuspendPolicy; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.XLineBreakpoint; import com.intellij.xdebugger.impl.XDebuggerHistoryManager; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.breakpoints.ui.DefaultLogExpressionComboBoxPanel; import com.sun.jdi.*; import com.sun.jdi.event.LocatableEvent; @@ -59,6 +61,8 @@ import javax.swing.*; import java.util.List; public abstract class Breakpoint

implements FilteredRequestor, ClassPrepareRequestor { + public static Key DATA_KEY = Key.create("JavaBreakpoint"); + final XBreakpoint

myXBreakpoint; protected final Project myProject; @@ -441,10 +445,10 @@ public abstract class Breakpoint

implements try { String logMessage = JDOMExternalizerUtil.readField(parentNode, LOG_MESSAGE_OPTION_NAME); if (logMessage != null && !logMessage.isEmpty()) { - TextWithImportsImpl text = new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, logMessage); - XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(DefaultLogExpressionComboBoxPanel.HISTORY_KEY, text.getText()); + XExpressionImpl expression = XExpressionImpl.fromText(logMessage); + XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(DefaultLogExpressionComboBoxPanel.HISTORY_KEY, expression); if (Boolean.valueOf(JDOMExternalizerUtil.readField(parentNode, "LOG_EXPRESSION_ENABLED"))) { - setLogMessage(text); + myXBreakpoint.setLogExpressionObject(expression); } } } @@ -461,11 +465,11 @@ public abstract class Breakpoint

implements public abstract PsiElement getEvaluationElement(); protected TextWithImports getLogMessage() { - return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getLogExpression()); + return TextWithImportsImpl.fromXExpression(myXBreakpoint.getLogExpressionObject()); } protected TextWithImports getCondition() { - return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, myXBreakpoint.getCondition()); + return TextWithImportsImpl.fromXExpression(myXBreakpoint.getConditionExpression()); } public boolean isEnabled() { @@ -485,8 +489,8 @@ public abstract class Breakpoint

implements } protected boolean isLogExpressionEnabled() { - String expression = myXBreakpoint.getLogExpression(); - if (expression == null || expression.isEmpty()) { + XExpression expression = myXBreakpoint.getLogExpressionObject(); + if (expression == null || expression.getExpression().isEmpty()) { return false; } return !getLogMessage().isEmpty(); @@ -602,30 +606,16 @@ public abstract class Breakpoint

implements myXBreakpoint.setSuspendPolicy(transformSuspendPolicy(policy)); } - protected void setLogMessage(@Nullable TextWithImports logMessage) { - if (logMessage != null && !logMessage.getText().isEmpty()) { - myXBreakpoint.setLogExpression(logMessage.toExternalForm()); - } - else { - myXBreakpoint.setLogExpression(null); - } - } - protected boolean isConditionEnabled() { - String condition = myXBreakpoint.getCondition(); - if (condition == null || condition.isEmpty()) { + XExpression condition = myXBreakpoint.getConditionExpression(); + if (condition == null || condition.getExpression().isEmpty()) { return false; } return !getCondition().isEmpty(); } public void setCondition(@Nullable TextWithImports condition) { - if (condition != null && !condition.getText().isEmpty()) { - myXBreakpoint.setCondition(condition.toExternalForm()); - } - else { - myXBreakpoint.setCondition(null); - } + myXBreakpoint.setConditionExpression(TextWithImportsImpl.toXExpression(condition)); } protected void addInstanceFilter(long l) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java index 91640416755d..979e675f041f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManager.java @@ -48,8 +48,8 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.psi.PsiField; -import com.intellij.util.Alarm; -import com.intellij.util.EventDispatcher; +import com.intellij.util.Function; +import com.intellij.util.containers.ContainerUtil; import com.intellij.xdebugger.XDebuggerManager; import com.intellij.xdebugger.XDebuggerUtil; import com.intellij.xdebugger.breakpoints.*; @@ -70,7 +70,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.java.debugger.breakpoints.properties.JavaExceptionBreakpointProperties; import javax.swing.*; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; public class BreakpointManager { private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.ui.breakpoints.BreakpointManager"); @@ -84,12 +87,8 @@ public class BreakpointManager { private static final String CONVERTED_PARAM = "converted"; private final Project myProject; - private final Map myBreakpoints = new HashMap(); // breakpoints storage, access should be synchronized - @Nullable private List myBreakpointsListForIteration = null; // another list for breakpoints iteration, unsynchronized access ok private final Map myUIProperties = new LinkedHashMap(); - private final EventDispatcher myDispatcher = EventDispatcher.create(BreakpointManagerListener.class); - private final StartupManager myStartupManager; public BreakpointManager(@NotNull Project project, @NotNull StartupManager startupManager, @NotNull DebuggerManagerImpl debuggerManager) { @@ -124,22 +123,18 @@ public class BreakpointManager { public void init() { XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager(); - manager.addBreakpointListener(new XBreakpointListener() { + manager.addBreakpointListener(new XBreakpointAdapter>() { @Override - public void breakpointAdded(@NotNull XBreakpoint xBreakpoint) { - if (isJavaType(xBreakpoint)) { - onBreakpointAdded(xBreakpoint); + public void breakpointAdded(@NotNull XBreakpoint xBreakpoint) { + Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint); + if (breakpoint != null) { + addBreakpoint(breakpoint); } } - @Override - public void breakpointRemoved(@NotNull XBreakpoint xBreakpoint) { - onBreakpointRemoved(xBreakpoint); - } - @Override public void breakpointChanged(@NotNull XBreakpoint xBreakpoint) { - Breakpoint breakpoint = myBreakpoints.get(xBreakpoint); + Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint); if (breakpoint != null) { fireBreakpointChanged(breakpoint); } @@ -306,13 +301,6 @@ public class BreakpointManager { return null; } - @Nullable - public static Breakpoint findBreakpoint(@NotNull XBreakpoint xBreakpoint) { - Project project = ((XBreakpointBase)xBreakpoint).getProject(); - BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(project).getBreakpointManager(); - return breakpointManager.myBreakpoints.get(xBreakpoint); - } - private HashMap myOriginalBreakpointsNodes = new HashMap(); public void readExternal(@NotNull final Element parentNode) { @@ -380,9 +368,11 @@ public class BreakpointManager { XBreakpointManager manager = XDebuggerManager.getInstance(myProject).getBreakpointManager(); JavaExceptionBreakpointType type = (JavaExceptionBreakpointType)XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class); XBreakpoint xBreakpoint = manager.getDefaultBreakpoint(type); - Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint); - breakpoint.readExternal(breakpointElement); - addBreakpoint(breakpoint); + Breakpoint breakpoint = getJavaBreakpoint(xBreakpoint); + if (breakpoint != null) { + breakpoint.readExternal(breakpointElement); + addBreakpoint(breakpoint); + } } } } @@ -463,12 +453,12 @@ public class BreakpointManager { xBreakpoint = createXLineBreakpoint(JavaFieldBreakpointType.class, breakpointNode); } else if (category.equals(ExceptionBreakpoint.CATEGORY.toString())) { - xBreakpoint = createXBreakpoint(JavaExceptionBreakpointType.class, breakpointNode); + xBreakpoint = createXBreakpoint(JavaExceptionBreakpointType.class, breakpointNode); } if (xBreakpoint == null) { throw new IllegalStateException("Unknown breakpoint category " + category); } - return myBreakpoints.get(xBreakpoint); + return getJavaBreakpoint(xBreakpoint); } private > XBreakpoint createXBreakpoint(Class> typeCls, @@ -477,9 +467,10 @@ public class BreakpointManager { return ApplicationManager.getApplication().runWriteAction(new Computable() { @Override public XBreakpoint compute() { - return XDebuggerManager.getInstance(myProject).getBreakpointManager() - .addBreakpoint((XBreakpointType)type, type.createProperties()); - }}); + return XDebuggerManager.getInstance(myProject).getBreakpointManager() + .addBreakpoint((XBreakpointType)type, type.createProperties()); + } + }); } private > XLineBreakpoint createXLineBreakpoint(Class> typeCls, @@ -505,19 +496,16 @@ public class BreakpointManager { return addXLineBreakpoint(typeCls, doc, line); } - //used in Fabrique - public synchronized void addBreakpoint(@NotNull Breakpoint breakpoint) { - myBreakpoints.put(breakpoint.myXBreakpoint, breakpoint); - myBreakpointsListForIteration = null; - breakpoint.updateUI(); - RequestManagerImpl.createRequests(breakpoint); - myDispatcher.getMulticaster().breakpointsChanged(); - checkAndNotifyPossiblySlowBreakpoint(breakpoint.myXBreakpoint); + public static void addBreakpointInt(@NotNull Breakpoint breakpoint) { + BreakpointManager breakpointManager = DebuggerManagerEx.getInstanceEx(breakpoint.getProject()).getBreakpointManager(); + breakpointManager.addBreakpoint(breakpoint); } - private synchronized void onBreakpointAdded(XBreakpoint xBreakpoint) { - Breakpoint breakpoint = createJavaBreakpoint(xBreakpoint); - addBreakpoint(breakpoint); + //used in Fabrique + public void addBreakpoint(@NotNull Breakpoint breakpoint) { + breakpoint.myXBreakpoint.putUserData(Breakpoint.DATA_KEY, breakpoint); + breakpoint.updateUI(); + checkAndNotifyPossiblySlowBreakpoint(breakpoint.myXBreakpoint); } public void removeBreakpoint(@Nullable final Breakpoint breakpoint) { @@ -532,24 +520,6 @@ public class BreakpointManager { }); } - private synchronized void onBreakpointRemoved(@Nullable final XBreakpoint xBreakpoint) { - ApplicationManager.getApplication().assertIsDispatchThread(); - if (xBreakpoint == null) { - return; - } - - Breakpoint breakpoint = myBreakpoints.remove(xBreakpoint); - if (breakpoint != null) { - //updateBreakpointRules(breakpoint); - myBreakpointsListForIteration = null; - //we delete breakpoints inside release, so gutter will not fire events to deleted breakpoints - breakpoint.delete(); - - RequestManagerImpl.deleteRequests(breakpoint); - myDispatcher.getMulticaster().breakpointsChanged(); - } - } - public void writeExternal(@NotNull final Element parentNode) { // restore old breakpoints for (Element group : myOriginalBreakpointsNodes.values()) { @@ -563,39 +533,34 @@ public class BreakpointManager { } @NotNull - public synchronized List getBreakpoints() { - if (myBreakpointsListForIteration == null) { - myBreakpointsListForIteration = new ArrayList(myBreakpoints.size()); - - XBreakpoint[] xBreakpoints = ApplicationManager.getApplication().runReadAction(new Computable[]>() { - public XBreakpoint[] compute() { - return getXBreakpointManager().getAllBreakpoints(); - } - }); - for (XBreakpoint xBreakpoint : xBreakpoints) { - if (isJavaType(xBreakpoint)) { - Breakpoint breakpoint = myBreakpoints.get(xBreakpoint); - if (breakpoint == null) { - breakpoint = createJavaBreakpoint(xBreakpoint); - myBreakpoints.put(xBreakpoint, breakpoint); + public List getBreakpoints() { + return ApplicationManager.getApplication().runReadAction(new Computable>() { + @Override + public List compute() { + return ContainerUtil.mapNotNull(getXBreakpointManager().getAllBreakpoints(), new Function, Breakpoint>() { + @Override + public Breakpoint fun(XBreakpoint xBreakpoint) { + return getJavaBreakpoint(xBreakpoint); } - } + }); } + }); + } - myBreakpointsListForIteration.addAll(myBreakpoints.values()); + @Nullable + public static Breakpoint getJavaBreakpoint(@Nullable XBreakpoint xBreakpoint) { + if (xBreakpoint == null) { + return null; } - return myBreakpointsListForIteration; - } - - private boolean isJavaType(XBreakpoint xBreakpoint) { - return xBreakpoint.getType() instanceof JavaBreakpointType; - } - - private Breakpoint createJavaBreakpoint(XBreakpoint xBreakpoint) { + Breakpoint breakpoint = xBreakpoint.getUserData(Breakpoint.DATA_KEY); + if (breakpoint != null) { + return breakpoint; + } + Project project = ((XBreakpointBase)xBreakpoint).getProject(); if (xBreakpoint.getType() instanceof JavaBreakpointType) { - return ((JavaBreakpointType)xBreakpoint.getType()).createJavaBreakpoint(myProject, xBreakpoint); + return ((JavaBreakpointType)xBreakpoint.getType()).createJavaBreakpoint(project, xBreakpoint); } - throw new IllegalStateException("Unsupported breakpoint type:" + xBreakpoint.getType()); + return null; } //interaction with RequestManagerImpl @@ -698,15 +663,6 @@ public class BreakpointManager { } } - public void updateAllRequests() { - ApplicationManager.getApplication().assertIsDispatchThread(); - - List breakpoints = getBreakpoints(); - for (Breakpoint breakpoint : breakpoints) { - fireBreakpointChanged(breakpoint); - } - } - public void updateBreakpointsUI() { ApplicationManager.getApplication().assertIsDispatchThread(); for (Breakpoint breakpoint : getBreakpoints()) { @@ -722,41 +678,10 @@ public class BreakpointManager { } } - public void addBreakpointManagerListener(@NotNull BreakpointManagerListener listener) { - myDispatcher.addListener(listener); - } - - public void removeBreakpointManagerListener(@NotNull BreakpointManagerListener listener) { - myDispatcher.removeListener(listener); - } - - private boolean myAllowMulticasting = true; - private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD); public void fireBreakpointChanged(Breakpoint breakpoint) { breakpoint.reload(); breakpoint.updateUI(); RequestManagerImpl.updateRequests(breakpoint); - if (myAllowMulticasting) { - // can be invoked from non-AWT thread - myAlarm.cancelAllRequests(); - final Runnable runnable = new Runnable() { - @Override - public void run() { - myAlarm.addRequest(new Runnable() { - @Override - public void run() { - myDispatcher.getMulticaster().breakpointsChanged(); - } - }, 100); - } - }; - if (ApplicationManager.getApplication().isDispatchThread()) { - runnable.run(); - } - else { - SwingUtilities.invokeLater(runnable); - } - } } public void setBreakpointEnabled(@NotNull final Breakpoint breakpoint, final boolean enabled) { @@ -796,7 +721,7 @@ public class BreakpointManager { @Nullable public Breakpoint findMasterBreakpoint(@NotNull Breakpoint dependentBreakpoint) { XDependentBreakpointManager dependentBreakpointManager = ((XBreakpointManagerImpl)getXBreakpointManager()).getDependentBreakpointManager(); - return myBreakpoints.get(dependentBreakpointManager.getMasterBreakpoint(dependentBreakpoint.myXBreakpoint)); + return getJavaBreakpoint(dependentBreakpointManager.getMasterBreakpoint(dependentBreakpoint.myXBreakpoint)); } public String getProperty(String name) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java index 4316da6e6743..96ee1cd18b8a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/ExceptionBreakpoint.java @@ -26,6 +26,7 @@ import com.intellij.debugger.SourcePosition; import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.icons.AllIcons; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Computable; @@ -121,7 +122,7 @@ public class ExceptionBreakpoint extends Breakpoint() { + SourcePosition classPosition = ApplicationManager.getApplication().runReadAction(new Computable() { public SourcePosition compute() { PsiClass psiClass = DebuggerUtils.findClass(getQualifiedName(), myProject, debugProcess.getSearchScope()); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java index c4175eb0b6af..3343f4bce7ca 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/FilteredRequestorImpl.java @@ -133,7 +133,7 @@ public class FilteredRequestorImpl implements JDOMExternalizable, FilteredReques breakpoint.setCondition(CONDITION_ENABLED ? myCondition : null); if (myCondition != null && !myCondition.isEmpty()) { - XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(DefaultConditionComboBoxPanel.HISTORY_KEY, myCondition.getText()); + XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(DefaultConditionComboBoxPanel.HISTORY_KEY, TextWithImportsImpl.toXExpression(myCondition)); } breakpoint.setClassFiltersEnabled(CLASS_FILTERS_ENABLED); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java index 2776032a2f4f..c6a67510c903 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointType.java @@ -17,6 +17,7 @@ package com.intellij.debugger.ui.breakpoints; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.breakpoints.XBreakpoint; +import org.jetbrains.annotations.NotNull; import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperties; /** @@ -24,5 +25,6 @@ import org.jetbrains.java.debugger.breakpoints.properties.JavaBreakpointProperti * @author egor */ public interface JavaBreakpointType

{ + @NotNull Breakpoint createJavaBreakpoint(Project project, XBreakpoint

breakpoint); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java index 0a223b6881fa..a537db14b2e8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointTypeBase.java @@ -60,7 +60,7 @@ public abstract class JavaBreakpointTypeBase @Nullable @Override public XSourcePosition getSourcePosition(@NotNull XBreakpoint breakpoint) { - Breakpoint javaBreakpoint = BreakpointManager.findBreakpoint(breakpoint); + Breakpoint javaBreakpoint = BreakpointManager.getJavaBreakpoint(breakpoint); if (javaBreakpoint != null) { PsiClass aClass = javaBreakpoint.getPsiClass(); if (aClass != null && aClass.getContainingFile() != null) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java index d5d4b714875c..3bbea653a8a9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaExceptionBreakpointType.java @@ -126,6 +126,7 @@ public class JavaExceptionBreakpointType extends JavaBreakpointTypeBase breakpoint) { if (!XDebuggerManager.getInstance(project).getBreakpointManager().isDefaultBreakpoint(breakpoint)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java index ea4f30d800ab..0b1ba90ecbd6 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaFieldBreakpointType.java @@ -164,6 +164,7 @@ public class JavaFieldBreakpointType extends JavaLineBreakpointTypeBase breakpoint) { - BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)BreakpointManager.findBreakpoint(breakpoint); + BreakpointWithHighlighter javaBreakpoint = (BreakpointWithHighlighter)BreakpointManager.getJavaBreakpoint(breakpoint); if (javaBreakpoint != null) { return javaBreakpoint.getDescription(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java index 54771f00b631..2ec27499e9a3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaMethodBreakpointType.java @@ -110,6 +110,7 @@ public class JavaMethodBreakpointType extends JavaLineBreakpointTypeBase() { + //final MethodDescriptor descriptor = docManager.commitAndRunReadAction(new Computable() { + // conflicts with readAction on initial breakpoints creation + final MethodDescriptor descriptor = ApplicationManager.getApplication().runReadAction(new Computable() { @Nullable public MethodDescriptor compute() { //PsiMethod method = DebuggerUtilsEx.findPsiMethod(psiJavaFile, endOffset); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java index 1bd00d1c5576..33a4fdb5d666 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/DebuggerTreePanel.java @@ -37,7 +37,7 @@ import javax.swing.*; import java.awt.*; import java.awt.event.KeyEvent; -public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements DataProvider { +public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements DataProvider, Disposable { public static final DataKey DATA_KEY = DataKey.create("DebuggerPanel"); private final SingleAlarm myRebuildAlarm = new SingleAlarm(new Runnable() { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java index a3f95f8ea983..554e5f117bcb 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/FrameVariablesTree.java @@ -162,7 +162,7 @@ public class FrameVariablesTree extends DebuggerTree { super.buildVariables(stackDescriptor, evaluationContext); } else { - final Map visibleVariables = getVisibleVariables(stackDescriptor); + final Map visibleVariables = getVisibleVariables(stackDescriptor.getFrameProxy()); final EvaluationContextImpl evalContext = debuggerContext.createEvaluationContext(); final Pair, Set> usedVars = ApplicationManager.getApplication().runReadAction(new Computable, Set>>() { @@ -225,7 +225,7 @@ public class FrameVariablesTree extends DebuggerTree { } } - private static List collectVariablesFromBytecode(final StackFrameProxy frame, int argumentCount) throws EvaluateException { + public static List collectVariablesFromBytecode(final StackFrameProxy frame, int argumentCount) throws EvaluateException { if (!frame.getVirtualMachine().canGetBytecodes()) { return Collections.emptyList(); } @@ -276,8 +276,7 @@ public class FrameVariablesTree extends DebuggerTree { return Collections.emptyList(); } - private static Map getVisibleVariables(final StackFrameDescriptorImpl stackDescriptor) throws EvaluateException { - final StackFrameProxyImpl frame = stackDescriptor.getFrameProxy(); + public static Map getVisibleVariables(final StackFrameProxyImpl frame) throws EvaluateException { final Map vars = new HashMap(); for (LocalVariableProxyImpl localVariableProxy : frame.visibleVariables()) { vars.put(localVariableProxy.name(), localVariableProxy); @@ -318,7 +317,7 @@ public class FrameVariablesTree extends DebuggerTree { return true; } - private static Pair, Set> findReferencedVars(final Set visibleVars, + public static Pair, Set> findReferencedVars(final Set visibleVars, final SourcePosition position, EvaluationContextImpl evalContext) { final int line = position.getLine(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java index e5d5b79ebd29..2d5130e9f386 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java @@ -404,7 +404,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi public abstract class BuildNodeCommand extends DebuggerContextCommandImpl { private final DebuggerTreeNodeImpl myNode; - protected final List myChildren = new LinkedList(); + protected final List myChildren = new LinkedList(); protected BuildNodeCommand(DebuggerTreeNodeImpl node) { super(DebuggerTree.this.getDebuggerContext()); @@ -425,7 +425,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi @Override public void run() { myNode.removeAllChildren(); - for (DebuggerTreeNode debuggerTreeNode : myChildren) { + for (DebuggerTreeNodeImpl debuggerTreeNode : myChildren) { myNode.add(debuggerTreeNode); } myNode.childrenChanged(scrollToVisible); @@ -587,9 +587,16 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi return (ValueDescriptorImpl)getNode().getDescriptor(); } + @Override + public void setRemaining(int remaining) {} + @Override public void setChildren(final List children) { - myChildren.addAll(children); + for (DebuggerTreeNode child : children) { + if (child instanceof DebuggerTreeNodeImpl) { + myChildren.add(((DebuggerTreeNodeImpl)child)); + } + } updateUI(false); } } @@ -661,7 +668,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi private class BuildThreadGroupCommand extends DebuggerCommandImpl { private final DebuggerTreeNodeImpl myNode; - protected final List myChildren = new LinkedList(); + protected final List myChildren = new LinkedList(); public BuildThreadGroupCommand(DebuggerTreeNodeImpl node) { myNode = node; @@ -719,7 +726,7 @@ public abstract class DebuggerTree extends DebuggerTreeBase implements DataProvi @Override public void run() { myNode.removeAllChildren(); - for (DebuggerTreeNode debuggerTreeNode : myChildren) { + for (DebuggerTreeNodeImpl debuggerTreeNode : myChildren) { myNode.add(debuggerTreeNode); } myNode.childrenChanged(scrollToVisible); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java index 56e0208d7d2c..3695d0c462b0 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeExpression.java @@ -258,7 +258,8 @@ public class DebuggerTreeNodeExpression { public static PsiExpression getEvaluationExpression(DebuggerTreeNodeImpl node, DebuggerContextImpl context) throws EvaluateException { if(node.getDescriptor() instanceof ValueDescriptorImpl) { - return ((ValueDescriptorImpl)node.getDescriptor()).getTreeEvaluation(node, context); + throw new IllegalStateException("Not supported any more"); + //return ((ValueDescriptorImpl)node.getDescriptor()).getTreeEvaluation(node, context); } else { LOG.error(node.getDescriptor() != null ? node.getDescriptor().getClass().getName() : "null"); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java index ed9f76ff3db8..dd8f17895522 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTreeNodeImpl.java @@ -40,16 +40,17 @@ import com.intellij.xdebugger.impl.ui.tree.ValueMarkup; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.tree.MutableTreeNode; import java.util.Map; -public class DebuggerTreeNodeImpl extends TreeBuilderNode implements DebuggerTreeNode{ +public class DebuggerTreeNodeImpl extends TreeBuilderNode implements DebuggerTreeNode, NodeDescriptorProvider, MutableTreeNode { private Icon myIcon; private SimpleColoredText myText; private String myMarkupTooltipText; private final DebuggerTree myTree; private final Map myProperties = new HashMap(); - private DebuggerTreeNodeImpl(DebuggerTree tree, NodeDescriptor descriptor) { + public DebuggerTreeNodeImpl(DebuggerTree tree, NodeDescriptor descriptor) { super(descriptor); myTree = tree; } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java index 223b3cc8fcc4..6a7a57ba7670 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/FieldDescriptorImpl.java @@ -41,6 +41,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.StringBuilderSpinAllocator; import com.sun.jdi.*; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; @@ -70,6 +71,7 @@ public class FieldDescriptorImpl extends ValueDescriptorImpl implements FieldDes } @SuppressWarnings({"HardCodedStringLiteral"}) + @Nullable public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) { if (context.getFrameProxy() == null) { return null; diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java index f93ab91056b8..d2109c54f1c4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/LocalVariableDescriptorImpl.java @@ -35,6 +35,7 @@ import com.intellij.util.IncorrectOperationException; import com.intellij.util.StringBuilderSpinAllocator; import com.sun.jdi.Value; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements LocalVariableDescriptor { private final StackFrameProxyImpl myFrameProxy; @@ -58,6 +59,7 @@ public class LocalVariableDescriptorImpl extends ValueDescriptorImpl implements return myLocalVariable; } + @Nullable public SourcePosition getSourcePosition(final Project project, final DebuggerContextImpl context) { StackFrameProxyImpl frame = context.getFrameProxy(); if (frame == null) return null; 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 54e4826f8d1d..3455672fa4dc 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 @@ -58,7 +58,7 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { myDisplayDescriptorSearcher.clear(); } - private T getDescriptor(NodeDescriptor parent, DescriptorData key) { + public T getDescriptor(NodeDescriptor parent, DescriptorData key) { final T descriptor = key.createDescriptor(myProject); final T oldDescriptor = findDescriptor(parent, descriptor, key); @@ -199,23 +199,23 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { } private static class DescriptorTreeSearcher { - private final MarkedDescriptorTree myDescriportTree; + private final MarkedDescriptorTree myDescriptorTree; private final HashMap mySearchedDescriptors = new HashMap(); - public DescriptorTreeSearcher(MarkedDescriptorTree descriportTree) { - myDescriportTree = descriportTree; + public DescriptorTreeSearcher(MarkedDescriptorTree descriptorTree) { + myDescriptorTree = descriptorTree; } @Nullable public T search(NodeDescriptor parent, T descriptor, DescriptorKey key) { final T result; if(parent == null) { - result = myDescriportTree.getChild(null, key); + result = myDescriptorTree.getChild(null, key); } else { final NodeDescriptor parentDescriptor = getSearched(parent); - result = parentDescriptor != null ? myDescriportTree.getChild(parentDescriptor, key) : null; + result = parentDescriptor != null ? myDescriptorTree.getChild(parentDescriptor, key) : null; } if(result != null) { mySearchedDescriptors.put(descriptor, result); @@ -229,13 +229,13 @@ public class NodeDescriptorFactoryImpl implements NodeDescriptorFactory { public void clear() { mySearchedDescriptors.clear(); - myDescriportTree.clear(); + myDescriptorTree.clear(); } } private class DisplayDescriptorTreeSearcher extends DescriptorTreeSearcher { - public DisplayDescriptorTreeSearcher(MarkedDescriptorTree descriportTree) { - super(descriportTree); + public DisplayDescriptorTreeSearcher(MarkedDescriptorTree descriptorTree) { + super(descriptorTree); } @Override diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorProvider.java similarity index 72% rename from java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java rename to java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorProvider.java index 8d84aebd9126..097b7bb1175a 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointManagerListener.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeDescriptorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,10 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.intellij.debugger.ui.breakpoints; +package com.intellij.debugger.ui.impl.watch; -import java.util.EventListener; - -public interface BreakpointManagerListener extends EventListener{ - void breakpointsChanged (); +/** + * @author egor + */ +public interface NodeDescriptorProvider { + NodeDescriptorImpl getDescriptor(); } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java index 2c2860e3d9ac..0e009582521f 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java @@ -17,16 +17,14 @@ package com.intellij.debugger.ui.impl.watch; import com.intellij.Patches; import com.intellij.debugger.DebuggerContext; -import com.intellij.debugger.engine.DebugProcess; -import com.intellij.debugger.engine.DebugProcessImpl; -import com.intellij.debugger.engine.DebuggerManagerThreadImpl; -import com.intellij.debugger.engine.DebuggerUtils; +import com.intellij.debugger.engine.*; import com.intellij.debugger.engine.evaluation.EvaluateException; import com.intellij.debugger.engine.evaluation.EvaluationContextImpl; import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.impl.DebuggerContextImpl; import com.intellij.debugger.jdi.VirtualMachineProxyImpl; import com.intellij.debugger.settings.NodeRendererSettings; +import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.debugger.ui.tree.NodeDescriptor; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.debugger.ui.tree.render.*; @@ -364,18 +362,18 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements } //returns expression that evaluates tree to this descriptor - public PsiExpression getTreeEvaluation(DebuggerTreeNodeImpl debuggerTreeNode, DebuggerContextImpl context) throws EvaluateException { - if(debuggerTreeNode.getParent() != null && debuggerTreeNode.getParent().getDescriptor() instanceof ValueDescriptor) { - final NodeDescriptorImpl descriptor = debuggerTreeNode.getParent().getDescriptor(); + public PsiExpression getTreeEvaluation(JavaValue value, DebuggerContextImpl context) throws EvaluateException { + if(value.getParent() != null) { + final NodeDescriptorImpl descriptor = value.getParent().getDescriptor(); final ValueDescriptorImpl vDescriptor = ((ValueDescriptorImpl)descriptor); - final PsiExpression parentEvaluation = vDescriptor.getTreeEvaluation(debuggerTreeNode.getParent(), context); + final PsiExpression parentEvaluation = vDescriptor.getTreeEvaluation(value.getParent(), context); if (parentEvaluation == null) { return null; } return DebuggerTreeNodeExpression.substituteThis( - vDescriptor.getRenderer(context.getDebugProcess()).getChildValueExpression(debuggerTreeNode, context), + vDescriptor.getRenderer(context.getDebugProcess()).getChildValueExpression(new DebuggerTreeNodeMock(value), context), parentEvaluation, vDescriptor.getValue() ); } @@ -383,6 +381,33 @@ public abstract class ValueDescriptorImpl extends NodeDescriptorImpl implements return getDescriptorEvaluation(context); } + private static class DebuggerTreeNodeMock implements DebuggerTreeNode { + private final JavaValue value; + + public DebuggerTreeNodeMock(JavaValue value) { + this.value = value; + } + + @Override + public DebuggerTreeNode getParent() { + return new DebuggerTreeNodeMock(value.getParent()); + } + + @Override + public ValueDescriptorImpl getDescriptor() { + return value.getDescriptor(); + } + + @Override + public Project getProject() { + return value.getProject(); + } + + @Override + public void setRenderer(NodeRenderer renderer) { + } + } + //returns expression that evaluates descriptor value //use 'this' to reference parent node //for ex. FieldDescriptorImpl should return diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java index 0825eb2c4c47..5553043b33d9 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/DebuggerTreeNode.java @@ -20,7 +20,7 @@ import com.intellij.debugger.ui.tree.render.NodeRenderer; import javax.swing.tree.MutableTreeNode; -public interface DebuggerTreeNode extends MutableTreeNode{ +public interface DebuggerTreeNode { DebuggerTreeNode getParent(); NodeDescriptor getDescriptor(); diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/actions/ShowAllAs.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/actions/ShowAllAs.java index 9e713a322851..ab1a0bdcc526 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/actions/ShowAllAs.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/actions/ShowAllAs.java @@ -20,6 +20,7 @@ import com.intellij.debugger.impl.DebuggerUtilsEx; import com.intellij.debugger.engine.DebuggerUtils; import com.intellij.debugger.engine.SuspendContext; import com.intellij.debugger.engine.managerThread.SuspendContextCommand; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.tree.DebuggerTreeNode; import com.intellij.debugger.ui.tree.ValueDescriptor; import com.intellij.debugger.ui.tree.render.NodeRenderer; @@ -65,7 +66,7 @@ public class ShowAllAs extends AnAction { } public void actionPerformed(AnActionEvent e) { - DebuggerTreeNode selectedNode = ((DebuggerUtilsEx)DebuggerUtils.getInstance()).getSelectedNode(e.getDataContext()); + DebuggerTreeNodeImpl selectedNode = (DebuggerTreeNodeImpl)((DebuggerUtilsEx)DebuggerUtils.getInstance()).getSelectedNode(e.getDataContext()); if(selectedNode == null) return; if(!isPrimitiveArray(selectedNode)) return; 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 54a2c6085b64..b97443b57ddd 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 @@ -123,6 +123,7 @@ public class ArrayRenderer extends NodeRendererImpl{ for (idx = start; idx <= end; idx++) { DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext); + if (arrayItemNode == null) continue; if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue; if(added >= (ENTRIES_LIMIT + 1)/ 2) break; children.add(arrayItemNode); @@ -135,6 +136,7 @@ public class ArrayRenderer extends NodeRendererImpl{ for (idx = end; idx >= start; idx--) { DebuggerTreeNode arrayItemNode = nodeManager.createNode(descriptorFactory.getArrayItemDescriptor(builder.getParentDescriptor(), array, idx), evaluationContext); + if (arrayItemNode == null) continue; if (ViewsGeneralSettings.getInstance().HIDE_NULL_ARRAY_ELEMENTS && ((ValueDescriptorImpl)arrayItemNode.getDescriptor()).isNull()) continue; if(added >= ENTRIES_LIMIT) break; childrenTail.add(arrayItemNode); @@ -168,12 +170,13 @@ public class ArrayRenderer extends NodeRendererImpl{ } } else { - if(START_INDEX > 0) { - children.add(0, nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); - } + //if(START_INDEX > 0) { + // children.add(0, nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + //} if(END_INDEX < array.length() - 1) { - children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + //children.add(nodeManager.createMessageNode(new MessageDescriptor(MORE_ELEMENTS, MessageDescriptor.SPECIAL))); + builder.setRemaining(array.length()-END_INDEX); } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java index 8a1f35893ac0..4a2b6f54b2f4 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/tree/render/ChildrenBuilder.java @@ -27,4 +27,6 @@ public interface ChildrenBuilder { ValueDescriptor getParentDescriptor(); void setChildren(List children); + + void setRemaining(int remaining); } diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java index 5df69039a726..69419f7ecf07 100644 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java +++ b/java/debugger/impl/src/org/jetbrains/java/debugger/JavaDebuggerEditorsProvider.java @@ -1,28 +1,31 @@ package org.jetbrains.java.debugger; -import com.intellij.debugger.engine.evaluation.CodeFragmentKind; +import com.intellij.debugger.engine.evaluation.CodeFragmentFactory; import com.intellij.debugger.engine.evaluation.TextWithImports; import com.intellij.debugger.engine.evaluation.TextWithImportsImpl; -import com.intellij.debugger.ui.DebuggerExpressionComboBox; +import com.intellij.debugger.impl.DebuggerUtilsEx; +import com.intellij.debugger.ui.DebuggerEditorImpl; import com.intellij.ide.highlighter.JavaFileType; +import com.intellij.lang.Language; +import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.JavaCodeFragmentFactory; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; +import com.intellij.psi.*; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; -import com.intellij.xdebugger.breakpoints.XBreakpoint; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; -import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProviderBase; -import com.intellij.xdebugger.impl.breakpoints.ui.XDebuggerComboBoxProvider; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import javax.swing.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; -public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase implements XDebuggerComboBoxProvider { +public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase { @NotNull @Override public FileType getFileType() { @@ -30,80 +33,60 @@ public class JavaDebuggerEditorsProvider extends XDebuggerEditorsProviderBase im } @Override - protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical) { + protected PsiFile createExpressionCodeFragment(@NotNull Project project, + @NotNull String text, + @Nullable PsiElement context, + boolean isPhysical) { return JavaCodeFragmentFactory.getInstance(project).createExpressionCodeFragment(text, context, null, isPhysical); } + @NotNull @Override - public XBreakpointCustomPropertiesPanel> createConditionComboBoxPanel(Project project, - XDebuggerEditorsProvider debuggerEditorsProvider, - String historyId, - XSourcePosition sourcePosition) { - return new ExpressionComboBoxPanel(project, historyId, sourcePosition) { - @Override - public void saveTo(@NotNull XBreakpoint breakpoint) { - TextWithImports text = myComboBox.getText(); - final String condition = !text.getText().isEmpty() ? text.toExternalForm() : null; - breakpoint.setCondition(condition); - if (condition != null) { - myComboBox.addRecent(text); - } + public Collection getSupportedLanguages(@NotNull Project project, @Nullable XSourcePosition sourcePosition) { + if (sourcePosition != null) { + PsiElement context = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project); + Collection res = new ArrayList(); + for (CodeFragmentFactory factory : DebuggerUtilsEx.getCodeFragmentFactories(context)) { + res.add(factory.getFileType().getLanguage()); } + return res; + } + return Collections.emptyList(); + } - @Override - public void loadFrom(@NotNull XBreakpoint breakpoint) { - myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getCondition()))); - } - }; + @NotNull + @Override + public XExpression createExpression(@NotNull Project project, @NotNull Document document, @Nullable Language language, @NotNull EvaluationMode mode) { + PsiDocumentManager.getInstance(project).commitDocument(document); + PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document); + if (psiFile != null) { + return new XExpressionImpl(psiFile.getText(), language, ((JavaCodeFragment)psiFile).importsToString(), mode); + } + return super.createExpression(project, document, language, mode); } @Override - public XBreakpointCustomPropertiesPanel> createLogExpressionComboBoxPanel(Project project, - XDebuggerEditorsProvider debuggerEditorsProvider, - String historyId, - XSourcePosition sourcePosition) { - return new ExpressionComboBoxPanel(project, historyId, sourcePosition) { - @Override - public void saveTo(@NotNull XBreakpoint breakpoint) { - TextWithImports text = myComboBox.getText(); - breakpoint.setLogExpression(myComboBox.isEnabled() && !text.getText().isEmpty() ? text.toExternalForm() : null); - if (text != null) { - myComboBox.addRecent(text); + protected PsiFile createExpressionCodeFragment(@NotNull Project project, + @NotNull XExpression expression, + @Nullable PsiElement context, + boolean isPhysical) { + TextWithImports text = TextWithImportsImpl.fromXExpression(expression); + if (text != null && context != null) { + CodeFragmentFactory factory = DebuggerEditorImpl.findAppropriateFactory(text, context); + JavaCodeFragment codeFragment = factory.createPresentationCodeFragment(text, context, project); + codeFragment.forceResolveScope(GlobalSearchScope.allScope(project)); + if (context != null) { + final PsiClass contextClass = PsiTreeUtil.getNonStrictParentOfType(context, PsiClass.class); + if (contextClass != null) { + final PsiClassType contextType = + JavaPsiFacade.getInstance(codeFragment.getProject()).getElementFactory().createType(contextClass); + codeFragment.setThisType(contextType); } } - - @Override - public void loadFrom(@NotNull XBreakpoint breakpoint) { - myComboBox.setText(new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, StringUtil.notNullize(breakpoint.getLogExpression()))); - } - }; - } - - private abstract class ExpressionComboBoxPanel extends XBreakpointCustomPropertiesPanel> { - protected final DebuggerExpressionComboBox myComboBox; - - private ExpressionComboBoxPanel(Project project, - String historyId, - XSourcePosition sourcePosition) { - myComboBox = new DebuggerExpressionComboBox(project, historyId); - if (sourcePosition != null) { - PsiElement element = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project); - myComboBox.setContext(element); - } - else { - myComboBox.setContext(null); - } + return codeFragment; } - - @NotNull - @Override - public JComponent getComponent() { - return myComboBox; - } - - @Override - public void dispose() { - myComboBox.dispose(); + else { + return super.createExpressionCodeFragment(project, expression, context, isPhysical); } } -} \ No newline at end of file +} diff --git a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java b/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java deleted file mode 100644 index 15cb3c471029..000000000000 --- a/java/debugger/impl/src/org/jetbrains/java/debugger/breakpoints/JavaBreakpointAdapterBase.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.jetbrains.java.debugger.breakpoints; - -import com.intellij.debugger.ui.breakpoints.LineBreakpoint; -import com.intellij.openapi.editor.Document; -import com.intellij.openapi.fileEditor.FileDocumentManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; -import com.intellij.xdebugger.breakpoints.XBreakpointAdapter; -import com.intellij.xdebugger.breakpoints.XBreakpointProperties; -import com.intellij.xdebugger.breakpoints.XLineBreakpoint; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -public abstract class JavaBreakpointAdapterBase extends XBreakpointAdapter> { - protected final Project myProject; - - public JavaBreakpointAdapterBase(Project project) { - myProject = project; - } - - @Nullable - public LineBreakpoint createBreakpoint(XLineBreakpoint breakpoint) { - String url = breakpoint.getFileUrl(); - VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url); - Document document = file != null ? FileDocumentManager.getInstance().getDocument(file) : null; - if (document == null) { - return null; - } - LineBreakpoint jBreakpoint = createInvisibleBreakpoint(myProject, document, breakpoint); - configureCreatedBreakpoint(jBreakpoint, breakpoint); - return jBreakpoint; - } - - protected void configureCreatedBreakpoint(LineBreakpoint oldBreakpoint, XLineBreakpoint breakpoint) { - } - - @Override - public final void breakpointChanged(@NotNull XLineBreakpoint breakpoint) { - LineBreakpoint jBreakpoint = findBreakpoint(breakpoint); - if (jBreakpoint != null) { - updateBreakpoint(jBreakpoint, breakpoint); - } - } - - protected abstract void updateBreakpoint(LineBreakpoint oldBreakpoint, XLineBreakpoint breakpoint); - - protected abstract LineBreakpoint findBreakpoint(XLineBreakpoint breakpoint); - - protected LineBreakpoint createInvisibleBreakpoint(Project project, Document document, XLineBreakpoint breakpoint) { - LineBreakpoint oldBreakpoint = doCreateInstance(project, document, breakpoint); - oldBreakpoint.setVisible(false); - oldBreakpoint.updateUI(); - oldBreakpoint.setEnabled(breakpoint.isEnabled()); - return oldBreakpoint; - } - - protected LineBreakpoint doCreateInstance(Project project, Document document, XLineBreakpoint xBreakpoint) { - return LineBreakpoint.create(project, xBreakpoint); - } -} diff --git a/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java b/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java index e75432a184eb..8b92f56390c3 100644 --- a/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java +++ b/java/idea-ui/src/com/intellij/jarFinder/InternetAttachSourceProvider.java @@ -218,6 +218,7 @@ public class InternetAttachSourceProvider implements AttachSourcesProvider { private static boolean isRootInExistingFile(VirtualFile root) { if (root.getFileSystem() instanceof JarFileSystem) { VirtualFile jar = JarFileSystem.getInstance().getVirtualFileForJar(root); + // we might be invoked outside EDT, so sync VFS refresh is impossible, so we check java.io.File existence if (jar == null || !VfsUtilCore.virtualToIoFile(jar).exists()) return false; } diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java index 2669e518c74d..75126caa4776 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateFromUsageUtils.java @@ -157,7 +157,7 @@ public class CreateFromUsageUtils { throw e; } catch (Exception e) { - throw new IncorrectOperationException("Failed to parse file template",e); + throw new IncorrectOperationException("Failed to parse file template", (Throwable)e); } if (methodText != null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 9b5b37f6c0ec..d8df67367790 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -382,8 +382,9 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil { try { methodText = "void foo () {\n" + template.getText(properties) + "\n}"; methodText = FileTemplateUtil.indent(methodText, result.getProject(), fileType); - } catch (Exception e) { - throw new IncorrectOperationException("Failed to parse file template",e); + } + catch (Exception e) { + throw new IncorrectOperationException("Failed to parse file template", (Throwable)e); } if (methodText != null) { PsiMethod m; diff --git a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java index 239fbb645f72..be9405ee4754 100644 --- a/java/java-impl/src/com/intellij/ide/util/PackageUtil.java +++ b/java/java-impl/src/com/intellij/ide/util/PackageUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -253,11 +253,11 @@ public class PackageUtil { } }); } - catch(IncorrectOperationException e) { + catch (IncorrectOperationException e) { throw e; } - catch(IOException e) { - throw new IncorrectOperationException(e.toString(), e); + catch (IOException e) { + throw new IncorrectOperationException(e); } catch (Exception e) { LOG.error(e); diff --git a/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java b/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java index 21280eeeaa55..58476c6fc799 100644 --- a/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java +++ b/java/java-impl/src/com/intellij/psi/impl/JavaPsiImplementationHelperImpl.java @@ -258,7 +258,7 @@ public class JavaPsiImplementationHelperImpl extends JavaPsiImplementationHelper throw ce; } catch (Exception e) { - throw new IncorrectOperationException("Incorrect file template", e); + throw new IncorrectOperationException("Incorrect file template", (Throwable)e); } catchSection.getCatchBlock().replace(codeBlockFromText); } diff --git a/java/java-impl/src/com/intellij/psi/util/CreateClassUtil.java b/java/java-impl/src/com/intellij/psi/util/CreateClassUtil.java index 5d19b4d40c65..29feaf2776ee 100644 --- a/java/java-impl/src/com/intellij/psi/util/CreateClassUtil.java +++ b/java/java-impl/src/com/intellij/psi/util/CreateClassUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -89,7 +89,7 @@ public class CreateClassUtil { return (PsiClass)JavaCodeStyleManager.getInstance(project).shortenClassReferences(aClass); } catch (IOException e) { - throw new IncorrectOperationException(e.toString(), e); + throw new IncorrectOperationException(e); } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java index 05819c471a27..2ededda029f8 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiJavaParserFacadeImpl.java @@ -168,7 +168,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ANNOTATION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiAnnotation)) { - throw new IncorrectOperationException("Incorrect annotation \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect annotation '" + text + "'"); } return (PsiAnnotation)element; } @@ -194,7 +194,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final PsiJavaFile aFile = createDummyJavaFile(StringUtil.join("class _Dummy_ {\n", body, "\n}")); final PsiClass[] classes = aFile.getClasses(); if (classes.length != 1) { - throw new IncorrectOperationException("Incorrect class \"" + body + "\"."); + throw new IncorrectOperationException("Incorrect class '" + body + "'"); } return classes[0]; } @@ -205,7 +205,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiField)) { - throw new IncorrectOperationException("Incorrect field \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect field '" + text + "'"); } return (PsiField)element; } @@ -216,7 +216,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, DECLARATION, level), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiMethod)) { - throw newException("Incorrect method \"" + text + "\".", holder); + throw newException("Incorrect method '" + text + "'", holder); } return (PsiMethod)element; } @@ -234,7 +234,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, PARAMETER, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiParameter)) { - throw new IncorrectOperationException("Incorrect parameter \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect parameter '" + text + "'"); } return (PsiParameter)element; } @@ -245,7 +245,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, RESOURCE, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiResourceVariable)) { - throw new IncorrectOperationException("Incorrect resource \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect resource '" + text + "'"); } return (PsiResourceVariable)element; } @@ -259,10 +259,11 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { @NotNull @Override public PsiTypeElement createTypeElementFromText(@NotNull final String text, @Nullable final PsiElement context) throws IncorrectOperationException { - final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, level(context)), context); + final LanguageLevel level = level(context); + final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, TYPE, level), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiTypeElement)) { - throw new IncorrectOperationException("Incorrect type \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect type '" + text + "' (" + level + ")"); } return (PsiTypeElement)element; } @@ -289,7 +290,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, wrapper, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiJavaCodeReferenceElement)) { - throw new IncorrectOperationException("Incorrect reference \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect reference '" + text + "'"); } return (PsiJavaCodeReferenceElement)element; } @@ -300,7 +301,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, CODE_BLOCK, level(context), true), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiCodeBlock)) { - throw new IncorrectOperationException("Incorrect code block \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect code block '" + text + "'"); } return (PsiCodeBlock)element; } @@ -311,7 +312,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, STATEMENT, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiStatement)) { - throw new IncorrectOperationException("Incorrect statement \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect statement '" + text + "'"); } return (PsiStatement)element; } @@ -322,7 +323,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, EXPRESSION, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiExpression)) { - throw new IncorrectOperationException("Incorrect expression \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect expression '" + text + "'"); } return (PsiExpression)element; } @@ -339,7 +340,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiTypeParameter)) { - throw new IncorrectOperationException("Incorrect type parameter \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect type parameter '" + text + "'"); } return (PsiTypeParameter)element; } @@ -359,7 +360,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { } } - throw new IncorrectOperationException("Incorrect comment \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect comment '" + text + "'"); } @NotNull @@ -368,7 +369,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { final DummyHolder holder = DummyHolderFactory.createHolder(myManager, new JavaDummyElement(text, ENUM_CONSTANT, level(context)), context); final PsiElement element = SourceTreeToPsiMap.treeElementToPsi(holder.getTreeElement().getFirstChildNode()); if (!(element instanceof PsiEnumConstant)) { - throw new IncorrectOperationException("Incorrect enum constant \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect enum constant '" + text + "'"); } return (PsiEnumConstant)element; } @@ -378,7 +379,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { public PsiType createPrimitiveType(@NotNull final String text, @NotNull final PsiAnnotation[] annotations) throws IncorrectOperationException { final PsiPrimitiveType primitiveType = getPrimitiveType(text); if (primitiveType == null) { - throw new IncorrectOperationException("Incorrect primitive type \"" + text + "\"."); + throw new IncorrectOperationException("Incorrect primitive type '" + text + "'"); } return annotations.length == 0 ? primitiveType : new PsiPrimitiveType(text, annotations); } @@ -396,9 +397,7 @@ public class PsiJavaParserFacadeImpl implements PsiJavaParserFacade { if (root instanceof JavaDummyElement) { final Throwable cause = ((JavaDummyElement)root).getParserError(); if (cause != null) { - return new IncorrectOperationException(msg) { - @Override public Throwable getCause() { return cause; } - }; + return new IncorrectOperationException(msg, cause); } } return new IncorrectOperationException(msg); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index 994495a6444d..60cb54cefe6b 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -588,8 +588,8 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme text += parameterList.getText(); } PsiJavaCodeReferenceElement ref = facade.getParserFacade().createReferenceFromText(text, getParent()); - getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); ((PsiJavaCodeReferenceElementImpl)ref).setAnnotations(annotations); + getTreeParent().replaceChildInternal(this, (TreeElement)ref.getNode()); if (!preserveQualification) { JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(project); diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java index da51b193c508..9daab3ff8300 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceSession.java @@ -74,7 +74,7 @@ public class InferenceSession { for (int i = 0; i < leftTypes.length; i++) { final PsiType rightType = mySiteSubstitutor.substitute(rightTypes[i]); if (rightType != null) { - myConstraints.add(new TypeCompatibilityConstraint(leftTypes[i], rightType)); + addConstraint(new TypeCompatibilityConstraint(leftTypes[i], rightType)); } } } @@ -115,7 +115,7 @@ public class InferenceSession { for (int i = 0; i < args.length; i++) { if (args[i] != null && isPertinentToApplicability(args[i], method)) { PsiType parameterType = getParameterType(parameters, i, mySiteSubstitutor, varargs); - myConstraints.add(new ExpressionCompatibilityConstraint(args[i], parameterType)); + addConstraint(new ExpressionCompatibilityConstraint(args[i], parameterType)); } } } @@ -399,7 +399,7 @@ public class InferenceSession { final PsiSubstitutor substitutor = resolveSubset(Collections.singletonList(inferenceVariable), mySiteSubstitutor); final PsiType substitutedReturnType = substitutor.substitute(inferenceVariable.getParameter()); if (substitutedReturnType != null) { - myConstraints.add(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutedReturnType, myContext))); + addConstraint(new TypeCompatibilityConstraint(targetType, PsiUtil.captureToplevelWildcards(substitutedReturnType, myContext))); } } else { @@ -420,10 +420,10 @@ public class InferenceSession { } final PsiType substitutedCapture = PsiUtil.captureToplevelWildcards(subst.substitute(returnType), myContext); myIncorporationPhase.addCapture(copy, (PsiClassType)returnType); - myConstraints.add(new TypeCompatibilityConstraint(targetType, substitutedCapture)); + addConstraint(new TypeCompatibilityConstraint(targetType, substitutedCapture)); } } else { - myConstraints.add(new TypeCompatibilityConstraint(targetType, myErased ? TypeConversionUtil.erasure(returnType) : returnType)); + addConstraint(new TypeCompatibilityConstraint(targetType, myErased ? TypeConversionUtil.erasure(returnType) : returnType)); } } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java index 13497e3d4557..a606e90e8a98 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/graphInference/InferenceVariable.java @@ -15,27 +15,30 @@ */ package com.intellij.psi.impl.source.resolve.graphInference; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiType; import com.intellij.psi.PsiTypeParameter; +import com.intellij.psi.impl.light.LightTypeParameter; import java.util.*; /** * User: anna */ -public class InferenceVariable { +public class InferenceVariable extends LightTypeParameter { public PsiTypeParameter getParameter() { - return myParameter; + return getDelegate(); } private boolean myThrownBound = false; private final Map> myBounds = new HashMap>(); - private final PsiTypeParameter myParameter; private PsiType myInstantiation = PsiType.NULL; - public InferenceVariable(PsiTypeParameter parameter) { - myParameter = parameter; + + InferenceVariable(PsiTypeParameter parameter) { + super(parameter); } + public PsiType getInstantiation() { return myInstantiation; } @@ -117,12 +120,13 @@ public class InferenceVariable { myThrownBound = true; } - public void replaceBounds(InferenceBound boundType, LinkedHashSet bounds) { - + @Override + public boolean isEquivalentTo(PsiElement another) { + return this == another || getDelegate() == another; } @Override public String toString() { - return myParameter.toString(); + return getDelegate().toString(); } } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterTypeAnno.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterTypeAnno.java new file mode 100644 index 000000000000..0d325f03ffba --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/afterTypeAnno.java @@ -0,0 +1,7 @@ +// "Add 'String' as 2nd parameter to method 'f'" "true" +import java.util.List; + public class S { + void f(List<@Anno String> args, String s) { + f(null, ""); + } + } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeTypeAnno.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeTypeAnno.java new file mode 100644 index 000000000000..3940a78552a6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8/beforeTypeAnno.java @@ -0,0 +1,7 @@ +// "Add 'String' as 2nd parameter to method 'f'" "true" +import java.util.List; + public class S { + void f(List<@Anno String> args) { + f(null, ""); + } + } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java new file mode 100644 index 000000000000..fbc121e1a2e2 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/ChangeMethodSignatureFromUsage8Test.java @@ -0,0 +1,33 @@ +/* + * 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.codeInsight.daemon.quickFix; + +import com.intellij.pom.java.LanguageLevel; + +public class ChangeMethodSignatureFromUsage8Test extends LightQuickFixParameterizedTestCase { + + public void test() throws Exception { doAllTests(); } + + @Override + protected String getBasePath() { + return "/codeInsight/daemonCodeAnalyzer/quickFix/changeMethodSignatureFromUsage8"; + } + + @Override + protected LanguageLevel getLanguageLevel() { + return LanguageLevel.JDK_1_8; + } +} diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy index 68efd487fe89..244dbb5d69dd 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy +++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameSuggestionsTest.groovy @@ -63,7 +63,7 @@ class RenameSuggestionsTest extends LightCodeInsightTestCase { return IdeaTestUtil.getMockJdk18() } - public void "test by Optional.of initializer"() { + public void "test by Optional_of initializer"() { def suggestions = getNameSuggestions(""" import java.util.*; class Foo {{ @@ -74,7 +74,7 @@ class Foo {{ assert suggestions == ["typeValue1", "value", "foo", "fooOptional", "optional", "o"] } - public void "test by Optional.ofNullable initializer"() { + public void "test by Optional_ofNullable initializer"() { def suggestions = getNameSuggestions(""" import java.util.*; class Foo {{ @@ -85,7 +85,7 @@ class Foo {{ assert suggestions == ["typeValue1", "value", "foo", "fooOptional", "optional", "o"] } - public void "test by Optional.of initializer with constructor"() { + public void "test by Optional_of initializer with constructor"() { def suggestions = getNameSuggestions(""" import java.util.*; class Foo {{ @@ -95,7 +95,7 @@ class Foo {{ assert suggestions == ["foo", "fooOptional", "optional", "o"] } - public void "test by Optional.flatMap"() { + public void "test by Optional_flatMap"() { def suggestions = getNameSuggestions(""" import java.util.*; class Foo {{ diff --git a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java index a04d8f3df382..63216ec0e7cd 100644 --- a/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/DebuggerTestCase.java @@ -16,6 +16,7 @@ package com.intellij.debugger; import com.intellij.debugger.engine.DebugProcessImpl; +import com.intellij.debugger.engine.JavaDebugProcess; import com.intellij.debugger.engine.RemoteStateState; import com.intellij.debugger.engine.SuspendContextImpl; import com.intellij.debugger.engine.evaluation.EvaluateException; @@ -35,6 +36,7 @@ import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.ExecutionEnvironmentBuilder; import com.intellij.execution.runners.ProgramRunner; import com.intellij.execution.ui.ExecutionConsole; import com.intellij.openapi.application.ApplicationManager; @@ -51,6 +53,10 @@ import com.intellij.psi.PsiClass; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.ui.UIUtil; +import com.intellij.xdebugger.XDebugProcess; +import com.intellij.xdebugger.XDebugProcessStarter; +import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XDebuggerManager; import org.jdom.Element; import org.jetbrains.annotations.NotNull; @@ -136,8 +142,10 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas final RemoteConnection debugParameters = DebuggerManagerImpl.createDebugParameters(javaParameters, debuggerRunnerSettings, false); - ExecutionEnvironment environment = new ExecutionEnvironment(new MockConfiguration(), DefaultDebugExecutor.getDebugExecutorInstance(), - myProject, debuggerRunnerSettings); + ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(myProject, DefaultDebugExecutor.getDebugExecutorInstance()) + .setRunnerSettings(debuggerRunnerSettings) + .setRunProfile(new MockConfiguration()) + .build(); final JavaCommandLineState javaCommandLineState = new JavaCommandLineState(environment){ @Override protected JavaParameters createJavaParameters() { @@ -150,14 +158,20 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas } }; - final GenericDebuggerRunner runner = new GenericDebuggerRunner(); - ApplicationManager.getApplication().invokeAndWait(new Runnable() { @Override public void run() { try { + GenericDebuggerRunner runner = new GenericDebuggerRunner(); myDebuggerSession = DebuggerManagerEx.getInstanceEx(myProject).attachVirtualMachine(DefaultDebugExecutor.getDebugExecutorInstance(), runner, new MockConfiguration(), javaCommandLineState, debugParameters, false); + XDebuggerManager.getInstance(myProject).startSession(runner, javaCommandLineState.getEnvironment(), null, new XDebugProcessStarter() { + @Override + @NotNull + public XDebugProcess start(@NotNull XDebugSession session) { + return new JavaDebugProcess(session, myDebuggerSession); + } + }); } catch (ExecutionException e) { LOG.error(e); @@ -193,8 +207,10 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas debuggerRunnerSettings.LOCAL = true; debuggerRunnerSettings.DEBUG_PORT = "3456"; - ExecutionEnvironment environment = new ExecutionEnvironment(new MockConfiguration(), DefaultDebugExecutor.getDebugExecutorInstance(), myProject, - debuggerRunnerSettings); + ExecutionEnvironment environment = new ExecutionEnvironmentBuilder(myProject, DefaultDebugExecutor.getDebugExecutorInstance()) + .setRunnerSettings(debuggerRunnerSettings) + .setRunProfile(new MockConfiguration()) + .build(); final JavaCommandLineState javaCommandLineState = new JavaCommandLineState(environment) { @Override protected JavaParameters createJavaParameters() { @@ -214,7 +230,15 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override public void run() { try { - debuggerSession[0] = attachVirtualMachine(javaCommandLineState, debugParameters, false); + GenericDebuggerRunner runner = new GenericDebuggerRunner(); + debuggerSession[0] = attachVirtualMachine(runner, javaCommandLineState, debugParameters, false); + XDebuggerManager.getInstance(myProject).startSession(runner, javaCommandLineState.getEnvironment(), null, new XDebugProcessStarter() { + @Override + @NotNull + public XDebugProcess start(@NotNull XDebugSession session) { + return new JavaDebugProcess(session, debuggerSession[0]); + } + }); } catch (ExecutionException e) { fail(e.getMessage()); @@ -293,7 +317,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override public void run() { try { - debuggerSession[0] = attachVirtualMachine(remoteState, remoteConnection, pollConnection); + debuggerSession[0] = attachVirtualMachine(new GenericDebuggerRunner(), remoteState, remoteConnection, pollConnection); } catch (ExecutionException e) { fail(e.getMessage()); @@ -445,10 +469,9 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas return myDebuggerSession; } - protected DebuggerSession attachVirtualMachine(RunProfileState state, RemoteConnection remoteConnection, boolean pollConnection) throws ExecutionException { + protected DebuggerSession attachVirtualMachine(ProgramRunner runner, RunProfileState state, RemoteConnection remoteConnection, boolean pollConnection) throws ExecutionException { return DebuggerManagerEx.getInstanceEx(myProject).attachVirtualMachine(DefaultDebugExecutor.getDebugExecutorInstance(), - new GenericDebuggerRunner(), - new MockConfiguration(), state, remoteConnection, pollConnection); + runner, new MockConfiguration(), state, remoteConnection, pollConnection); } private static class MockConfiguration implements ModuleRunConfiguration { @@ -517,7 +540,7 @@ public abstract class DebuggerTestCase extends ExecutionWithDebuggerToolsTestCas @Override public String getName() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return ""; //To change body of implemented methods use File | Settings | File Templates. } @Override diff --git a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java index d7dfea857ba9..f295ee6dd40e 100644 --- a/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/ExecutionWithDebuggerToolsTestCase.java @@ -294,19 +294,29 @@ public abstract class ExecutionWithDebuggerToolsTestCase extends ExecutionTestCa if (comment.indexOf("Method") != -1) { breakpoint = breakpointManager.addMethodBreakpoint(document, commentLine + 1); - println("MethodBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + if (breakpoint != null) { + println("MethodBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), + ProcessOutputTypes.SYSTEM); + } } else if (comment.indexOf("Field") != -1) { breakpoint = breakpointManager.addFieldBreakpoint(document, commentLine + 1, readValue(comment, "Field")); - println("FieldBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + if (breakpoint != null) { + println("FieldBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + } } else if (comment.indexOf("Exception") != -1) { breakpoint = breakpointManager.addExceptionBreakpoint(readValue(comment, "Exception"), ""); - println("ExceptionBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + if (breakpoint != null) { + println("ExceptionBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), + ProcessOutputTypes.SYSTEM); + } } else { breakpoint = breakpointManager.addLineBreakpoint(document, commentLine + 1); - println("LineBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + if (breakpoint != null) { + println("LineBreakpoint created at " + file.getVirtualFile().getName() + ":" + (commentLine + 2), ProcessOutputTypes.SYSTEM); + } } String suspendPolicy = readValue(comment, "suspendPolicy"); diff --git a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java index a3ad0c55ceab..db072f4ce97a 100644 --- a/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java +++ b/java/testFramework/src/com/intellij/debugger/impl/DescriptorTestCase.java @@ -24,6 +24,7 @@ import com.intellij.debugger.engine.events.SuspendContextCommandImpl; import com.intellij.debugger.engine.jdi.StackFrameProxy; import com.intellij.debugger.settings.NodeRendererSettings; import com.intellij.debugger.ui.impl.watch.DebuggerTree; +import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl; import com.intellij.debugger.ui.impl.watch.LocalVariableDescriptorImpl; import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl; import com.intellij.debugger.ui.tree.DebuggerTreeNode; @@ -176,7 +177,7 @@ public abstract class DescriptorTestCase extends DebuggerTestCase { public void run() { boolean anyCollapsed = false; for(int i = 0; i < tree.getRowCount(); i++) { - final DebuggerTreeNode treeNode = (DebuggerTreeNode)tree.getPathForRow(i).getLastPathComponent(); + final DebuggerTreeNodeImpl treeNode = (DebuggerTreeNodeImpl)tree.getPathForRow(i).getLastPathComponent(); if(tree.isCollapsed(i) && !treeNode.isLeaf()) { final NodeDescriptor nodeDescriptor = treeNode.getDescriptor(); boolean shouldExpand = filter == null || filter.shouldExpand(treeNode); diff --git a/platform/core-impl/src/com/intellij/indentation/IndentationParser.java b/platform/core-impl/src/com/intellij/indentation/IndentationParser.java index dc46db89f5f6..159a34bf7519 100644 --- a/platform/core-impl/src/com/intellij/indentation/IndentationParser.java +++ b/platform/core-impl/src/com/intellij/indentation/IndentationParser.java @@ -23,6 +23,9 @@ import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.ArrayList; +import java.util.List; + /** * @author oleg */ @@ -35,6 +38,21 @@ public abstract class IndentationParser implements PsiParser { private final IElementType myBlockElementType; @NotNull private final IElementType myDocumentType; + private final List myContainerTypes; + + public IndentationParser( + @NotNull IElementType documentType, + @NotNull final IElementType blockElementType, + @NotNull final IElementType eolTokenType, + @NotNull final IElementType indentTokenType, + final List containerTypes) + { + myDocumentType = documentType; + myBlockElementType = blockElementType; + myEolTokenType = eolTokenType; + myIndentTokenType = indentTokenType; + myContainerTypes = containerTypes; + } public IndentationParser( @NotNull IElementType documentType, @@ -42,18 +60,21 @@ public abstract class IndentationParser implements PsiParser { @NotNull final IElementType eolTokenType, @NotNull final IElementType indentTokenType) { - myDocumentType = documentType; - myBlockElementType = blockElementType; - myEolTokenType = eolTokenType; - myIndentTokenType = indentTokenType; + this(documentType, blockElementType, eolTokenType, indentTokenType, null); } @Override @NotNull public final ASTNode parse(final IElementType root, final PsiBuilder builder) { final PsiBuilder.Marker fileMarker = builder.mark(); + final ArrayList containerMarkers = new ArrayList(); + if (myContainerTypes != null) { + for (IElementType ignored : myContainerTypes) { + final PsiBuilder.Marker containerMarker = builder.mark(); + containerMarkers.add(containerMarker); + } + } final PsiBuilder.Marker documentMarker = builder.mark(); - while (builder.getTokenType() == myEolTokenType) { advanceLexer(builder); } @@ -125,6 +146,14 @@ public abstract class IndentationParser implements PsiParser { } documentMarker.done(myDocumentType); + + if (myContainerTypes != null) { + for (int i = containerMarkers.size() - 1; i >= 0; i--) { + final PsiBuilder.Marker marker = containerMarkers.get(i); + marker.done(myContainerTypes.get(i)); + } + } + fileMarker.done(root); return builder.getTreeBuilt(); } diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java index 479ff3d6670c..edf8fdda95f5 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiDirectoryImpl.java @@ -411,7 +411,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu return copyPsi; } catch (IOException e) { - throw new IncorrectOperationException(e.toString(), e); + throw new IncorrectOperationException(e); } } @@ -489,7 +489,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu return newFile; } catch (IOException e) { - throw new IncorrectOperationException(e.toString(), e); + throw new IncorrectOperationException(e); } } else { @@ -550,7 +550,7 @@ public class PsiDirectoryImpl extends PsiElementBase implements PsiDirectory, Qu myFile.delete(myManager); } catch (IOException e) { - throw new IncorrectOperationException(e.toString(), e); + throw new IncorrectOperationException(e); } /* diff --git a/platform/core-impl/src/com/intellij/psi/impl/file/PsiFileImplUtil.java b/platform/core-impl/src/com/intellij/psi/impl/file/PsiFileImplUtil.java index 42f0857eb21a..5c6a489e3239 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/file/PsiFileImplUtil.java +++ b/platform/core-impl/src/com/intellij/psi/impl/file/PsiFileImplUtil.java @@ -51,7 +51,7 @@ public class PsiFileImplUtil { vFile.rename(manager, newName); } catch(IOException e){ - throw new IncorrectOperationException(e.toString(),e); + throw new IncorrectOperationException(e); } return file.getViewProvider().isPhysical() ? manager.findFile(vFile) : file; @@ -75,7 +75,7 @@ public class PsiFileImplUtil { vFile.delete(manager); } catch(IOException e){ - throw new IncorrectOperationException(e.toString(),e); + throw new IncorrectOperationException(e); } } } diff --git a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java index 859a6046957f..b3498f317a54 100644 --- a/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java +++ b/platform/core-impl/src/com/intellij/psi/impl/source/resolve/ResolveCache.java @@ -100,7 +100,7 @@ public class ResolveCache { Getter reference = map.get(ref); TResult result = reference == null ? null : reference.get(); if (result != null) { - return result; + //return result; } RecursionGuard.StackStamp stamp = myGuard.markStack(); diff --git a/platform/icons/src/general/macCorner@2x_dark.png b/platform/icons/src/general/macCorner@2x_dark.png index 27f8afbd5209..c9c9f7955529 100644 Binary files a/platform/icons/src/general/macCorner@2x_dark.png and b/platform/icons/src/general/macCorner@2x_dark.png differ diff --git a/platform/icons/src/general/macCorner_dark.png b/platform/icons/src/general/macCorner_dark.png index 54ccf637c6ba..07b6b5e8cdda 100644 Binary files a/platform/icons/src/general/macCorner_dark.png and b/platform/icons/src/general/macCorner_dark.png differ diff --git a/platform/lang-api/src/com/intellij/execution/RunManager.java b/platform/lang-api/src/com/intellij/execution/RunManager.java index 674d74ab3861..c63a4bd575ec 100644 --- a/platform/lang-api/src/com/intellij/execution/RunManager.java +++ b/platform/lang-api/src/com/intellij/execution/RunManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -217,7 +217,8 @@ public abstract class RunManager { */ public abstract void refreshUsagesList(RunProfile profile); - public static String suggestUniqueName(String str, ArrayList currentNames) { + @NotNull + public static String suggestUniqueName(@NotNull String str, @NotNull Collection currentNames) { if (!currentNames.contains(str)) return str; final Matcher matcher = Pattern.compile("(.*?)\\s*\\(\\d+\\)").matcher(str); diff --git a/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java b/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java index fc590c486c5b..adfc58956d2a 100644 --- a/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java +++ b/platform/lang-api/src/com/intellij/execution/actions/RunConfigurationProducer.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -145,15 +145,18 @@ public abstract class RunConfigurationProducer { final RunManager runManager = RunManager.getInstance(context.getProject()); final ConfigurationType type = fromContext.getConfigurationType(); final List configurations = runManager.getConfigurationSettingsList(type); - final RunnerAndConfigurationSettings configuration = findExistingConfiguration(context); - if (configuration != null) { - fromContext.setConfigurationSettings(configuration); + final RunnerAndConfigurationSettings settings = findExistingConfiguration(context); + if (settings != null) { + fromContext.setConfigurationSettings(settings); } else { final ArrayList currentNames = new ArrayList(); for (RunnerAndConfigurationSettings configurationSettings : configurations) { currentNames.add(configurationSettings.getName()); } - fromContext.getConfiguration().setName(RunManager.suggestUniqueName(fromContext.getConfiguration().getName(), currentNames)); + RunConfiguration configuration = fromContext.getConfiguration(); + String name = configuration.getName(); + assert name != null : configuration; + configuration.setName(RunManager.suggestUniqueName(name, currentNames)); } } } diff --git a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java index 60ab050fe9be..99766cab33e0 100644 --- a/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/impl/ExecutionManagerImpl.java @@ -224,7 +224,9 @@ public class ExecutionManagerImpl extends ExecutionManager implements ProjectCom ExecutionManager.getInstance(project).getContentManager().showRunContent(executor, descriptor, reuseContent); final ProcessHandler processHandler = descriptor.getProcessHandler(); if (processHandler != null) { - processHandler.startNotify(); + if (!processHandler.isStartNotified()) { + processHandler.startNotify(); + } project.getMessageBus().syncPublisher(EXECUTION_TOPIC).processStarted(executor.getId(), env, processHandler); started = true; processHandler.addProcessListener(new ProcessExecutionListener(project, profile, processHandler)); diff --git a/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java b/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java index 30d4933cbcb4..7fbde2d02ee4 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java +++ b/platform/lang-impl/src/com/intellij/ide/util/PlatformPackageUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,7 +166,7 @@ public class PlatformPackageUtil { throw e; } catch (IOException e) { - throw new IncorrectOperationException(e.toString(), e); + throw new IncorrectOperationException(e); } catch (Exception e) { LOG.error(e); diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java index 051368b8f1ae..c2bdeba4baf0 100644 --- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java +++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoActionModel.java @@ -170,7 +170,7 @@ public class GotoActionModel implements ChooseByNameModel, CustomMatcherModel, C final Color fg = defaultActionForeground(isSelected, presentation); - final JLabel actionLabel = createActionLabel(anAction, templatePresentation.getText() + "::" + actionWithParentGroup.getMode(), fg, bg, icon); + final JLabel actionLabel = createActionLabel(anAction, templatePresentation.getText(), fg, bg, icon); panel.add(actionLabel, BorderLayout.WEST); final String groupName = actionWithParentGroup.getGroupName(); diff --git a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java index e8b1880b400c..885ce5b07214 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java +++ b/platform/lang-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/MoveFilesOrDirectoriesUtil.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -63,7 +63,7 @@ public class MoveFilesOrDirectoriesUtil { aDirectory.getVirtualFile().move(manager, destDirectory.getVirtualFile()); } catch (IOException e) { - throw new IncorrectOperationException(e.toString(),e); + throw new IncorrectOperationException(e); } } @@ -87,7 +87,7 @@ public class MoveFilesOrDirectoriesUtil { virtualFile.move(manager, newDirectory.getVirtualFile()); } catch (IOException e) { - throw new IncorrectOperationException(e.toString(),e); + throw new IncorrectOperationException(e); } } } diff --git a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java index 176ffd90c17f..602615a656e2 100644 --- a/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java +++ b/platform/platform-api/src/com/intellij/openapi/ui/ComponentWithBrowseButton.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,6 +20,7 @@ import com.intellij.openapi.actionSystem.AnActionEvent; import com.intellij.openapi.actionSystem.CustomShortcutSet; import com.intellij.openapi.actionSystem.ShortcutSet; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.fileChooser.FileChooser; import com.intellij.openapi.fileChooser.FileChooserDescriptor; import com.intellij.openapi.keymap.KeymapUtil; @@ -47,6 +48,8 @@ import java.awt.event.InputEvent; import java.awt.event.KeyEvent; public class ComponentWithBrowseButton extends JPanel implements Disposable { + private static final Logger LOG = Logger.getInstance(ComponentWithBrowseButton.class); + private final Comp myComponent; private final FixedSizeButton myBrowseButton; private boolean myButtonEnabled = true; @@ -153,8 +156,7 @@ public class ComponentWithBrowseButton extends JPanel i } @Override - public void dispose() { - } + public void dispose() { } public FixedSizeButton getButton() { return myBrowseButton; @@ -193,7 +195,22 @@ public class ComponentWithBrowseButton extends JPanel i private Project myProject; protected final FileChooserDescriptor myFileChooserDescriptor; - public BrowseFolderActionListener(@Nullable String title, @Nullable String description, ComponentWithBrowseButton textField, @Nullable Project project, FileChooserDescriptor fileChooserDescriptor, TextComponentAccessor accessor) { + public BrowseFolderActionListener(@Nullable String title, + @Nullable String description, + ComponentWithBrowseButton textField, + @Nullable Project project, + FileChooserDescriptor fileChooserDescriptor, + TextComponentAccessor accessor) { + if (fileChooserDescriptor != null && fileChooserDescriptor.isChooseMultiple()) { + LOG.error("multiple selection not supported"); + fileChooserDescriptor = new FileChooserDescriptor(fileChooserDescriptor) { + @Override + public boolean isChooseMultiple() { + return false; + } + }; + } + myTitle = title; myDescription = description; myTextComponent = textField; @@ -227,7 +244,7 @@ public class ComponentWithBrowseButton extends JPanel i FileChooser.chooseFile(fileChooserDescriptor, getProject(), getInitialFile(), new Consumer() { @Override public void consume(VirtualFile file) { - onFileChoosen(file); + onFileChosen(file); } }); } @@ -264,9 +281,16 @@ public class ComponentWithBrowseButton extends JPanel i return chosenFile.getPresentableUrl(); } + /** @deprecated use/override {@link #onFileChosen(VirtualFile)} (to be removed in IDEA 15) */ + @SuppressWarnings("SpellCheckingInspection") protected void onFileChoosen(@NotNull VirtualFile chosenFile) { myAccessor.setText(myTextComponent.getChildComponent(), chosenFileToResultingText(chosenFile)); } + + @SuppressWarnings("deprecation") + protected void onFileChosen(@NotNull VirtualFile chosenFile) { + onFileChoosen(chosenFile); + } } @Override @@ -274,6 +298,7 @@ public class ComponentWithBrowseButton extends JPanel i myComponent.requestFocus(); } + @SuppressWarnings("deprecation") @Override public final void setNextFocusableComponent(Component aComponent) { super.setNextFocusableComponent(aComponent); @@ -281,9 +306,10 @@ public class ComponentWithBrowseButton extends JPanel i } private KeyEvent myCurrentEvent = null; + @Override protected final boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { - if (condition == WHEN_FOCUSED && myCurrentEvent != e) + if (condition == WHEN_FOCUSED && myCurrentEvent != e) { try { myCurrentEvent = e; myComponent.dispatchEvent(e); @@ -291,8 +317,8 @@ public class ComponentWithBrowseButton extends JPanel i finally { myCurrentEvent = null; } + } if (e.isConsumed()) return true; return super.processKeyBinding(ks, e, condition, pressed); } - } diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java index ba2e012a8ba9..b8d19407f48d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java +++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/EditorsSplitters.java @@ -26,6 +26,7 @@ import com.intellij.openapi.fileEditor.impl.text.FileDropHandler; import com.intellij.openapi.keymap.Keymap; import com.intellij.openapi.keymap.KeymapManager; import com.intellij.openapi.keymap.KeymapManagerListener; +import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.util.Comparing; @@ -473,7 +474,11 @@ public class EditorsSplitters extends IdePanePanel implements UISettingsListener VirtualFile file = getCurrentFile(); File ioFile = file == null ? null : new File(file.getPresentableUrl()); - String fileTitle = file == null ? null : FrameTitleBuilder.getInstance().getFileTitle(project, file); + String fileTitle = null; + if (file != null) { + fileTitle = DumbService.isDumb(project) ? file.getName() + : FrameTitleBuilder.getInstance().getFileTitle(project, file); + } frame.setFileTitle(fileTitle, ioFile); } diff --git a/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java b/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java index 0f63a6333a90..42556dd45175 100644 --- a/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java +++ b/platform/platform-impl/src/com/intellij/platform/LocationNameFieldsBinding.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2012 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,7 +64,7 @@ public class LocationNameFieldsBinding { descriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) { @Override - protected void onFileChoosen(@NotNull VirtualFile chosenFile) { + protected void onFileChosen(@NotNull VirtualFile chosenFile) { myBaseDir = chosenFile.getPath(); if (isProjectNameChanged(nameTextField.getText()) && !nameTextField.getText().equals(chosenFile.getName())) { myExternalModify = true; diff --git a/platform/platform-resources/src/idea/LangActions.xml b/platform/platform-resources/src/idea/LangActions.xml index eb1884d38fe6..5fbfa62d898c 100644 --- a/platform/platform-resources/src/idea/LangActions.xml +++ b/platform/platform-resources/src/idea/LangActions.xml @@ -717,6 +717,12 @@ + + + + + + diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContext.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContext.java index 8c704fad13cc..77edd2262303 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContext.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContext.java @@ -1,5 +1,6 @@ package org.jetbrains.debugger; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -29,6 +30,12 @@ public interface EvaluateContext { @NotNull EvaluateContext withValueManager(@NotNull String objectGroup); + /** + * If you evaluate "foo.bar = 4" and want to update Variables view (and all other clients), you can use use this task + */ + @NotNull + ActionCallback refreshOnDone(@NotNull ActionCallback result); + /** * call only if withLoader was called before */ diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContextBase.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContextBase.java index a75795522c2f..d933b8e25033 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContextBase.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/EvaluateContextBase.java @@ -1,10 +1,21 @@ package org.jetbrains.debugger; +import com.intellij.openapi.util.ActionCallback; import com.intellij.openapi.util.AsyncResult; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.debugger.values.Value; +import org.jetbrains.debugger.values.ValueManager; + +import java.util.Map; + +public abstract class EvaluateContextBase implements EvaluateContext { + protected final VALUE_MANAGER valueManager; + + protected EvaluateContextBase(@NotNull VALUE_MANAGER valueManager) { + this.valueManager = valueManager; + } -public abstract class EvaluateContextBase implements EvaluateContext { @NotNull @Override public AsyncResult evaluate(@NotNull String expression) { @@ -20,4 +31,19 @@ public abstract class EvaluateContextBase implements EvaluateContext { @Override public void releaseObjects() { } + + @NotNull + @Override + public abstract AsyncResult evaluate(@NotNull String expression, @Nullable Map additionalContext); + + @NotNull + public final VALUE_MANAGER getValueManager() { + return valueManager; + } + + @NotNull + @Override + public ActionCallback refreshOnDone(@NotNull ActionCallback result) { + return result.doWhenDone(valueManager.getClearCachesTask()); + } } \ No newline at end of file diff --git a/platform/util/src/com/intellij/util/IncorrectOperationException.java b/platform/util/src/com/intellij/util/IncorrectOperationException.java index 09d9b892837f..aeaaf726f553 100644 --- a/platform/util/src/com/intellij/util/IncorrectOperationException.java +++ b/platform/util/src/com/intellij/util/IncorrectOperationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,13 +19,22 @@ import org.jetbrains.annotations.NonNls; public class IncorrectOperationException extends RuntimeException { public IncorrectOperationException() { - this(null); + super(); } public IncorrectOperationException(@NonNls String message) { super(message); } + public IncorrectOperationException(Throwable t) { + super(t); + } + + public IncorrectOperationException(@NonNls String message, Throwable t) { + super(message, t); + } + + /** @deprecated use {@link #IncorrectOperationException(String, Throwable)} (to be removed in IDEA 15) */ public IncorrectOperationException(@NonNls String message, Exception e) { super(message, e); } diff --git a/platform/util/src/com/intellij/util/text/DateFormatUtil.java b/platform/util/src/com/intellij/util/text/DateFormatUtil.java index bbdbe12c09a4..e9e19f73bc51 100644 --- a/platform/util/src/com/intellij/util/text/DateFormatUtil.java +++ b/platform/util/src/com/intellij/util/text/DateFormatUtil.java @@ -314,7 +314,7 @@ public class DateFormatUtil { boolean loaded = false; try { - if (SystemInfo.isWinVistaOrNewer) { + if (SystemInfo.isWin7OrNewer) { loaded = getWindowsFormats(formats); } else if (SystemInfo.isMac) { diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsMappingConfigurationDialog.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsMappingConfigurationDialog.java index 83e51eb04596..5a5503556e63 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsMappingConfigurationDialog.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/configurable/VcsMappingConfigurationDialog.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -198,9 +198,9 @@ public class VcsMappingConfigurationDialog extends DialogWrapper { } @Override - protected void onFileChoosen(@NotNull final VirtualFile chosenFile) { + protected void onFileChosen(@NotNull final VirtualFile chosenFile) { String oldText = myDirectoryTextField.getText(); - super.onFileChoosen(chosenFile); + super.onFileChosen(chosenFile); final VcsDescriptor wrapper = (VcsDescriptor) myVCSComboBox.getSelectedItem(); if (oldText.length() == 0 && (wrapper == null || wrapper.isNone())) { final ModalityIgnorantBackgroundableTask task = diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java index 92dad57901ad..605589621a76 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XDebuggerUtil.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger; +import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; @@ -26,6 +27,7 @@ import com.intellij.psi.PsiElement; import com.intellij.util.Processor; import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; +import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.frame.XValueContainer; import com.intellij.xdebugger.settings.XDebuggerSettings; import org.jetbrains.annotations.NotNull; @@ -117,4 +119,7 @@ public abstract class XDebuggerUtil { @Nullable public abstract PsiElement findContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project, boolean checkXml); + + @NotNull + public abstract XExpression createExpression(@NotNull String text, Language language, String custom, EvaluationMode mode); } diff --git a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderError.java b/platform/xdebugger-api/src/com/intellij/xdebugger/XExpression.java similarity index 58% rename from plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderError.java rename to platform/xdebugger-api/src/com/intellij/xdebugger/XExpression.java index a5c4dc0f74a9..b7975aa4a204 100644 --- a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderError.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/XExpression.java @@ -13,30 +13,19 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.jetbrains.plugins.gradle.tooling; +package com.intellij.xdebugger; +import com.intellij.lang.Language; +import com.intellij.xdebugger.evaluation.EvaluationMode; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** - * @author Vladislav.Soroka - * @since 5/13/2014 - */ -public class ModelBuilderError { - @NotNull private final String group; - @NotNull private final String error; - - public ModelBuilderError(@NotNull String group, @NotNull String error) { - this.group = group; - this.error = error; - } - - @NotNull - public String getGroup() { - return group; - } - - @NotNull - public String getError() { - return error; - } +* @author egor +*/ +public interface XExpression { + @NotNull String getExpression(); + @Nullable Language getLanguage(); + @Nullable String getCustomInfo(); + EvaluationMode getMode(); } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java index 305e60c33520..099aa5020303 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/breakpoints/XBreakpoint.java @@ -18,6 +18,7 @@ package com.intellij.xdebugger.breakpoints; import com.intellij.openapi.util.UserDataHolder; import com.intellij.pom.Navigatable; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -56,15 +57,33 @@ public interface XBreakpoint

extends UserDataHo void setLogMessage(boolean logMessage); + /** + * @deprecated use {@link #getLogExpressionObject()} instead + */ + @Deprecated @Nullable String getLogExpression(); void setLogExpression(@Nullable String expression); + @Nullable + XExpression getLogExpressionObject(); + + void setLogExpressionObject(@Nullable XExpression expression); + + /** + * @deprecated use {@link #getConditionExpression()} instead + */ + @Deprecated @Nullable String getCondition(); void setCondition(@Nullable String condition); + @Nullable + XExpression getConditionExpression(); + + void setConditionExpression(@Nullable XExpression condition); + long getTimeStamp(); } diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProvider.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProvider.java index afdac133337b..4b65633121fa 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProvider.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProvider.java @@ -15,13 +15,20 @@ */ package com.intellij.xdebugger.evaluation; +import com.intellij.lang.Language; import com.intellij.openapi.editor.Document; import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; +import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; +import java.util.Collections; + public abstract class XDebuggerEditorsProvider { @NotNull public abstract FileType getFileType(); @@ -31,4 +38,26 @@ public abstract class XDebuggerEditorsProvider { @NotNull String text, @Nullable XSourcePosition sourcePosition, @NotNull EvaluationMode mode); + + @NotNull + public Document createDocument(@NotNull Project project, + @NotNull XExpression expression, + @Nullable XSourcePosition sourcePosition, + @NotNull EvaluationMode mode) { + return createDocument(project, expression.getExpression(), sourcePosition, mode); + } + + @NotNull + public Collection getSupportedLanguages(@NotNull Project project, @Nullable XSourcePosition sourcePosition) { + FileType type = getFileType(); + if (type instanceof LanguageFileType) { + return Collections.singleton(((LanguageFileType)type).getLanguage()); + } + return Collections.emptyList(); + } + + @NotNull + public XExpression createExpression(@NotNull Project project, @NotNull Document document, @Nullable Language language, @NotNull EvaluationMode mode) { + return XDebuggerUtil.getInstance().createExpression(document.getText(), language, null, mode); + } } \ No newline at end of file diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java index 6a593abcfb65..bbf97ff220ab 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEditorsProviderBase.java @@ -1,5 +1,6 @@ package com.intellij.xdebugger.evaluation; +import com.intellij.lang.Language; import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; @@ -7,10 +8,14 @@ import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.xdebugger.XDebuggerUtil; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; +import com.sun.org.apache.xpath.internal.jaxp.XPathExpressionImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + public abstract class XDebuggerEditorsProviderBase extends XDebuggerEditorsProvider { @NotNull @Override @@ -26,8 +31,29 @@ public abstract class XDebuggerEditorsProviderBase extends XDebuggerEditorsProvi return document; } + @NotNull + @Override + public Document createDocument(@NotNull Project project, + @NotNull XExpression expression, + @Nullable XSourcePosition sourcePosition, + @NotNull EvaluationMode mode) { + PsiElement context = null; + if (sourcePosition != null) { + context = getContextElement(sourcePosition.getFile(), sourcePosition.getOffset(), project); + } + + PsiFile codeFragment = createExpressionCodeFragment(project, expression, context, true); + Document document = PsiDocumentManager.getInstance(project).getDocument(codeFragment); + assert document != null; + return document; + } + protected abstract PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull String text, @Nullable PsiElement context, boolean isPhysical); + protected PsiFile createExpressionCodeFragment(@NotNull Project project, @NotNull XExpression expression, @Nullable PsiElement context, boolean isPhysical) { + return createExpressionCodeFragment(project, expression.getExpression(), context, isPhysical); + } + @Nullable protected PsiElement getContextElement(@NotNull VirtualFile virtualFile, int offset, @NotNull Project project) { return XDebuggerUtil.getInstance().findContextElement(virtualFile, offset, project, false); diff --git a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java index bcdbf5336833..3065a2e05dba 100644 --- a/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java +++ b/platform/xdebugger-api/src/com/intellij/xdebugger/evaluation/XDebuggerEvaluator.java @@ -20,6 +20,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.frame.XSuspendContext; @@ -70,6 +71,10 @@ public abstract class XDebuggerEvaluator { */ public abstract void evaluate(@NotNull String expression, @NotNull XEvaluationCallback callback, @Nullable XSourcePosition expressionPosition); + public void evaluate(@NotNull XExpression expression, @NotNull XEvaluationCallback callback, @Nullable XSourcePosition expressionPosition) { + evaluate(expression.getExpression(), callback, expressionPosition); + } + /** * Start evaluating expression. * @@ -82,6 +87,10 @@ public abstract class XDebuggerEvaluator { evaluate(expression, callback, expressionPosition); } + public void evaluate(@NotNull XExpression expression, @NotNull XEvaluationCallback callback, @Nullable XSourcePosition expressionPosition, @NotNull EvaluationMode mode) { + evaluate(expression, callback, expressionPosition); + } + /** * If this method returns {@code true} 'Code Fragment Mode' button will be shown in 'Evaluate' dialog allowing user to execute a set of * statements diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java index 710443370c74..2a120b41eaa7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerHistoryManager.java @@ -18,8 +18,11 @@ package com.intellij.xdebugger.impl; import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; @@ -28,33 +31,34 @@ import java.util.*; */ public class XDebuggerHistoryManager { public static final int MAX_RECENT_EXPRESSIONS = 10; - private final Map> myRecentExpressions = new HashMap>(); + private final Map> myRecentExpressions = new HashMap>(); public static XDebuggerHistoryManager getInstance(@NotNull Project project) { return ServiceManager.getService(project, XDebuggerHistoryManager.class); } - public void addRecentExpression(@NotNull @NonNls String id, @NotNull String expression) { - if (StringUtil.isEmptyOrSpaces(expression)) { - return; + public boolean addRecentExpression(@NotNull @NonNls String id, @Nullable XExpression expression) { + if (expression == null || StringUtil.isEmptyOrSpaces(expression.getExpression())) { + return false; } - LinkedList list = myRecentExpressions.get(id); + LinkedList list = myRecentExpressions.get(id); if (list == null) { - list = new LinkedList(); + list = new LinkedList(); myRecentExpressions.put(id, list); } if (list.size() == MAX_RECENT_EXPRESSIONS) { list.removeLast(); } - String trimmedExpression = expression.trim(); + XExpression trimmedExpression = new XExpressionImpl(expression.getExpression().trim(), expression.getLanguage(), expression.getCustomInfo()); list.remove(trimmedExpression); list.addFirst(trimmedExpression); + return true; } - public List getRecentExpressions(@NonNls String id) { - LinkedList list = myRecentExpressions.get(id); - return list != null ? list : Collections.emptyList(); + public List getRecentExpressions(@NonNls String id) { + LinkedList list = myRecentExpressions.get(id); + return list != null ? list : Collections.emptyList(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java index 799bc55e1885..6e7c7001c4d8 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/XDebuggerUtilImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger.impl; +import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.Result; @@ -32,17 +33,17 @@ import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Processor; -import com.intellij.xdebugger.XDebuggerManager; -import com.intellij.xdebugger.XDebuggerUtil; -import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.*; import com.intellij.xdebugger.breakpoints.*; import com.intellij.xdebugger.breakpoints.ui.XBreakpointGroupingRule; +import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XSuspendContext; import com.intellij.xdebugger.frame.XValueContainer; import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.breakpoints.ui.grouping.XBreakpointFileGroupingRule; import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager; import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager; @@ -350,4 +351,19 @@ public class XDebuggerUtilImpl extends XDebuggerUtil { public static Editor createEditor(@NotNull OpenFileDescriptor descriptor) { return descriptor.canNavigate() ? FileEditorManager.getInstance(descriptor.getProject()).openTextEditor(descriptor, false) : null; } + + public static void rebuildAllSessionsViews(@Nullable Project project) { + if (project == null) return; + for (XDebugSession session : XDebuggerManager.getInstance(project).getDebugSessions()) { + if (session.isSuspended()) { + session.rebuildViews(); + } + } + } + + @NotNull + @Override + public XExpression createExpression(@NotNull String text, Language language, String custom, EvaluationMode mode) { + return new XExpressionImpl(text, language, custom, mode); + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java index 50c5d8d2d8ac..7a00d6c156b7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/XDebuggerActions.java @@ -50,6 +50,8 @@ public interface XDebuggerActions { @NonNls String VARIABLES_TREE_POPUP_GROUP = "XDebugger.Variables.Tree.Popup"; @NonNls String WATCHES_TREE_POPUP_GROUP = "XDebugger.Watches.Tree.Popup"; @NonNls String WATCHES_TREE_TOOLBAR_GROUP = "XDebugger.Watches.Tree.Toolbar"; + @NonNls String FRAMES_TREE_POPUP_GROUP = "XDebugger.Frames.Tree.Popup"; + @NonNls String FRAMES_TOP_TOOLBAR_GROUP = "XDebugger.Frames.TopToolbar"; @NonNls String ADD_TO_WATCH = "Debugger.AddToWatch"; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java index b023150ecdcd..9df9bb6cc487 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XAddToWatchesFromEditorActionHandler.java @@ -22,6 +22,7 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.impl.XDebugSessionImpl; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,6 +58,6 @@ public class XAddToWatchesFromEditorActionHandler extends XDebuggerActionHandler final String text = getTextToEvaluate(dataContext, session); if (text == null) return; - ((XDebugSessionImpl)session).getSessionTab().getWatchesView().addWatchExpression(text, -1, true); + ((XDebugSessionImpl)session).getSessionTab().getWatchesView().addWatchExpression(XExpressionImpl.fromText(text), -1, true); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java index b3648d6e6fa9..4394d2a37f22 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerEvaluateActionHandler.java @@ -15,19 +15,25 @@ */ package com.intellij.xdebugger.impl.actions.handlers; +import com.intellij.lang.Language; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.ExpressionInfo; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; 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.intellij.xdebugger.impl.evaluate.XDebuggerEvaluationDialog; +import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase; import com.intellij.xdebugger.impl.ui.tree.actions.XDebuggerTreeActionBase; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,7 +69,22 @@ public class XDebuggerEvaluateActionHandler extends XDebuggerActionHandler { text = value.getEvaluationExpression(); } } - new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, StringUtil.notNullize(text), stackFrame == null ? null : stackFrame.getSourcePosition()).show(); + + Language language = null; + if (stackFrame != null) { + XSourcePosition position = stackFrame.getSourcePosition(); + if (position != null) { + language = XDebuggerEditorBase.getFileTypeLanguage(position.getFile().getFileType()); + } + } + if (language == null) { + VirtualFile file = CommonDataKeys.VIRTUAL_FILE.getData(dataContext); + if (file != null) { + language = XDebuggerEditorBase.getFileTypeLanguage(file.getFileType()); + } + } + XExpression expression = new XExpressionImpl(StringUtil.notNullize(text), language, null); + new XDebuggerEvaluationDialog(session, editorsProvider, evaluator, expression, stackFrame == null ? null : stackFrame.getSourcePosition()).show(); } @Nullable diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerMuteBreakpointsHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerMuteBreakpointsHandler.java index 0b4a6d497249..74bb43f12354 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerMuteBreakpointsHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerMuteBreakpointsHandler.java @@ -17,20 +17,39 @@ package com.intellij.xdebugger.impl.actions.handlers; import com.intellij.xdebugger.XDebugSession; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.xdebugger.impl.ui.XDebugSessionData; +import org.jetbrains.annotations.Nullable; /** * @author nik */ public class XDebuggerMuteBreakpointsHandler extends XDebuggerToggleActionHandler { - protected boolean isEnabled(final XDebugSession session, final AnActionEvent event) { + protected boolean isEnabled(@Nullable final XDebugSession session, final AnActionEvent event) { return true; } - protected boolean isSelected(final XDebugSession session, final AnActionEvent event) { - return session.areBreakpointsMuted(); + protected boolean isSelected(@Nullable final XDebugSession session, final AnActionEvent event) { + if (session != null) { + return session.areBreakpointsMuted(); + } + else { + XDebugSessionData data = event.getData(XDebugSessionData.DATA_KEY); + if (data != null) { + return data.isBreakpointsMuted(); + } + } + return false; } - protected void setSelected(final XDebugSession session, final AnActionEvent event, final boolean state) { - session.setBreakpointMuted(state); + protected void setSelected(@Nullable final XDebugSession session, final AnActionEvent event, final boolean state) { + if (session != null) { + session.setBreakpointMuted(state); + } + else { + XDebugSessionData data = event.getData(XDebugSessionData.DATA_KEY); + if (data != null) { + data.setBreakpointsMuted(state); + } + } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerToggleActionHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerToggleActionHandler.java index 76545dd71a00..b76970504030 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerToggleActionHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/actions/handlers/XDebuggerToggleActionHandler.java @@ -21,6 +21,7 @@ import com.intellij.xdebugger.XDebugSession; import com.intellij.openapi.project.Project; import com.intellij.openapi.actionSystem.AnActionEvent; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik @@ -28,24 +29,22 @@ import org.jetbrains.annotations.NotNull; public abstract class XDebuggerToggleActionHandler extends DebuggerToggleActionHandler { public final boolean isEnabled(@NotNull final Project project, final AnActionEvent event) { XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); - return session != null && isEnabled(session, event); + return isEnabled(session, event); } public boolean isSelected(@NotNull final Project project, final AnActionEvent event) { XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); - return session != null && isSelected(session, event); + return isSelected(session, event); } public void setSelected(@NotNull final Project project, final AnActionEvent event, final boolean state) { XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession(); - if (session != null) { - setSelected(session, event, state); - } + setSelected(session, event, state); } - protected abstract boolean isEnabled(final XDebugSession session, final AnActionEvent event); + protected abstract boolean isEnabled(@Nullable XDebugSession session, final AnActionEvent event); - protected abstract boolean isSelected(final XDebugSession session, final AnActionEvent event); + protected abstract boolean isSelected(@Nullable XDebugSession session, final AnActionEvent event); - protected abstract void setSelected(final XDebugSession session, final AnActionEvent event, boolean state); + protected abstract void setSelected(@Nullable XDebugSession session, final AnActionEvent event, boolean state); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java index eddbb8ab4620..7196801c06ac 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/BreakpointState.java @@ -15,13 +15,16 @@ */ package com.intellij.xdebugger.impl.breakpoints; +import com.intellij.lang.Language; import com.intellij.util.xmlb.annotations.*; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.breakpoints.SuspendPolicy; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.XBreakpointProperties; import com.intellij.xdebugger.breakpoints.XBreakpointType; import org.jdom.Element; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; /** * @author nik @@ -123,52 +126,30 @@ public class BreakpointState, P extends XBreakpointProp myDescription = description; } - @Transient - public String getLogExpression() { - return myLogExpression != null ? myLogExpression.myExpression : null; - } - - public void setLogExpression(String expression) { - if (expression != null) { - myLogExpression = new LogExpression(); - myLogExpression.myExpression = expression; - } - else { - myLogExpression = null; - } - } - + @Nullable @Property(surroundWithTag = false) - public LogExpression getLogExpressionObject() { + public LogExpression getLogExpression() { return myLogExpression; } - public void setLogExpressionObject(final LogExpression logExpression) { - setLogExpression(logExpression.myOldExpression != null ? logExpression.myOldExpression : logExpression.myExpression); - } - - @Transient - public String getCondition() { - return myCondition != null ? myCondition.myExpression : null; - } - - public void setCondition(String condition) { - if (condition != null) { - myCondition = new Condition(); - myCondition.myExpression = condition; - } - else { - myCondition = null; + public void setLogExpression(@Nullable LogExpression logExpression) { + if (logExpression != null) { + logExpression.checkConverted(); } + myLogExpression = logExpression; } + @Nullable @Property(surroundWithTag = false) - public Condition getConditionObject() { + public Condition getCondition() { return myCondition; } - public void setConditionObject(final Condition condition) { - setCondition(condition.myOldExpression != null ? condition.myOldExpression : condition.myExpression); + public void setCondition(@Nullable Condition condition) { + if (condition != null) { + condition.checkConverted(); + } + myCondition = condition; } @Property(surroundWithTag = false) @@ -197,18 +178,56 @@ public class BreakpointState, P extends XBreakpointProp } @Tag("condition") - public static class Condition { - @Attribute("expression") - public String myExpression; - @Text - public String myOldExpression; + public static class Condition extends XExpressionState { + public Condition() { + } + + public Condition(XExpression expression) { + super(expression.getExpression(), expression.getLanguage() != null ? expression.getLanguage().getID() : null, expression.getCustomInfo()); + } } @Tag("log-expression") - public static class LogExpression { + public static class LogExpression extends XExpressionState { + public LogExpression() { + } + + public LogExpression(XExpression expression) { + super(expression.getExpression(), expression.getLanguage() != null ? expression.getLanguage().getID() : null, expression.getCustomInfo()); + } + } + + private static class XExpressionState { @Attribute("expression") public String myExpression; + + @Attribute("language") + public String myLanguage; + + @Attribute("custom") + public String myCustomInfo; + @Text public String myOldExpression; + + public XExpressionState() { + } + + public XExpressionState(@NotNull String expression, String language, String customInfo) { + myExpression = expression; + myLanguage = language; + myCustomInfo = customInfo; + } + + void checkConverted() { + if (myOldExpression != null) { + myExpression = myOldExpression; + myOldExpression = null; + } + } + + public XExpression toXExpression() { + return new XExpressionImpl(myExpression, Language.findLanguageByID(myLanguage), myCustomInfo); + } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java index 9c6b94ffcea2..f6b75b4a863f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointBase.java @@ -31,6 +31,7 @@ import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters; import com.intellij.util.xmlb.XmlSerializer; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.SuspendPolicy; import com.intellij.xdebugger.breakpoints.XBreakpoint; @@ -61,12 +62,15 @@ public class XBreakpointBase, P extends XBreakpointP private final XBreakpointManagerImpl myBreakpointManager; private Icon myIcon; private CustomizedBreakpointPresentation myCustomizedPresentation; + private XExpression myCondition; + private XExpression myLogExpression; public XBreakpointBase(final XBreakpointType type, XBreakpointManagerImpl breakpointManager, final @Nullable P properties, final S state) { myState = state; myType = type; myProperties = properties; myBreakpointManager = breakpointManager; + initExpressions(); } protected XBreakpointBase(final XBreakpointType type, XBreakpointManagerImpl breakpointManager, S breakpointState) { @@ -77,6 +81,14 @@ public class XBreakpointBase, P extends XBreakpointP if (myProperties != null) { ComponentSerializationUtil.loadComponentState(myProperties, myState.getPropertiesElement()); } + initExpressions(); + } + + private void initExpressions() { + BreakpointState.Condition condition = myState.getCondition(); + myCondition = condition != null ? condition.toXExpression() : null; + BreakpointState.LogExpression expression = myState.getLogExpression(); + myLogExpression = expression != null ? expression.toXExpression() : null; } public final Project getProject() { @@ -148,26 +160,54 @@ public class XBreakpointBase, P extends XBreakpointP @Override public String getLogExpression() { - return myState.getLogExpression(); + return myLogExpression != null ? myLogExpression.getExpression() : null; } @Override public void setLogExpression(@Nullable final String expression) { if (!Comparing.equal(getLogExpression(), expression)) { - myState.setLogExpression(expression); + myLogExpression = XExpressionImpl.fromText(expression); + fireBreakpointChanged(); + } + } + + @Nullable + @Override + public XExpression getLogExpressionObject() { + return myLogExpression; + } + + @Override + public void setLogExpressionObject(@Nullable XExpression expression) { + if (!Comparing.equal(getLogExpressionObject(), expression)) { + myLogExpression = expression; fireBreakpointChanged(); } } @Override public String getCondition() { - return myState.getCondition(); + return myCondition != null ? myCondition.getExpression() : null; } @Override public void setCondition(@Nullable final String condition) { if (!Comparing.equal(condition, getCondition())) { - myState.setCondition(condition); + myCondition = XExpressionImpl.fromText(condition); + fireBreakpointChanged(); + } + } + + @Nullable + @Override + public XExpression getConditionExpression() { + return myCondition; + } + + @Override + public void setConditionExpression(@Nullable XExpression condition) { + if (!Comparing.equal(condition, getConditionExpression())) { + myCondition = condition; fireBreakpointChanged(); } } @@ -195,6 +235,8 @@ public class XBreakpointBase, P extends XBreakpointP public S getState() { Element propertiesElement = myProperties != null ? XmlSerializer.serialize(myProperties.getState(), SERIALIZATION_FILTERS) : null; + myState.setCondition(myCondition != null && !myCondition.getExpression().isEmpty() ? new BreakpointState.Condition(myCondition) : null); + myState.setLogExpression(myLogExpression != null && !myLogExpression.getExpression().isEmpty() ? new BreakpointState.LogExpression(myLogExpression) : null); myState.setPropertiesElement(propertiesElement); return myState; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java index cd8ebaa48d26..a85e13331841 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XBreakpointItem.java @@ -57,7 +57,7 @@ class XBreakpointItem extends BreakpointItem { } final SimpleTextAttributes attributes = myBreakpoint.isEnabled() ? SimpleTextAttributes.SIMPLE_CELL_ATTRIBUTES : SimpleTextAttributes.GRAYED_ATTRIBUTES; - renderer.append(getDisplayText(), attributes); + renderer.append(StringUtil.notNullize(getDisplayText()), attributes); String description = getUserDescription(); if (!StringUtil.isEmpty(description)) { renderer.append(" (" + description + ")", SimpleTextAttributes.REGULAR_ITALIC_ATTRIBUTES); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionImpl.java new file mode 100644 index 000000000000..b966377a47ba --- /dev/null +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XExpressionImpl.java @@ -0,0 +1,110 @@ +/* + * 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.xdebugger.impl.breakpoints; + +import com.intellij.lang.Language; +import com.intellij.xdebugger.XExpression; +import com.intellij.xdebugger.evaluation.EvaluationMode; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** +* @author egor +*/ +public class XExpressionImpl implements XExpression { + public static final XExpression EMPTY_EXPRESSION = fromText("", EvaluationMode.EXPRESSION); + public static final XExpression EMPTY_CODE_FRAGMENT = fromText("", EvaluationMode.CODE_FRAGMENT); + + @NotNull private final String myExpression; + private final Language myLanguage; + private final String myCustomInfo; + private final EvaluationMode myMode; + + public XExpressionImpl(@NotNull String expression, Language language, String customInfo) { + this(expression, language, customInfo, EvaluationMode.EXPRESSION); + } + + public XExpressionImpl(@NotNull String expression, Language language, String customInfo, EvaluationMode mode) { + myExpression = expression; + myLanguage = language; + myCustomInfo = customInfo; + myMode = mode; + } + + @NotNull + @Override + public String getExpression() { + return myExpression; + } + + @Override + public Language getLanguage() { + return myLanguage; + } + + @Override + public String getCustomInfo() { + return myCustomInfo; + } + + @Override + public EvaluationMode getMode() { + return myMode; + } + + @Nullable + public static XExpressionImpl fromText(@Nullable String text) { + return text != null ? new XExpressionImpl(text, null, null, EvaluationMode.EXPRESSION) : null; + } + + @Nullable + public static XExpressionImpl fromText(@Nullable String text, EvaluationMode mode) { + return text != null ? new XExpressionImpl(text, null, null, mode) : null; + } + + public static XExpressionImpl changeMode(XExpression expression, EvaluationMode mode) { + return new XExpressionImpl(expression.getExpression(), expression.getLanguage(), expression.getCustomInfo(), mode); + } + + @Override + public String toString() { + return myExpression; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + XExpressionImpl that = (XExpressionImpl)o; + + if (myCustomInfo != null ? !myCustomInfo.equals(that.myCustomInfo) : that.myCustomInfo != null) return false; + if (!myExpression.equals(that.myExpression)) return false; + if (myLanguage != null ? !myLanguage.equals(that.myLanguage) : that.myLanguage != null) return false; + if (myMode != that.myMode) return false; + + return true; + } + + @Override + public int hashCode() { + int result = myExpression.hashCode(); + result = 31 * result + (myLanguage != null ? myLanguage.hashCode() : 0); + result = 31 * result + (myCustomInfo != null ? myCustomInfo.hashCode() : 0); + result = 31 * result + (myMode != null ? myMode.hashCode() : 0); + return result; + } +} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java index 3ea01ec15295..852d239538e7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/XLineBreakpointImpl.java @@ -279,4 +279,9 @@ public class XLineBreakpointImpl

extends XBreak } setIcon(isTemporary() ? myType.getTemporaryIcon() : myType.getEnabledIcon()); } + + @Override + public String toString() { + return "XLineBreakpointImpl(" + myType.getId() + " at " + getShortFilePath() + ":" + getLine() + ")"; + } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java index d7ae72b2ad53..8fe6c01981e1 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultConditionComboBoxPanel.java @@ -16,7 +16,6 @@ package com.intellij.xdebugger.impl.breakpoints.ui; import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.breakpoints.XBreakpoint; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; @@ -48,15 +47,12 @@ public class DefaultConditionComboBoxPanel> extends XBr @Override public void saveTo(@NotNull B breakpoint) { - final String condition = StringUtil.nullize(myConditionComboBox.getText(), true); - breakpoint.setCondition(condition); - if (condition != null) { - myConditionComboBox.saveTextInHistory(); - } + breakpoint.setConditionExpression(myConditionComboBox.getExpression()); + myConditionComboBox.saveTextInHistory(); } @Override public void loadFrom(@NotNull B breakpoint) { - myConditionComboBox.setText(StringUtil.notNullize(breakpoint.getCondition())); + myConditionComboBox.setExpression(breakpoint.getConditionExpression()); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java index d8ef28a68a10..72ca1d73cebc 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/DefaultLogExpressionComboBoxPanel.java @@ -47,14 +47,12 @@ public class DefaultLogExpressionComboBoxPanel> extends @Override public void saveTo(@NotNull B breakpoint) { - String logExpression = myLogExpressionComboBox.getComponent().isEnabled() ? myLogExpressionComboBox.getText() : null; - breakpoint.setLogExpression(logExpression); + breakpoint.setLogExpressionObject(myLogExpressionComboBox.getComponent().isEnabled() ? myLogExpressionComboBox.getExpression() : null); myLogExpressionComboBox.saveTextInHistory(); } @Override public void loadFrom(@NotNull B breakpoint) { - String logExpression = breakpoint.getLogExpression(); - myLogExpressionComboBox.setText(logExpression != null ? logExpression : ""); + myLogExpressionComboBox.setExpression(breakpoint.getLogExpressionObject()); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java index dbb8b21ee4ce..c73a8675bb52 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XBreakpointActionsPanel.java @@ -54,16 +54,7 @@ public class XBreakpointActionsPanel> extends XBreakpoi onCheckboxChanged(); } }; - - if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) { - logExpressionPanel = ((XDebuggerComboBoxProvider)debuggerEditorsProvider).createLogExpressionComboBoxPanel( - project, debuggerEditorsProvider, DefaultLogExpressionComboBoxPanel.HISTORY_KEY, myBreakpoint.getSourcePosition()); - } - else { - logExpressionPanel = - new DefaultLogExpressionComboBoxPanel(project, debuggerEditorsProvider, myBreakpoint.getSourcePosition()); - } - + logExpressionPanel = new DefaultLogExpressionComboBoxPanel(project, debuggerEditorsProvider, myBreakpoint.getSourcePosition()); JComponent logExpressionComponent = logExpressionPanel.getComponent(); myLogExpressionPanel.add(logExpressionComponent, BorderLayout.CENTER); logExpressionComponent.setEnabled(false); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java deleted file mode 100644 index fd5391146657..000000000000 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XDebuggerComboBoxProvider.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.xdebugger.impl.breakpoints.ui; - -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XSourcePosition; -import com.intellij.xdebugger.breakpoints.XBreakpoint; -import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; -import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; - -/** - * @author egor - */ -public interface XDebuggerComboBoxProvider> { - XBreakpointCustomPropertiesPanel createConditionComboBoxPanel(Project project, - XDebuggerEditorsProvider debuggerEditorsProvider, - String historyId, - XSourcePosition sourcePosition); - - XBreakpointCustomPropertiesPanel createLogExpressionComboBoxPanel(Project project, - XDebuggerEditorsProvider debuggerEditorsProvider, - String historyId, - XSourcePosition sourcePosition); -} diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java index 67d42988578c..c0eb1bcb8d10 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/breakpoints/ui/XLightBreakpointPropertiesPanel.java @@ -23,7 +23,6 @@ import com.intellij.xdebugger.breakpoints.XBreakpointManager; import com.intellij.xdebugger.breakpoints.XBreakpointType; import com.intellij.xdebugger.breakpoints.ui.XBreakpointCustomPropertiesPanel; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; -import com.intellij.xdebugger.impl.breakpoints.XBreakpointBase; import com.intellij.xdebugger.impl.breakpoints.XBreakpointUtil; import javax.swing.*; @@ -105,14 +104,7 @@ public class XLightBreakpointPropertiesPanel> implement myCustomPanels = new ArrayList>(); if (debuggerEditorsProvider != null) { final XBreakpointCustomPropertiesPanel conditionPanel; - if (debuggerEditorsProvider instanceof XDebuggerComboBoxProvider) { - conditionPanel = ((XDebuggerComboBoxProvider)debuggerEditorsProvider).createConditionComboBoxPanel( - project, debuggerEditorsProvider, DefaultConditionComboBoxPanel.HISTORY_KEY, myBreakpoint.getSourcePosition()); - } - else { - conditionPanel = - new DefaultConditionComboBoxPanel(project, debuggerEditorsProvider, myBreakpoint.getSourcePosition()); - } + conditionPanel = new DefaultConditionComboBoxPanel(project, debuggerEditorsProvider, myBreakpoint.getSourcePosition()); myConditionExpressionPanel.add(conditionPanel.getComponent(), BorderLayout.CENTER); myCustomPanels.add(conditionPanel); myMainPanel.addFocusListener(new FocusAdapter() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java index 20ba0acfd6d6..141a56c9b721 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/CodeFragmentInputComponent.java @@ -20,8 +20,10 @@ import com.intellij.openapi.ui.Splitter; import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.Disposable; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase; import com.intellij.xdebugger.impl.ui.XDebuggerMultilineEditor; import org.jetbrains.annotations.NotNull; @@ -38,9 +40,9 @@ public class CodeFragmentInputComponent extends EvaluationInputComponent { private final JPanel myMainPanel; public CodeFragmentInputComponent(final @NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, - final @Nullable XSourcePosition sourcePosition, @Nullable String statements, Disposable parentDisposable) { + final @Nullable XSourcePosition sourcePosition, @Nullable XExpression statements, Disposable parentDisposable) { super(XDebuggerBundle.message("dialog.title.evaluate.code.fragment")); - myMultilineEditor = new XDebuggerMultilineEditor(project, editorsProvider, "evaluateCodeFragment", sourcePosition, statements != null ? statements : ""); + myMultilineEditor = new XDebuggerMultilineEditor(project, editorsProvider, "evaluateCodeFragment", sourcePosition, statements != null ? statements : XExpressionImpl.EMPTY_CODE_FRAGMENT); myMainPanel = new JPanel(new BorderLayout()); JPanel editorPanel = new JPanel(new BorderLayout()); editorPanel.add(myMultilineEditor.getComponent(), BorderLayout.CENTER); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java index 0850bf6e5f45..a272cb30321f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/ExpressionInputComponent.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.evaluate; import com.intellij.openapi.project.Project; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase; @@ -35,7 +36,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent { private final JPanel myMainPanel; public ExpressionInputComponent(final @NotNull Project project, @NotNull XDebuggerEditorsProvider editorsProvider, final @Nullable XSourcePosition sourcePosition, - @Nullable String expression) { + @Nullable XExpression expression) { super(XDebuggerBundle.message("xdebugger.dialog.title.evaluate.expression")); myMainPanel = new JPanel(new BorderLayout()); myMainPanel.add(new JLabel(XDebuggerBundle.message("xdebugger.evaluate.label.expression")), BorderLayout.WEST); @@ -43,7 +44,7 @@ public class ExpressionInputComponent extends EvaluationInputComponent { myExpressionComboBox.getComboBox().setMinimumAndPreferredWidth(250); myMainPanel.add(myExpressionComboBox.getComponent(), BorderLayout.CENTER); if (expression != null) { - myExpressionComboBox.setText(expression); + myExpressionComboBox.setExpression(expression); } myExpressionComboBox.selectAll(); } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java index 4abf17312585..169f2e75eef7 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/XDebuggerEvaluationDialog.java @@ -22,15 +22,13 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.wm.IdeFocusManager; -import com.intellij.xdebugger.XDebugSession; -import com.intellij.xdebugger.XDebugSessionAdapter; -import com.intellij.xdebugger.XDebuggerBundle; -import com.intellij.xdebugger.XSourcePosition; +import com.intellij.xdebugger.*; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.actions.XDebuggerActions; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.ui.XDebuggerEditorBase; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel; @@ -63,7 +61,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { public XDebuggerEvaluationDialog(@NotNull XDebugSession session, @NotNull XDebuggerEditorsProvider editorsProvider, @NotNull XDebuggerEvaluator evaluator, - @NotNull String text, + @NotNull XExpression text, @Nullable XSourcePosition sourcePosition) { super(session.getProject(), true); mySession = session; @@ -109,12 +107,12 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { EvaluationMode mode = EvaluationMode.EXPRESSION; myIsCodeFragmentEvaluationSupported = evaluator.isCodeFragmentEvaluationSupported(); - if (text.indexOf('\n') != -1) { + if (text.getExpression().indexOf('\n') != -1) { if (myIsCodeFragmentEvaluationSupported) { mode = EvaluationMode.CODE_FRAGMENT; } else { - text = StringUtil.replace(text, "\n", " "); + text = new XExpressionImpl(StringUtil.replace(text.getExpression(), "\n", " "), text.getLanguage(), text.getCustomInfo()); } } switchToMode(mode, text); @@ -148,8 +146,8 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { return button; } - public String getExpression() { - return myInputComponent.getInputEditor().getText(); + public XExpression getExpression() { + return myInputComponent.getInputEditor().getExpression(); } private static String getSwitchButtonText(EvaluationMode mode) { @@ -158,7 +156,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { : XDebuggerBundle.message("button.text.code.fragment.mode"); } - private void switchToMode(EvaluationMode mode, String text) { + private void switchToMode(EvaluationMode mode, XExpression text) { if (myMode == mode) return; myMode = mode; @@ -174,8 +172,9 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { } } - private EvaluationInputComponent createInputComponent(EvaluationMode mode, String text) { + private EvaluationInputComponent createInputComponent(EvaluationMode mode, XExpression text) { final Project project = mySession.getProject(); + text = XExpressionImpl.changeMode(text, mode); if (mode == EvaluationMode.EXPRESSION) { return new ExpressionInputComponent(project, myEditorsProvider, mySourcePosition, text); } @@ -210,7 +209,7 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { public void startEvaluation(@NotNull XDebuggerEvaluator.XEvaluationCallback evaluationCallback) { final XDebuggerEditorBase inputEditor = myInputComponent.getInputEditor(); inputEditor.saveTextInHistory(); - String expression = inputEditor.getText(); + XExpression expression = inputEditor.getExpression(); XDebuggerEvaluator evaluator = mySession.getDebugProcess().getEvaluator(); if (evaluator == null) { @@ -229,12 +228,12 @@ public class XDebuggerEvaluationDialog extends DialogWrapper { private class SwitchModeAction extends AbstractAction { @Override public void actionPerformed(ActionEvent e) { - String text = myInputComponent.getInputEditor().getText(); + XExpression text = myInputComponent.getInputEditor().getExpression(); if (myMode == EvaluationMode.EXPRESSION) { switchToMode(EvaluationMode.CODE_FRAGMENT, text); } else { - if (text.indexOf('\n') != -1) text = ""; + if (text.getExpression().indexOf('\n') != -1) text = XExpressionImpl.EMPTY_EXPRESSION; switchToMode(EvaluationMode.EXPRESSION, text); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java index 7458de335ad5..1669e102f15f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/evaluate/quick/XQuickEvaluateHandler.java @@ -90,7 +90,7 @@ public class XQuickEvaluateHandler extends QuickEvaluateHandler { && selectionStart <= offset && offset <= selectionEnd) { return new ExpressionInfo(new TextRange(selectionStart, selectionEnd)); } - return evaluator.getExpressionInfoAtOffset(project, editor.getDocument(), offset, false); + return evaluator.getExpressionInfoAtOffset(project, editor.getDocument(), offset, type == ValueHintType.MOUSE_CLICK_HINT || type == ValueHintType.MOUSE_ALT_OVER_HINT); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java index 9f04b9107619..b3e52b49d1b2 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/WatchInplaceEditor.java @@ -15,10 +15,10 @@ */ package com.intellij.xdebugger.impl.frame; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.AppUIUtil; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebugSessionAdapter; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreeInplaceEditor; import com.intellij.xdebugger.impl.ui.tree.nodes.WatchNode; import com.intellij.xdebugger.impl.ui.tree.nodes.WatchesRootNode; @@ -45,7 +45,7 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor { myRootNode = rootNode; myWatchesView = watchesView; myOldNode = oldNode; - myExpressionEditor.setText(oldNode != null ? oldNode.getExpression() : ""); + myExpressionEditor.setExpression(oldNode != null ? oldNode.getExpression() : null); new WatchEditorSessionListener(session).install(); } @@ -66,11 +66,11 @@ public class WatchInplaceEditor extends XDebuggerTreeInplaceEditor { @Override public void doOKAction() { - String expression = myExpressionEditor.getText(); + XExpression expression = myExpressionEditor.getExpression(); myExpressionEditor.saveTextInHistory(); super.doOKAction(); int index = myRootNode.removeChildNode(getNode()); - if (!StringUtil.isEmpty(expression) && index != -1) { + if (!expression.getExpression().isEmpty() && index != -1) { myWatchesView.addWatchExpression(expression, index, false); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java index 275015c59a00..d4ca8726f35a 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XFramesView.java @@ -16,13 +16,12 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.ide.CommonActionsManager; -import com.intellij.openapi.actionSystem.ActionManager; -import com.intellij.openapi.actionSystem.ActionPlaces; -import com.intellij.openapi.actionSystem.DefaultActionGroup; +import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.impl.ActionToolbarImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.CaptionPanel; +import com.intellij.ui.PopupHandler; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.border.CustomLineBorder; import com.intellij.ui.components.panels.Wrapper; @@ -32,6 +31,7 @@ import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.frame.XExecutionStack; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.frame.XSuspendContext; +import com.intellij.xdebugger.impl.actions.XDebuggerActions; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -83,6 +83,16 @@ public class XFramesView implements XDebugView { } } }); + + final ActionManager actionManager = ActionManager.getInstance(); + myFramesList.addMouseListener(new PopupHandler() { + @Override + public void invokePopup(final Component comp, final int x, final int y) { + ActionGroup group = (ActionGroup)actionManager.getAction(XDebuggerActions.FRAMES_TREE_POPUP_GROUP); + actionManager.createActionPopupMenu(ActionPlaces.UNKNOWN, group).getComponent().show(comp, x, y); + } + }); + myMainPanel.add(ScrollPaneFactory.createScrollPane(myFramesList), BorderLayout.CENTER); myThreadComboBox = new JComboBox(); @@ -106,6 +116,8 @@ public class XFramesView implements XDebugView { framesGroup.add(actionsManager.createPrevOccurenceAction(getFramesList())); framesGroup.add(actionsManager.createNextOccurenceAction(getFramesList())); + framesGroup.addAll(ActionManager.getInstance().getAction(XDebuggerActions.FRAMES_TOP_TOOLBAR_GROUP)); + final ActionToolbarImpl toolbar = (ActionToolbarImpl)ActionManager.getInstance().createActionToolbar(ActionPlaces.DEBUGGER_TOOLBAR, framesGroup, true); toolbar.setReservePlaceAutoPopupIcon(false); @@ -242,8 +254,11 @@ public class XFramesView implements XDebugView { XStackFrame topFrame = executionStack.getTopFrame(); if (topFrame != null) { myStackFrames.add(topFrame); + myNextFrameIndex = 1; + } + else { + myNextFrameIndex = 0; } - myNextFrameIndex = 1; } @Override @@ -279,7 +294,7 @@ public class XFramesView implements XDebugView { private void addFrameListElements(final List values, final boolean last) { if (myExecutionStack != null && myExecutionStack == mySelectedStack) { DefaultListModel model = myFramesList.getModel(); - if (model.getElementAt(model.getSize() - 1) == null) { + if (!model.isEmpty() && model.getElementAt(model.getSize() - 1) == null) { model.removeElementAt(model.getSize() - 1); } for (Object value : values) { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java index 9196f5157b6e..c061b8b39fe1 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesView.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.frame; import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.impl.ui.tree.nodes.XDebuggerTreeNode; import org.jetbrains.annotations.NotNull; @@ -27,7 +28,7 @@ import java.util.List; public interface XWatchesView { DataKey DATA_KEY = DataKey.create("XDEBUGGER_WATCHES_VIEW"); - void addWatchExpression(@NotNull String expression, int index, boolean navigateToWatchNode); + void addWatchExpression(@NotNull XExpression expression, int index, boolean navigateToWatchNode); void removeWatches(List nodes); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java index 790896f2cd88..648124ff2aa1 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/frame/XWatchesViewImpl.java @@ -26,13 +26,14 @@ import com.intellij.ui.AnActionButtonRunnable; import com.intellij.ui.CaptionPanel; import com.intellij.ui.ToolbarDecorator; import com.intellij.ui.border.CustomLineBorder; -import com.intellij.util.ArrayUtil; import com.intellij.util.ui.tree.TreeUtil; import com.intellij.xdebugger.XDebugSession; import com.intellij.xdebugger.XDebuggerBundle; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.frame.XStackFrame; import com.intellij.xdebugger.impl.XDebugSessionImpl; import com.intellij.xdebugger.impl.actions.XDebuggerActions; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.ui.XDebugSessionData; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTreePanel; @@ -122,7 +123,7 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi } @Override - public void addWatchExpression(@NotNull String expression, int index, final boolean navigateToWatchNode) { + public void addWatchExpression(@NotNull XExpression expression, int index, final boolean navigateToWatchNode) { myRootNode.addWatchExpression(mySession.getDebugProcess().getEvaluator(), expression, index, navigateToWatchNode); updateSessionData(); } @@ -195,14 +196,14 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi } private void updateSessionData() { - List watchExpressions = new ArrayList(); + List watchExpressions = new ArrayList(); final List children = myRootNode.getAllChildren(); if (children != null) { for (WatchNode child : children) { watchExpressions.add(child.getExpression()); } } - mySessionData.setWatchExpressions(ArrayUtil.toStringArray(watchExpressions)); + mySessionData.setWatchExpressions(watchExpressions.toArray(new XExpression[watchExpressions.size()])); } @Override @@ -229,14 +230,14 @@ public class XWatchesViewImpl implements DnDNativeTarget, XWatchesView, XDebugVi for (XValueNodeImpl node : nodes) { String expression = node.getValueContainer().getEvaluationExpression(); if (expression != null) { - addWatchExpression(expression, -1, false); + addWatchExpression(XExpressionImpl.fromText(expression), -1, false); } } } else if (object instanceof EventInfo) { String text = ((EventInfo)object).getTextForFlavor(DataFlavor.stringFlavor); if (text != null) { - addWatchExpression(text, -1, false); + addWatchExpression(XExpressionImpl.fromText(text), -1, false); } } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionData.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionData.java index 6a46d661618d..acc8cc506e25 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionData.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionData.java @@ -15,30 +15,34 @@ */ package com.intellij.xdebugger.impl.ui; +import com.intellij.openapi.actionSystem.DataKey; import com.intellij.util.ArrayUtil; +import com.intellij.xdebugger.XExpression; import org.jetbrains.annotations.NotNull; /** * @author nik */ public class XDebugSessionData { - private String[] myWatchExpressions; + public static final DataKey DATA_KEY = DataKey.create("XDebugSessionData"); + + private XExpression[] myWatchExpressions; private boolean myBreakpointsMuted = false; - public XDebugSessionData(final @NotNull String[] watchExpressions) { + public XDebugSessionData(final @NotNull XExpression[] watchExpressions) { myWatchExpressions = watchExpressions; } public XDebugSessionData() { - this(ArrayUtil.EMPTY_STRING_ARRAY); + this(new XExpression[0]); } - public void setWatchExpressions(@NotNull String[] watchExpressions) { + public void setWatchExpressions(@NotNull XExpression[] watchExpressions) { myWatchExpressions = watchExpressions; } @NotNull - public String[] getWatchExpressions() { + public XExpression[] getWatchExpressions() { return myWatchExpressions; } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java index 99d1dd9235b3..674c921db938 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebugSessionTab.java @@ -150,6 +150,9 @@ public class XDebugSessionTab extends DebuggerSessionTabBase { if (LangDataKeys.CONSOLE_VIEW.is(dataId)) { return session.getConsoleView(); } + if (XDebugSessionData.DATA_KEY.is(dataId)) { + return sessionData; + } return null; } }); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java index 240bf070f19c..32b3f5511f2e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerEditorBase.java @@ -15,17 +15,38 @@ */ package com.intellij.xdebugger.impl.ui; +import com.intellij.ide.DataManager; +import com.intellij.lang.Language; +import com.intellij.openapi.actionSystem.AnAction; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.DataContext; +import com.intellij.openapi.actionSystem.DefaultActionGroup; import com.intellij.openapi.editor.Document; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopup; +import com.intellij.openapi.util.IconLoader; +import com.intellij.openapi.wm.IdeFocusManager; +import com.intellij.reference.SoftReference; +import com.intellij.ui.ClickListener; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.impl.XDebuggerHistoryManager; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseEvent; +import java.lang.ref.WeakReference; +import java.util.Collection; import java.util.Collections; import java.util.List; @@ -40,6 +61,9 @@ public abstract class XDebuggerEditorBase { private final XSourcePosition mySourcePosition; private int myHistoryIndex; + private final JLabel myChooseFactory = new JLabel(); + private WeakReference myPopup; + protected XDebuggerEditorBase(final Project project, @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, @NotNull EvaluationMode mode, @@ -50,6 +74,53 @@ public abstract class XDebuggerEditorBase { myMode = mode; myHistoryId = historyId; mySourcePosition = sourcePosition; + + myChooseFactory.setToolTipText("Click to change the language"); + myChooseFactory.setBorder(new EmptyBorder(0, 3, 0, 3)); + new ClickListener() { + @Override + public boolean onClick(@NotNull MouseEvent e, int clickCount) { + ListPopup oldPopup = SoftReference.dereference(myPopup); + if (oldPopup != null && !oldPopup.isDisposed()) { + oldPopup.cancel(); + myPopup = null; + return true; + } + ListPopup popup = createLanguagePopup(); + popup.showUnderneathOf(myChooseFactory); + myPopup = new WeakReference(popup); + return true; + } + }.installOn(myChooseFactory); + } + + private ListPopup createLanguagePopup() { + DefaultActionGroup actions = new DefaultActionGroup(); + for (final Language language : getEditorsProvider().getSupportedLanguages(myProject, mySourcePosition)) { + actions.add(new AnAction(language.getDisplayName(), null, language.getAssociatedFileType().getIcon()) { + @Override + public void actionPerformed(AnActionEvent e) { + XExpression currentExpression = getExpression(); + setExpression(new XExpressionImpl(currentExpression.getExpression(), language, currentExpression.getCustomInfo())); + IdeFocusManager.getInstance(getProject()).requestFocus(getComponent(), true); + } + }); + } + + DataContext dataContext = DataManager.getInstance().getDataContext(getComponent()); + return JBPopupFactory.getInstance().createActionGroupPopup("Choose language", actions, dataContext, + JBPopupFactory.ActionSelectionAid.SPEEDSEARCH, + false); + } + + protected JPanel addChooseFactoryLabel(JComponent component, boolean top) { + JPanel panel = new JPanel(new BorderLayout()); + panel.add(component, BorderLayout.CENTER); + + JPanel factoryPanel = new JPanel(new BorderLayout()); + factoryPanel.add(myChooseFactory, top ? BorderLayout.NORTH : BorderLayout.CENTER); + panel.add(factoryPanel, BorderLayout.WEST); + return panel; } @NotNull @@ -59,14 +130,51 @@ public abstract class XDebuggerEditorBase { public abstract JComponent getComponent(); - protected abstract void doSetText(String text); + protected abstract void doSetText(XExpression text); - public void setText(String text) { + public void setExpression(@Nullable XExpression text) { + if (text == null) { + text = getMode() == EvaluationMode.EXPRESSION ? XExpressionImpl.EMPTY_EXPRESSION : XExpressionImpl.EMPTY_CODE_FRAGMENT; + } saveTextInHistory(text); + Language language = text.getLanguage(); + if (language == null) { + if (mySourcePosition != null) { + language = getFileTypeLanguage(mySourcePosition.getFile().getFileType()); + } + if (language == null) { + language = getFileTypeLanguage(getEditorsProvider().getFileType()); + } + } + text = new XExpressionImpl(text.getExpression(), language, text.getCustomInfo(), getMode()); + + Collection languages = getEditorsProvider().getSupportedLanguages(myProject, mySourcePosition); + boolean many = languages.size() > 1; + + if (language != null) { + myChooseFactory.setVisible(many); + } + myChooseFactory.setVisible(myChooseFactory.isVisible() || many); + //myChooseFactory.setEnabled(many && languages.contains(language)); + + if (language != null && language.getAssociatedFileType() != null) { + Icon icon = language.getAssociatedFileType().getIcon(); + myChooseFactory.setIcon(icon); + myChooseFactory.setDisabledIcon(IconLoader.getDisabledIcon(icon)); + } + doSetText(text); } - public abstract String getText(); + @Nullable + public static Language getFileTypeLanguage(@Nullable FileType fileType) { + if (fileType instanceof LanguageFileType) { + return ((LanguageFileType)fileType).getLanguage(); + } + return null; + } + + public abstract XExpression getExpression(); @Nullable public abstract JComponent getPreferredFocusedComponent(); @@ -76,7 +184,7 @@ public abstract class XDebuggerEditorBase { protected void onHistoryChanged() { } - protected List getRecentExpressions() { + protected List getRecentExpressions() { if (myHistoryId != null) { return XDebuggerHistoryManager.getInstance(myProject).getRecentExpressions(myHistoryId); } @@ -84,14 +192,16 @@ public abstract class XDebuggerEditorBase { } public void saveTextInHistory() { - saveTextInHistory(getText()); + saveTextInHistory(getExpression()); } - private void saveTextInHistory(final String text) { + private void saveTextInHistory(final XExpression text) { if (myHistoryId != null) { - XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(myHistoryId, text); + boolean update = XDebuggerHistoryManager.getInstance(myProject).addRecentExpression(myHistoryId, text); myHistoryIndex = 0; - onHistoryChanged(); + if (update) { + onHistoryChanged(); + } } } @@ -103,7 +213,7 @@ public abstract class XDebuggerEditorBase { return myProject; } - protected Document createDocument(final String text) { + protected Document createDocument(final XExpression text) { return getEditorsProvider().createDocument(getProject(), text, mySourcePosition, myMode); } @@ -116,7 +226,7 @@ public abstract class XDebuggerEditorBase { } public void goBackward() { - final List expressions = getRecentExpressions(); + final List expressions = getRecentExpressions(); if (myHistoryIndex < expressions.size() - 1) { myHistoryIndex++; doSetText(expressions.get(myHistoryIndex)); @@ -124,7 +234,7 @@ public abstract class XDebuggerEditorBase { } public void goForward() { - final List expressions = getRecentExpressions(); + final List expressions = getRecentExpressions(); if (myHistoryIndex > 0) { myHistoryIndex--; doSetText(expressions.get(myHistoryIndex)); diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java index 694ef28f8b37..52a38b24c1a5 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerExpressionComboBox.java @@ -19,13 +19,14 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.ComboBox; -import com.intellij.openapi.util.text.StringUtil; import com.intellij.ui.EditorComboBoxEditor; import com.intellij.ui.EditorComboBoxRenderer; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; import com.intellij.xdebugger.impl.XDebuggerHistoryManager; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -37,23 +38,23 @@ import java.awt.*; * @author nik */ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { + private final JComponent myComponent; private final ComboBox myComboBox; private EditorComboBoxEditor myEditor; - private final XDebuggerEditorsProvider myDebuggerEditorsProvider; - private String myExpression; + private XExpression myExpression; public XDebuggerExpressionComboBox(final @NotNull Project project, final @NotNull XDebuggerEditorsProvider debuggerEditorsProvider, final @Nullable @NonNls String historyId, final @Nullable XSourcePosition sourcePosition) { super(project, debuggerEditorsProvider, EvaluationMode.EXPRESSION, historyId, sourcePosition); - myDebuggerEditorsProvider = debuggerEditorsProvider; myComboBox = new ComboBox(); myComboBox.setEditable(true); - myExpression = ""; + myExpression = XExpressionImpl.EMPTY_EXPRESSION; Dimension minimumSize = new Dimension(myComboBox.getMinimumSize()); minimumSize.width = 100; myComboBox.setMinimumSize(minimumSize); initEditor(); fillComboBox(); + myComponent = addChooseFactoryLabel(myComboBox, false); } public ComboBox getComboBox() { @@ -62,7 +63,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { @Override public JComponent getComponent() { - return myComboBox; + return myComponent; } @Nullable @@ -84,24 +85,23 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { initEditor(); } else { - myExpression = getText(); + myExpression = getExpression(); } } private void initEditor() { - myEditor = new EditorComboBoxEditor(getProject(), myDebuggerEditorsProvider.getFileType()) { + myEditor = new EditorComboBoxEditor(getProject(), getEditorsProvider().getFileType()) { @Override public void setItem(Object anObject) { - super.setItem(createDocument(StringUtil.notNullize((String)anObject))); - } - - @Override - public Object getItem() { - return ((Document)super.getItem()).getText(); + if (anObject == null) { + anObject = XExpressionImpl.EMPTY_EXPRESSION; + } + super.setItem(createDocument(((XExpression)anObject))); } }; + myEditor.getEditorComponent().setFontInheritedFromLAF(false); myComboBox.setEditor(myEditor); - myEditor.setItem(myExpression); + //myEditor.setItem(myExpression); myComboBox.setRenderer(new EditorComboBoxRenderer(myEditor)); myComboBox.setMaximumRowCount(XDebuggerHistoryManager.MAX_RECENT_EXPRESSIONS); } @@ -113,7 +113,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { private void fillComboBox() { myComboBox.removeAllItems(); - for (String expression : getRecentExpressions()) { + for (XExpression expression : getRecentExpressions()) { myComboBox.addItem(expression); } if (myComboBox.getItemCount() > 0) { @@ -122,7 +122,7 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { } @Override - protected void doSetText(String text) { + protected void doSetText(XExpression text) { if (myComboBox.getItemCount() > 0) { myComboBox.setSelectedIndex(0); } @@ -130,15 +130,17 @@ public class XDebuggerExpressionComboBox extends XDebuggerEditorBase { if (myComboBox.isEditable()) { myEditor.setItem(text); } - else { - myExpression = text; - } + myExpression = text; } @Override - public String getText() { - final Object value = myComboBox.isPopupVisible() ? myComboBox.getPopup().getList().getSelectedValue() : myEditor.getItem(); - return StringUtil.notNullize((String)value); + public XExpression getExpression() { + if (myComboBox.isPopupVisible()) { + return (XExpression)myComboBox.getPopup().getList().getSelectedValue(); + } + else { + return getEditorsProvider().createExpression(getProject(), (Document)myEditor.getItem(), myExpression.getLanguage(), EvaluationMode.EXPRESSION); + } } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java index a59baafaba9b..95a698832fb3 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/XDebuggerMultilineEditor.java @@ -19,9 +19,11 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.ex.EditorEx; import com.intellij.openapi.project.Project; import com.intellij.ui.EditorTextField; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.XSourcePosition; import com.intellij.xdebugger.evaluation.EvaluationMode; import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -33,13 +35,15 @@ import javax.swing.*; */ public class XDebuggerMultilineEditor extends XDebuggerEditorBase { private final EditorTextField myEditorTextField; + private XExpression myExpression; public XDebuggerMultilineEditor(Project project, XDebuggerEditorsProvider debuggerEditorsProvider, @Nullable @NonNls String historyId, - @Nullable XSourcePosition sourcePosition, @NotNull String text) { + @Nullable XSourcePosition sourcePosition, @NotNull XExpression text) { super(project, debuggerEditorsProvider, EvaluationMode.CODE_FRAGMENT, historyId, sourcePosition); - myEditorTextField = new EditorTextField(createDocument(text), project, debuggerEditorsProvider.getFileType()) { + myExpression = XExpressionImpl.changeMode(text, getMode()); + myEditorTextField = new EditorTextField(createDocument(myExpression), project, debuggerEditorsProvider.getFileType()) { @Override protected EditorEx createEditor() { final EditorEx editor = super.createEditor(); @@ -60,13 +64,13 @@ public class XDebuggerMultilineEditor extends XDebuggerEditorBase { } @Override - protected void doSetText(String text) { - myEditorTextField.setText(text); + protected void doSetText(XExpression text) { + myEditorTextField.setText(text.getExpression()); } @Override - public String getText() { - return myEditorTextField.getText(); + public XExpression getExpression() { + return XExpressionImpl.fromText(myEditorTextField.getText(), EvaluationMode.CODE_FRAGMENT); } @Override diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java index 6667335e7b6a..fb052a410e08 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/SetValueInplaceEditor.java @@ -22,6 +22,7 @@ import com.intellij.ui.AppUIUtil; import com.intellij.ui.SimpleColoredComponent; import com.intellij.xdebugger.frame.XValueModifier; import com.intellij.xdebugger.frame.presentation.XValuePresentation; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import com.intellij.xdebugger.impl.ui.tree.nodes.XValuePresentationUtil; @@ -56,7 +57,7 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor { myEditorPanel.add(myExpressionEditor.getComponent(), BorderLayout.CENTER); final String value = myModifier != null ? myModifier.getInitialValueEditorText() : null; - myExpressionEditor.setText(value != null ? value : ""); + myExpressionEditor.setExpression(XExpressionImpl.fromText(value)); myExpressionEditor.selectAll(); } @@ -72,7 +73,7 @@ public class SetValueInplaceEditor extends XDebuggerTreeInplaceEditor { myExpressionEditor.saveTextInHistory(); final XDebuggerTreeState treeState = XDebuggerTreeState.saveState(myTree); myValueNode.setValueModificationStarted(); - myModifier.setValue(myExpressionEditor.getText(), new XValueModifier.XModificationCallback() { + myModifier.setValue(myExpressionEditor.getExpression().getExpression(), new XValueModifier.XModificationCallback() { @Override public void valueModified() { AppUIUtil.invokeOnEdt(new Runnable() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java index ddd1ec4bf159..00d803d68244 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/SortValuesToggleAction.java @@ -16,13 +16,9 @@ package com.intellij.xdebugger.impl.ui.tree.actions; import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CommonDataKeys; -import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.actionSystem.ToggleAction; import com.intellij.openapi.project.DumbAware; -import com.intellij.openapi.project.Project; -import com.intellij.xdebugger.XDebugSession; -import com.intellij.xdebugger.XDebuggerManager; +import com.intellij.xdebugger.impl.XDebuggerUtilImpl; import com.intellij.xdebugger.impl.settings.XDebuggerSettingsManager; /** @@ -37,14 +33,6 @@ public class SortValuesToggleAction extends ToggleAction implements DumbAware { @Override public void setSelected(AnActionEvent e, boolean state) { XDebuggerSettingsManager.getInstance().getDataViewSettings().setSortValues(state); - final Project project = e.getData(CommonDataKeys.PROJECT); - if (project != null) { - final XDebugSession[] sessions = XDebuggerManager.getInstance(project).getDebugSessions(); - for (XDebugSession session : sessions) { - if (session.isSuspended()) { - session.rebuildViews(); - } - } - } + XDebuggerUtilImpl.rebuildAllSessionsViews(e.getProject()); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java index eb6c1586f103..830d0fd1b02b 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XAddToWatchesAction.java @@ -16,6 +16,7 @@ package com.intellij.xdebugger.impl.ui.tree.actions; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.frame.XWatchesView; import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl; import org.jetbrains.annotations.NotNull; @@ -34,7 +35,7 @@ class XAddToWatchesAction extends XDebuggerTreeActionBase { XWatchesView watchesView = e.getData(XWatchesView.DATA_KEY); String expression = node.getValueContainer().getEvaluationExpression(); if (watchesView != null && expression != null) { - watchesView.addWatchExpression(expression, -1, true); + watchesView.addWatchExpression(XExpressionImpl.fromText(expression), -1, true); } } } \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java index df7f2e0aa7bd..3926e89ecd4c 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/actions/XFetchValueActionBase.java @@ -81,7 +81,7 @@ public abstract class XFetchValueActionBase extends AnAction { } } else if (node instanceof WatchMessageNode) { - valueCollector.add(((WatchMessageNode)node).getExpression()); + valueCollector.add(((WatchMessageNode)node).getExpression().getExpression()); } } valueCollector.processed = true; diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchMessageNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchMessageNode.java index cfa3e946ce87..71aa2fb7fc9f 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchMessageNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchMessageNode.java @@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.icons.AllIcons; import com.intellij.ui.SimpleTextAttributes; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import org.jetbrains.annotations.NotNull; @@ -27,9 +28,9 @@ import javax.swing.*; * @author nik */ public class WatchMessageNode extends MessageTreeNode implements WatchNode { - private final String myExpression; + private final XExpression myExpression; - private WatchMessageNode(XDebuggerTree tree, XDebuggerTreeNode parent, @NotNull String expression, final Icon icon) { + private WatchMessageNode(XDebuggerTree tree, XDebuggerTreeNode parent, @NotNull XExpression expression, final Icon icon) { super(tree, parent, true); myExpression = expression; setIcon(icon); @@ -37,23 +38,23 @@ public class WatchMessageNode extends MessageTreeNode implements WatchNode { @Override @NotNull - public String getExpression() { + public XExpression getExpression() { return myExpression; } - public static WatchMessageNode createMessageNode(XDebuggerTree tree, XDebuggerTreeNode parent, String expression) { + public static WatchMessageNode createMessageNode(XDebuggerTree tree, XDebuggerTreeNode parent, XExpression expression) { final WatchMessageNode node = new WatchMessageNode(tree, parent, expression, AllIcons.Debugger.Watch); - node.myText.append(expression, SimpleTextAttributes.REGULAR_ATTRIBUTES); + node.myText.append(expression.getExpression(), SimpleTextAttributes.REGULAR_ATTRIBUTES); return node; } - public static WatchMessageNode createEvaluatingNode(XDebuggerTree tree, XDebuggerTreeNode parent, String expression) { + public static WatchMessageNode createEvaluatingNode(XDebuggerTree tree, XDebuggerTreeNode parent, XExpression expression) { final WatchMessageNode node = new WatchMessageNode(tree, parent, expression, AllIcons.Debugger.Watch); node.myText.append(expression + " = ...", XDebuggerUIConstants.EVALUATING_EXPRESSION_HIGHLIGHT_ATTRIBUTES); return node; } - public static WatchMessageNode createErrorNode(XDebuggerTree tree, XDebuggerTreeNode parent, @NotNull String expression, @NotNull String errorMessage) { + public static WatchMessageNode createErrorNode(XDebuggerTree tree, XDebuggerTreeNode parent, @NotNull XExpression expression, @NotNull String errorMessage) { final WatchMessageNode node = new WatchMessageNode(tree, parent, expression, XDebuggerUIConstants.ERROR_MESSAGE_ICON); node.myText.append(expression + " = ", SimpleTextAttributes.REGULAR_ATTRIBUTES); node.myText.append(errorMessage, SimpleTextAttributes.ERROR_ATTRIBUTES); @@ -62,6 +63,6 @@ public class WatchMessageNode extends MessageTreeNode implements WatchNode { @Override public String toString() { - return myExpression; + return myExpression.getExpression(); } } diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNode.java index be265f58ba5b..415f94779110 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNode.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger.impl.ui.tree.nodes; +import com.intellij.xdebugger.XExpression; import org.jetbrains.annotations.NotNull; import javax.swing.tree.TreeNode; @@ -24,5 +25,5 @@ import javax.swing.tree.TreeNode; */ public interface WatchNode extends TreeNode { @NotNull - String getExpression(); + XExpression getExpression(); } \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java index 2c06c202da20..73bc05646b8e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchNodeImpl.java @@ -15,6 +15,7 @@ */ package com.intellij.xdebugger.impl.ui.tree.nodes; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.frame.XValue; import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree; import org.jetbrains.annotations.NotNull; @@ -23,17 +24,17 @@ import org.jetbrains.annotations.NotNull; * @author nik */ public class WatchNodeImpl extends XValueNodeImpl implements WatchNode { - private final String myExpression; + private final XExpression myExpression; public WatchNodeImpl(final @NotNull XDebuggerTree tree, final @NotNull WatchesRootNode parent, final @NotNull XValue result, - final @NotNull String expression) { - super(tree, parent, expression, result); + final @NotNull XExpression expression) { + super(tree, parent, expression.getExpression(), result); myExpression = expression; } @Override @NotNull - public String getExpression() { + public XExpression getExpression() { return myExpression; } } \ No newline at end of file diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java index f959015b6f74..204f45a4a02d 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/tree/nodes/WatchesRootNode.java @@ -16,8 +16,10 @@ package com.intellij.xdebugger.impl.ui.tree.nodes; import com.intellij.xdebugger.XDebugSession; +import com.intellij.xdebugger.XExpression; import com.intellij.xdebugger.evaluation.XDebuggerEvaluator; import com.intellij.xdebugger.frame.XValue; +import com.intellij.xdebugger.impl.breakpoints.XExpressionImpl; import com.intellij.xdebugger.impl.frame.WatchInplaceEditor; import com.intellij.xdebugger.impl.frame.XWatchesView; import com.intellij.xdebugger.impl.ui.DebuggerUIUtil; @@ -44,12 +46,12 @@ public class WatchesRootNode extends XDebuggerTreeNode { public WatchesRootNode(final @NotNull XDebuggerTree tree, @NotNull XDebugSession session, @NotNull XWatchesView watchesView, - @NotNull String[] watchExpressions) { + @NotNull XExpression[] watchExpressions) { super(tree, null, false); mySession = session; myWatchesView = watchesView; myChildren = new ArrayList(); - for (String watchExpression : watchExpressions) { + for (XExpression watchExpression : watchExpressions) { myChildren.add(WatchMessageNode.createMessageNode(tree, this, watchExpression)); } } @@ -59,7 +61,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { List newChildren = new ArrayList(); if (evaluator != null) { for (WatchNode child : myChildren) { - final String expression = child.getExpression(); + final XExpression expression = child.getExpression(); final WatchMessageNode evaluatingNode = WatchMessageNode.createEvaluatingNode(myTree, this, expression); newChildren.add(evaluatingNode); evaluator.evaluate(expression, new MyEvaluationCallback(evaluatingNode), null); @@ -67,7 +69,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { } else { for (WatchNode child : myChildren) { - final String expression = child.getExpression(); + final XExpression expression = child.getExpression(); newChildren.add(WatchMessageNode.createMessageNode(myTree, this, expression)); } } @@ -124,7 +126,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { } public void addWatchExpression(final @Nullable XDebuggerEvaluator evaluator, - final @NotNull String expression, + final @NotNull XExpression expression, int index, final boolean navigateToWatchNode) { WatchMessageNode message = evaluator != null ? WatchMessageNode.createEvaluatingNode(myTree, this, expression) : WatchMessageNode.createMessageNode(myTree, this, expression); if (index == -1) { @@ -177,7 +179,7 @@ public class WatchesRootNode extends XDebuggerTreeNode { } public void editWatch(@Nullable WatchNode node) { - WatchNode messageNode = WatchMessageNode.createMessageNode(myTree, this, ""); + WatchNode messageNode = WatchMessageNode.createMessageNode(myTree, this, XExpressionImpl.EMPTY_EXPRESSION); int index = node != null ? myChildren.indexOf(node) : -1; if (index == -1) { myChildren.add(messageNode); diff --git a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestContainer.java b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestContainer.java index 286c965ee74b..32c65d8eb6fc 100644 --- a/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestContainer.java +++ b/platform/xdebugger-impl/testSrc/com/intellij/xdebugger/XTestContainer.java @@ -40,9 +40,7 @@ public class XTestContainer { myFinished.release(); } - - public void setMessage(@NotNull String message, - final Icon icon, @NotNull final SimpleTextAttributes attributes, @Nullable XDebuggerTreeNodeHyperlink link) { + public void setMessage(@NotNull String message, Icon icon, @NotNull final SimpleTextAttributes attributes, @Nullable XDebuggerTreeNodeHyperlink link) { } public void setErrorMessage(@NotNull String message, @Nullable XDebuggerTreeNodeHyperlink link) { @@ -59,8 +57,10 @@ public class XTestContainer { } public Pair, String> waitFor(long timeout) throws InterruptedException { - if (!XDebuggerTestUtil.waitFor(myFinished, timeout)) throw new AssertionError("Waiting timed out"); - - return new Pair, String>(myChildren, myErrorMessage); + if (!XDebuggerTestUtil.waitFor(myFinished, timeout)) { + throw new AssertionError("Waiting timed out"); + } + + return Pair.create(myChildren, myErrorMessage); } } diff --git a/plugins/ant/src/META-INF/plugin.xml b/plugins/ant/src/META-INF/plugin.xml index 6917238d231d..4e9bd959c1a8 100644 --- a/plugins/ant/src/META-INF/plugin.xml +++ b/plugins/ant/src/META-INF/plugin.xml @@ -2,7 +2,7 @@ Ant Support AntSupport 1.0 - + Editing, maintaining and running ANT build scripts inside IntelliJ IDEA. JetBrains @@ -70,6 +70,9 @@ + + + diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfiguration.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfiguration.java new file mode 100644 index 000000000000..5f0d38aa1e88 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfiguration.java @@ -0,0 +1,216 @@ +/* + * 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.lang.ant.config.execution; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.Executor; +import com.intellij.execution.configurations.*; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.lang.ant.config.AntBuildTarget; +import com.intellij.lang.ant.config.AntConfiguration; +import com.intellij.lang.ant.config.impl.GlobalAntConfiguration; +import com.intellij.lang.ant.config.impl.TargetChooserDialog; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.options.ConfigurationException; +import com.intellij.openapi.options.SettingsEditor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.TextFieldWithBrowseButton; +import com.intellij.openapi.util.InvalidDataException; +import com.intellij.openapi.util.JDOMExternalizable; +import com.intellij.openapi.util.WriteExternalException; +import com.intellij.openapi.vfs.VirtualFile; +import org.jdom.Element; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import javax.swing.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class AntRunConfiguration extends LocatableConfigurationBase implements RunProfileWithCompileBeforeLaunchOption{ + private AntSettings mySettings = new AntSettings(); + + public AntRunConfiguration(Project project, + ConfigurationFactory factory, + String name) { + super(project, factory, name); + } + + @Override + public RunConfiguration clone() { + AntRunConfiguration configuration = (AntRunConfiguration)super.clone(); + configuration.mySettings = mySettings.clone(); + return configuration; + } + + @NotNull + @Override + public Module[] getModules() { + return new Module[0]; + } + + @NotNull + @Override + public SettingsEditor getConfigurationEditor() { + return new SettingsEditor() { + private String myFileUrl = null; + private String myTargetName = null; + private final JTextField myTextField = new JTextField(); + private ActionListener myActionListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + AntBuildTarget buildTarget = getTarget(); + final TargetChooserDialog dlg = new TargetChooserDialog(getProject(), buildTarget); + dlg.show(); + if (dlg.isOK()) { + myFileUrl = null; + myTargetName = null; + buildTarget = dlg.getSelectedTarget(); + if (buildTarget != null) { + final VirtualFile vFile = buildTarget.getModel().getBuildFile().getVirtualFile(); + if (vFile != null) { + myFileUrl = vFile.getUrl(); + myTargetName = buildTarget.getName(); + } + } + updateTextField(); + } + } + }; + + private void updateTextField() { + myTextField.setText(""); + if (myFileUrl != null && myTargetName != null) { + myTextField.setText(myTargetName); + } + fireEditorStateChanged(); + } + + @Override + protected void resetEditorFrom(RunConfiguration s) { + AntRunConfiguration configuration = (AntRunConfiguration)s; + myFileUrl = configuration.mySettings.myFileUrl; + myTargetName = configuration.mySettings.myTargetName; + updateTextField(); + } + + @Override + protected void applyEditorTo(RunConfiguration s) throws ConfigurationException { + AntRunConfiguration configuration = (AntRunConfiguration)s; + configuration.mySettings.myFileUrl = myFileUrl; + configuration.mySettings.myTargetName = myTargetName; + } + + @NotNull + @Override + protected JComponent createEditor() { + myTextField.setEditable(false); + return new TextFieldWithBrowseButton(myTextField, myActionListener); + } + }; + } + + @Override + public void checkConfiguration() throws RuntimeConfigurationException { + if (!AntConfiguration.getInstance(getProject()).isInitialized()) { + throw new RuntimeConfigurationException("Ant Configuration still haven't been initialized"); + } + if (getTarget() == null) + throw new RuntimeConfigurationException("Target is not specified", "Missing parameters"); + } + + @Override + public String suggestedName() { + AntBuildTarget target = getTarget(); + return target != null ? target.getDisplayName() : ""; + } + + + @Nullable + @Override + public RunProfileState getState(@NotNull Executor executor, @NotNull ExecutionEnvironment env) throws ExecutionException { + return new AntRunProfileState(env); + } + + @Override + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + mySettings.readExternal(element); + } + + @Override + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + mySettings.writeExternal(element); + } + + public AntBuildTarget getTarget() { + return GlobalAntConfiguration.getInstance().findTarget(getProject(), mySettings.myFileUrl, mySettings.myTargetName); + } + + public boolean acceptSettings(AntBuildTarget target) { + VirtualFile virtualFile = target.getModel().getBuildFile().getVirtualFile(); + if (virtualFile == null) return false; + mySettings.myFileUrl = virtualFile.getUrl(); + mySettings.myTargetName = target.getName(); + return true; + } + + public static class AntSettings implements Cloneable, JDOMExternalizable { + private static final String SETTINGS = "antsettings"; + private static final String FILE = "antfile"; + private static final String TARGET = "target"; + private String myFileUrl = null; + private String myTargetName = null; + + public AntSettings() { + } + + public AntSettings(String fileUrl, String targetName) { + myFileUrl = fileUrl; + myTargetName = targetName; + } + + @Override + public String toString() { + return myTargetName + "@" + myFileUrl; + } + + @Override + protected AntSettings clone() { + return new AntSettings(myFileUrl, myTargetName); + } + + @Override + public void readExternal(Element element) throws InvalidDataException { + element = element.getChild(SETTINGS); + if (element != null) { + myFileUrl = element.getAttributeValue(FILE); + myTargetName = element.getAttributeValue(TARGET); + } + } + + @Override + public void writeExternal(Element element) throws WriteExternalException { + if (myFileUrl != null && myTargetName != null) { + Element child = new Element(SETTINGS); + child.setAttribute(FILE, myFileUrl); + child.setAttribute(TARGET, myTargetName); + element.addContent(child); + } + } + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfigurationType.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfigurationType.java new file mode 100644 index 000000000000..d5dde7d05a08 --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunConfigurationType.java @@ -0,0 +1,70 @@ +/* + * 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.lang.ant.config.execution; + +import com.intellij.execution.configurations.ConfigurationFactory; +import com.intellij.execution.configurations.ConfigurationType; +import com.intellij.execution.configurations.ConfigurationTypeUtil; +import com.intellij.execution.configurations.RunConfiguration; +import com.intellij.openapi.project.Project; +import icons.AntIcons; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; + +public class AntRunConfigurationType implements ConfigurationType { + private final ConfigurationFactory myFactory = new ConfigurationFactory(this) { + @Override + public RunConfiguration createTemplateConfiguration(Project project) { + return new AntRunConfiguration(project, this, ""); + } + }; + + public static AntRunConfigurationType getInstance() { + return ConfigurationTypeUtil.findConfigurationType(AntRunConfigurationType.class); + } + + + @Override + public String getDisplayName() { + return "Ant Target"; + } + + @Override + public String getConfigurationTypeDescription() { + return "Run Ant Target"; + } + + @Override + public Icon getIcon() { + return AntIcons.Build; + } + + @NotNull + @Override + public String getId() { + return "AntRunConfiguration"; + } + + @Override + public ConfigurationFactory[] getConfigurationFactories() { + return new ConfigurationFactory[]{myFactory}; + } + + public ConfigurationFactory getFactory() { + return myFactory; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunProfileState.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunProfileState.java new file mode 100644 index 000000000000..14ab1f752cec --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunProfileState.java @@ -0,0 +1,62 @@ +/* + * 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.lang.ant.config.execution; + +import com.intellij.execution.DefaultExecutionResult; +import com.intellij.execution.ExecutionException; +import com.intellij.execution.ExecutionResult; +import com.intellij.execution.Executor; +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.ProgramRunner; +import com.intellij.lang.ant.config.AntBuildListener; +import com.intellij.lang.ant.config.AntBuildTarget; +import com.intellij.lang.ant.config.impl.BuildFileProperty; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.ArrayList; + +public class AntRunProfileState implements RunProfileState { + private final ExecutionEnvironment myEnvironment; + + public AntRunProfileState(ExecutionEnvironment environment) { + myEnvironment = environment; + } + + @Nullable + @Override + public ExecutionResult execute(Executor executor, @NotNull ProgramRunner runner) throws ExecutionException { + RunProfile profile = myEnvironment.getRunProfile(); + if (profile instanceof AntRunConfiguration) { + AntRunConfiguration antRunConfiguration = (AntRunConfiguration)profile; + AntBuildTarget target = antRunConfiguration.getTarget(); + if (target == null) return null; + ProcessHandler processHandler = ExecutionHandler + .runTarget(antRunConfiguration, myEnvironment.getDataContext(), new ArrayList(), new AntBuildListener() { + @Override + public void buildFinished(int state, int errorCount) { + + } + }); + if (processHandler == null) return null; + return new DefaultExecutionResult(null, processHandler); + } + return null; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java new file mode 100644 index 000000000000..1398718e293a --- /dev/null +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/AntRunner.java @@ -0,0 +1,54 @@ +/* + * 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.lang.ant.config.execution; + +import com.intellij.execution.ExecutionException; +import com.intellij.execution.configurations.RunProfile; +import com.intellij.execution.configurations.RunProfileState; +import com.intellij.execution.executors.DefaultRunExecutor; +import com.intellij.execution.runners.ExecutionEnvironment; +import com.intellij.execution.runners.GenericProgramRunner; +import com.intellij.execution.ui.RunContentDescriptor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class AntRunner extends GenericProgramRunner { + public static final String EXECUTOR_ID = "AntRunConfigurationRunner"; + + @Nullable + @Override + protected RunContentDescriptor doExecute(@NotNull Project project, + @NotNull RunProfileState state, + @Nullable RunContentDescriptor contentToReuse, + @NotNull ExecutionEnvironment environment) throws ExecutionException { + FileDocumentManager.getInstance().saveAllDocuments(); + state.execute(environment.getExecutor(), this); + return null; + } + + @NotNull + @Override + public String getRunnerId() { + return EXECUTOR_ID; + } + + @Override + public boolean canRun(@NotNull String executorId, @NotNull RunProfile profile) { + return DefaultRunExecutor.EXECUTOR_ID.equals(executorId) && profile instanceof AntRunConfiguration; + } +} diff --git a/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java b/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java index a0a075fa74c9..85f1c390e7f1 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/execution/ExecutionHandler.java @@ -22,10 +22,7 @@ import com.intellij.execution.configurations.CommandLineBuilder; import com.intellij.execution.configurations.GeneralCommandLine; import com.intellij.execution.junit.JUnitProcessHandler; import com.intellij.execution.junit2.segments.OutputPacketProcessor; -import com.intellij.execution.process.OSProcessHandler; -import com.intellij.execution.process.ProcessAdapter; -import com.intellij.execution.process.ProcessEvent; -import com.intellij.execution.process.ProcessOutputTypes; +import com.intellij.execution.process.*; import com.intellij.execution.testframework.Printable; import com.intellij.execution.testframework.Printer; import com.intellij.execution.util.ExecutionErrorDialog; @@ -34,6 +31,7 @@ import com.intellij.ide.macro.Macro; import com.intellij.lang.ant.AntBundle; import com.intellij.lang.ant.config.AntBuildFileBase; import com.intellij.lang.ant.config.AntBuildListener; +import com.intellij.lang.ant.config.AntBuildTarget; import com.intellij.lang.ant.config.impl.BuildFileProperty; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.application.ApplicationManager; @@ -44,10 +42,11 @@ import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.Task; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VfsUtil; +import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.encoding.EncodingProjectManager; import com.intellij.openapi.wm.StatusBar; import com.intellij.openapi.wm.WindowManager; +import com.intellij.util.concurrency.FutureResult; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,6 +62,31 @@ public final class ExecutionHandler { private ExecutionHandler() { } + @Nullable + public static ProcessHandler runTarget(AntRunConfiguration antRunConfiguration, + final DataContext dataContext, + List additionalProperties, @NotNull final AntBuildListener antBuildListener) { + AntBuildTarget target = antRunConfiguration.getTarget(); + if (target == null) return null; + FutureResult result = runBuildImpl((AntBuildFileBase)target.getModel().getBuildFile(), + new String[]{target.getName()}, + null, + dataContext, + additionalProperties, antBuildListener); + if (result != null) { + try { + return result.get(); + } + catch (InterruptedException e) { + LOG.warn(e); + } + catch (java.util.concurrent.ExecutionException e) { + LOG.warn(e); + } + } + return null; + } + /** * @param antBuildListener should not be null. Use {@link com.intellij.lang.ant.config.AntBuildListener#NULL} */ @@ -71,6 +95,34 @@ public final class ExecutionHandler { @Nullable final AntBuildMessageView buildMessageViewToReuse, final DataContext dataContext, List additionalProperties, @NotNull final AntBuildListener antBuildListener) { + FutureResult futureResult = + runBuildImpl(buildFile, targets, buildMessageViewToReuse, dataContext, additionalProperties, antBuildListener); + if (futureResult != null) { + try { + ProcessHandler processHandler = futureResult.get(); + if (processHandler != null) { + processHandler.waitFor(); + } + } + catch (InterruptedException e) { + LOG.warn(e); + } + catch (java.util.concurrent.ExecutionException e) { + LOG.warn(e); + } + } + } + + /** + * @param antBuildListener should not be null. Use {@link com.intellij.lang.ant.config.AntBuildListener#NULL} + */ + @Nullable + public static FutureResult runBuildImpl(final AntBuildFileBase buildFile, + String[] targets, + @Nullable final AntBuildMessageView buildMessageViewToReuse, + final DataContext dataContext, + List additionalProperties, + @NotNull final AntBuildListener antBuildListener) { final AntBuildMessageView messageView; final GeneralCommandLine commandLine; final Project project = buildFile.getProject(); @@ -78,7 +130,7 @@ public final class ExecutionHandler { FileDocumentManager.getInstance().saveAllDocuments(); final AntCommandLineBuilder builder = new AntCommandLineBuilder(); - builder.setBuildFile(buildFile.getAllOptions(), VfsUtil.virtualToIoFile(buildFile.getVirtualFile())); + builder.setBuildFile(buildFile.getAllOptions(), VfsUtilCore.virtualToIoFile(buildFile.getVirtualFile())); builder.calculateProperties(dataContext, additionalProperties); builder.addTargets(targets); @@ -89,25 +141,25 @@ public final class ExecutionHandler { messageView.setBuildCommandLine(commandLine.getCommandLineString()); } catch (RunCanceledException e) { - e.showMessage(project, AntBundle.message("run.ant.erorr.dialog.title")); + e.showMessage(project, AntBundle.message("run.ant.error.dialog.title")); antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); - return; + return null; } catch (CantRunException e) { - ExecutionErrorDialog.show(e, AntBundle.message("cant.run.ant.erorr.dialog.title"), project); + ExecutionErrorDialog.show(e, AntBundle.message("cant.run.ant.error.dialog.title"), project); antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); - return; + return null; } catch (Macro.ExecutionCancelledException e) { antBuildListener.buildFinished(AntBuildListener.ABORTED, 0); - return; + return null; } catch (Throwable e) { antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); LOG.error(e); - return; + return null; } - + final FutureResult future = new FutureResult(); new Task.Backgroundable(buildFile.getProject(), AntBundle.message("ant.build.progress.dialog.title"), true) { public boolean shouldStartInBackground() { @@ -116,11 +168,12 @@ public final class ExecutionHandler { public void onCancel() { antBuildListener.buildFinished(AntBuildListener.ABORTED, 0); + future.set(null); } public void run(@NotNull final ProgressIndicator indicator) { try { - runBuild(indicator, messageView, buildFile, antBuildListener, commandLine); + future.set(runBuild(indicator, messageView, buildFile, antBuildListener, commandLine)); } catch (Throwable e) { LOG.error(e); @@ -128,13 +181,15 @@ public final class ExecutionHandler { } } }.queue(); + return future; } - private static void runBuild(final ProgressIndicator progress, - @NotNull final AntBuildMessageView errorView, - @NotNull final AntBuildFileBase buildFile, - @NotNull final AntBuildListener antBuildListener, - @NotNull GeneralCommandLine commandLine) { + @Nullable + private static ProcessHandler runBuild(final ProgressIndicator progress, + @NotNull final AntBuildMessageView errorView, + @NotNull final AntBuildFileBase buildFile, + @NotNull final AntBuildListener antBuildListener, + @NotNull GeneralCommandLine commandLine) { final Project project = buildFile.getProject(); final long startTime = System.currentTimeMillis(); @@ -146,15 +201,15 @@ public final class ExecutionHandler { catch (final ExecutionException e) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { - ExecutionErrorDialog.show(e, AntBundle.message("could.not.start.process.erorr.dialog.title"), project); + ExecutionErrorDialog.show(e, AntBundle.message("could.not.start.process.error.dialog.title"), project); } }); antBuildListener.buildFinished(AntBuildListener.FAILED_TO_RUN, 0); - return; + return null; } processRunningAnt(progress, handler, errorView, buildFile, startTime, antBuildListener); - handler.waitFor(); + return handler; } private static void processRunningAnt(final ProgressIndicator progress, diff --git a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java index 1f8fa6091678..6d9a055a4f2b 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/explorer/AntExplorer.java @@ -15,8 +15,9 @@ */ package com.intellij.lang.ant.config.explorer; -import com.intellij.execution.RunManagerAdapter; -import com.intellij.execution.RunManagerEx; +import com.intellij.execution.*; +import com.intellij.execution.impl.RunDialog; +import com.intellij.execution.impl.RunManagerImpl; import com.intellij.icons.AllIcons; import com.intellij.ide.CommonActionsManager; import com.intellij.ide.DataManager; @@ -27,6 +28,8 @@ import com.intellij.lang.ant.AntBundle; import com.intellij.lang.ant.config.*; import com.intellij.lang.ant.config.actions.AntBuildFilePropertiesAction; import com.intellij.lang.ant.config.actions.RemoveBuildFileAction; +import com.intellij.lang.ant.config.execution.AntRunConfiguration; +import com.intellij.lang.ant.config.execution.AntRunConfigurationType; import com.intellij.lang.ant.config.execution.ExecutionHandler; import com.intellij.lang.ant.config.impl.*; import com.intellij.lang.ant.config.impl.configuration.BuildFilePropertiesPanel; @@ -57,6 +60,7 @@ import com.intellij.util.ui.tree.TreeUtil; import com.intellij.util.xml.DomEventListener; import com.intellij.util.xml.DomManager; import com.intellij.util.xml.events.DomEvent; +import icons.AntIcons; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.Nullable; @@ -398,6 +402,7 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, final DefaultActionGroup group = new DefaultActionGroup(); group.add(new RunAction()); group.add(new CreateMetaTargetAction()); + group.add(new MakeAntRunConfigurationAction()); group.add(new RemoveMetaTargetsOrBuildFileAction()); group.add(ActionManager.getInstance().getAction(IdeActions.ACTION_EDIT_SOURCE)); if (userObject instanceof AntBuildFileNodeDescriptor) { @@ -582,6 +587,59 @@ public class AntExplorer extends SimpleToolWindowPanel implements DataProvider, presentation.setEnabled(canRunSelection()); } } + private final class MakeAntRunConfigurationAction extends AnAction { + public MakeAntRunConfigurationAction() { + super(AntBundle.message("make.ant.runconfiguration.name"), null, AntIcons.Build); + } + + @Override + public void update(AnActionEvent e) { + super.update(e); + + final Presentation presentation = e.getPresentation(); + presentation.setEnabled(myTree.getSelectionCount() == 1 && canRunSelection()); + } + + @Override + public void actionPerformed(AnActionEvent e) { + final AntBuildFile buildFile = getCurrentBuildFile(); + if (buildFile == null || !buildFile.exists()) { + return; + } + + TreePath selectionPath = myTree.getSelectionPath(); + if (selectionPath == null) return; + final DefaultMutableTreeNode node = (DefaultMutableTreeNode) selectionPath.getLastPathComponent(); + final Object userObject = node.getUserObject(); + AntBuildTarget target = null; + if (userObject instanceof AntTargetNodeDescriptor) { + AntTargetNodeDescriptor targetNodeDescriptor = (AntTargetNodeDescriptor)userObject; + target = targetNodeDescriptor.getTarget(); + } + else if (userObject instanceof AntBuildFileNodeDescriptor){ + AntBuildModel model = ((AntBuildFileNodeDescriptor)userObject).getBuildFile().getModel(); + target = model.findTarget(model.getDefaultTargetName()); + } + String name = target != null ? target.getDisplayName() : null; + if (target == null || name == null) { + return; + } + + RunManagerImpl runManager = (RunManagerImpl)RunManager.getInstance(e.getProject()); + RunnerAndConfigurationSettings settings = + runManager.createRunConfiguration(name, AntRunConfigurationType.getInstance().getFactory()); + AntRunConfiguration configuration = (AntRunConfiguration)settings.getConfiguration(); + configuration.acceptSettings(target); + if (RunDialog.editConfiguration(e.getProject(), settings, ExecutionBundle + .message("create.run.configuration.for.item.dialog.title", configuration.getName()))) { + runManager.addConfiguration(settings, + runManager.isConfigurationShared(settings), + runManager.getBeforeRunTasks(settings.getConfiguration()), false); + runManager.setSelectedConfiguration(settings); + } + } + } + private final class ShowAllTargetsAction extends ToggleAction { public ShowAllTargetsAction() { diff --git a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBeforeRunTaskProvider.java b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBeforeRunTaskProvider.java index 0201736f89ea..57e5d175addd 100644 --- a/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBeforeRunTaskProvider.java +++ b/plugins/ant/src/com/intellij/lang/ant/config/impl/AntBeforeRunTaskProvider.java @@ -20,15 +20,13 @@ import com.intellij.execution.RunManagerEx; import com.intellij.execution.configurations.RunConfiguration; import com.intellij.execution.runners.ExecutionEnvironment; import com.intellij.lang.ant.AntBundle; -import com.intellij.lang.ant.config.AntBuildFile; import com.intellij.lang.ant.config.AntBuildTarget; -import com.intellij.lang.ant.config.AntConfiguration; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Key; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.openapi.vfs.VirtualFileManager; import icons.AntIcons; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; @@ -115,32 +113,8 @@ public class AntBeforeRunTaskProvider extends BeforeRunTaskProvider " + + "" + myProject + ((myDescription != null) ? ": " + myDescription : "") + "" + + "\nDetails: " + getErrorMessage(myException) + + "" + ).replaceAll("\r\n|\n\r|\n|\r", EOL_TAG) + ); + } + + + private static String getErrorMessage(@NotNull Throwable e) { + StringBuilder buf = new StringBuilder(); + Throwable cause = e; + while (cause != null) { + if (buf.length() != 0) { + buf.append("\nCaused by: "); + } + buf.append(cause.getClass().getName()).append(": ").append(cause.getMessage()); + cause = cause.getCause(); + } + return buf.toString(); + } +} diff --git a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java b/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java index d87f5d59d416..cd29943a4b0b 100644 --- a/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java +++ b/plugins/gradle/tooling-extension-api/src/org/jetbrains/plugins/gradle/tooling/ModelBuilderService.java @@ -28,5 +28,5 @@ public interface ModelBuilderService { Object buildAll(String modelName, Project project); @NotNull - ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e); + ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e); } diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java index d3880889b493..ce6c0df5a9bf 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModelBuildScriptClasspathBuilderImpl.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel; import org.jetbrains.plugins.gradle.model.ClasspathEntryModel; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.internal.BuildScriptClasspathModelImpl; import org.jetbrains.plugins.gradle.tooling.internal.ClasspathEntryModelImpl; @@ -102,13 +102,10 @@ public class ModelBuildScriptClasspathBuilderImpl implements ModelBuilderService @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError( - "Project build classpath resolve errors", - String.format( - "%s\nCodeInsight feature may not work for gradle build script of %s", - e.getMessage(), project) - ); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create( + project, e, "Project build classpath resolve errors" + ).withDescription("Some codeInsight features may not work for gradle build script"); } private static Set convert(Set paths) { diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModuleExtendedModelBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModuleExtendedModelBuilderImpl.java index cbaa239f115b..2d3d79cefb3c 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModuleExtendedModelBuilderImpl.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ModuleExtendedModelBuilderImpl.java @@ -28,7 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot; import org.jetbrains.plugins.gradle.model.ModuleExtendedModel; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.internal.IdeaContentRootImpl; import org.jetbrains.plugins.gradle.tooling.internal.IdeaSourceDirectoryImpl; @@ -170,13 +170,10 @@ public class ModuleExtendedModelBuilderImpl implements ModelBuilderService { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError( - "Other", - String.format( - "%s\nUnable to resolve all content root directories for %s", - e.getMessage(), project) - ); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create( + project, e, "Other" + ).withDescription("Unable to resolve all content root directories"); } private static boolean isTestDir(SourceSet sourceSet, List testClassesDirs) { diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ScalaModelBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ScalaModelBuilderImpl.java index e3daad68ca2f..1f7b1ef25e60 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ScalaModelBuilderImpl.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/ScalaModelBuilderImpl.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.scala.ScalaModel; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.internal.scala.ScalaCompileOptionsImpl; import org.jetbrains.plugins.gradle.tooling.internal.scala.ScalaForkOptionsImpl; @@ -68,13 +68,10 @@ public class ScalaModelBuilderImpl implements ModelBuilderService { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError( - "Scala import errors", - String.format( - "%s\nUnable to build Scala gradle configuration for %s", - e.getMessage(), project) - ); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create( + project, e, "Scala import errors" + ).withDescription("Unable to build Scala project configuration"); } @Nullable diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java index 29d4a472ca0e..62e02eeffc17 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/builder/WarModelBuilderImpl.java @@ -27,7 +27,7 @@ import org.gradle.api.tasks.bundling.War; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.plugins.gradle.model.web.WebConfiguration; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.internal.web.WarModelImpl; import org.jetbrains.plugins.gradle.tooling.internal.web.WebConfigurationImpl; @@ -125,13 +125,10 @@ public class WarModelBuilderImpl implements ModelBuilderService { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError( - "Web project import errors", - String.format( - "%s\nWeb Facets/Artifacts will not be configured for %s", - e.getMessage(), project) - ); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create( + project, e, "Web project import errors" + ).withDescription("Web Facets/Artifacts will not be configured"); } private static void addPath(List webResources, String warRelativePath, String fileRelativePath, File file) { diff --git a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilder.java b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilder.java index 35dad8437605..6695d84b3190 100644 --- a/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilder.java +++ b/plugins/gradle/tooling-extension-impl/src/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilder.java @@ -20,11 +20,10 @@ import org.gradle.tooling.provider.model.ToolingModelBuilder; import org.gradle.util.GradleVersion; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.TestOnly; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions; -import java.io.File; import java.util.ServiceLoader; /** @@ -33,10 +32,6 @@ import java.util.ServiceLoader; */ @SuppressWarnings("UnusedDeclaration") public class ExtraModelBuilder implements ToolingModelBuilder { - public static final String GROUP_TAG = ""; - public static final String NAV_TAG = ""; - public static final String EOL_TAG = ""; - private static final String RANGE_TOKEN = " <=> "; private static ServiceLoader buildersLoader = ServiceLoader.load(ModelBuilderService.class, ExtraModelBuilder.class.getClassLoader()); @@ -69,16 +64,8 @@ public class ExtraModelBuilder implements ToolingModelBuilder { return service.buildAll(modelName, project); } catch (Exception e) { - ModelBuilderError builderError = service.getModelBuildError(project, e); - String group = builderError.getGroup().replaceAll("\r\n|\n\r|\n|\r", " "); - String msg = builderError.getError().replaceAll("\r\n|\n\r|\n|\r", EOL_TAG); - final File projectBuildFile = project.getBuildFile(); - - project.getLogger().error( - GROUP_TAG + group + GROUP_TAG + - (projectBuildFile != null ? (NAV_TAG + projectBuildFile.getPath() + NAV_TAG) : "") + - msg - ); + ErrorMessageBuilder builderError = service.getErrorMessageBuilder(project, e); + project.getLogger().error(builderError.build()); } return null; } diff --git a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilderTest.java b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilderTest.java index 05e4d735a3b5..40b215962873 100644 --- a/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilderTest.java +++ b/plugins/gradle/tooling-extension-impl/testSources/org/jetbrains/plugins/gradle/tooling/internal/ExtraModelBuilderTest.java @@ -18,7 +18,7 @@ package org.jetbrains.plugins.gradle.tooling.internal; import org.gradle.api.Project; import org.gradle.util.GradleVersion; import org.jetbrains.annotations.NotNull; -import org.jetbrains.plugins.gradle.tooling.ModelBuilderError; +import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder; import org.jetbrains.plugins.gradle.tooling.ModelBuilderService; import org.jetbrains.plugins.gradle.tooling.annotation.TargetVersions; import org.junit.Test; @@ -80,8 +80,8 @@ public class ExtraModelBuilderTest { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError("", ""); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create(project, e, ""); } } @@ -99,8 +99,8 @@ public class ExtraModelBuilderTest { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError("", ""); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create(project, e, ""); } } @@ -118,8 +118,8 @@ public class ExtraModelBuilderTest { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError("", ""); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create(project, e, ""); } } @@ -137,8 +137,8 @@ public class ExtraModelBuilderTest { @NotNull @Override - public ModelBuilderError getModelBuildError(@NotNull Project project, @NotNull Exception e) { - return new ModelBuilderError("", ""); + public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) { + return ErrorMessageBuilder.create(project, e, ""); } } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java index 9da4d88dc4db..2eb3676822ba 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyPsiElementFactoryImpl.java @@ -412,7 +412,7 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory { return ((GrNewExpression)initializer).getReferenceElement(); } catch (RuntimeException e) { - throw new IncorrectOperationException("reference text=" + qName, e); + throw new IncorrectOperationException("reference text=" + qName, (Throwable)e); } } diff --git a/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/JiraRepository.java b/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/JiraRepository.java index 582400c0d3dc..c5a469a40c33 100644 --- a/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/JiraRepository.java +++ b/plugins/tasks/tasks-core/jira/src/com/intellij/tasks/jira/JiraRepository.java @@ -159,8 +159,11 @@ public class JiraRepository extends BaseRepositoryImpl { } catch (Exception e) { // probably JIRA version prior 4.2 - // without hasBeenUsed() check getStatusCode() might throw NPE, if connection was refused - if (method.hasBeenUsed() && method.getStatusCode() == HttpStatus.SC_NOT_FOUND) { + // It's not safe to call HttpMethod.getStatusCode() directly, because it will throw NPE + // if response was not received (connection lost etc.) and hasBeenUsed()/isRequestSent() are + // not the way to check it safely. + StatusLine status = method.getStatusLine(); + if (status != null && status.getStatusCode() == HttpStatus.SC_NOT_FOUND) { return new JiraSoapApi(this); } else { diff --git a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java index b0da25f4290f..de22555f9b70 100644 --- a/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java +++ b/plugins/ui-designer/src/com/intellij/uiDesigner/actions/AbstractCreateFormAction.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,11 +18,15 @@ package com.intellij.uiDesigner.actions; import com.intellij.ide.IdeView; import com.intellij.ide.actions.CreateElementActionBase; -import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.actionSystem.CommonDataKeys; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.ProjectFileIndex; import com.intellij.openapi.roots.ProjectRootManager; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.JavaDirectoryService; import com.intellij.psi.PsiDirectory; @@ -34,7 +38,6 @@ import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes; import javax.swing.*; import java.io.IOException; -import java.io.InputStream; /** * @author yole @@ -65,25 +68,17 @@ public abstract class AbstractCreateFormAction extends CreateElementActionBase i } } - protected String createFormBody(@Nullable final String fullQualifiedClassName, @NonNls final String formName, - final String layoutManager) throws IncorrectOperationException { - - final InputStream inputStream = getClass().getResourceAsStream(formName); - - final StringBuffer buffer = new StringBuffer(); + protected String createFormBody(@Nullable String fqn, @NonNls String formName, String layoutManager) throws IncorrectOperationException { + String s; try { - for (int ch; (ch = inputStream.read()) != -1;) { - buffer.append((char)ch); - } + s = FileUtil.loadTextAndClose(getClass().getResourceAsStream(formName)); } catch (IOException e) { - throw new IncorrectOperationException(UIDesignerBundle.message("error.cannot.read", formName),e); + throw new IncorrectOperationException(UIDesignerBundle.message("error.cannot.read", formName), (Throwable)e); } - String s = buffer.toString(); - - if (fullQualifiedClassName != null) { - s = StringUtil.replace(s, "$CLASS$", fullQualifiedClassName); + if (fqn != null) { + s = StringUtil.replace(s, "$CLASS$", fqn); } else { s = StringUtil.replace(s, "bind-to-class=\"$CLASS$\"", ""); diff --git a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java index 3b0392f350a6..da041f961f80 100644 --- a/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java +++ b/python/src/com/jetbrains/python/run/PythonRunConfigurationForm.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2013 JetBrains s.r.o. + * Copyright 2000-2014 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -64,8 +64,8 @@ public class PythonRunConfigurationForm implements PythonRunConfigurationParams, chooserDescriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) { @Override - protected void onFileChoosen(@NotNull VirtualFile chosenFile) { - super.onFileChoosen(chosenFile); + protected void onFileChosen(@NotNull VirtualFile chosenFile) { + super.onFileChosen(chosenFile); myCommonOptionsForm.setWorkingDirectory(chosenFile.getParent().getPath()); } }; diff --git a/resources-en/src/messages/AntBundle.properties b/resources-en/src/messages/AntBundle.properties index 80d351f7e6e2..8c98c67e4997 100644 --- a/resources-en/src/messages/AntBundle.properties +++ b/resources-en/src/messages/AntBundle.properties @@ -46,9 +46,9 @@ cancel.button=Cancel background.button=&Background ant.build.progress.dialog.title=Ant Build Progress ant.build.local.history.label=Running Ant: ''{0}'' -run.ant.erorr.dialog.title=Run ANT -cant.run.ant.erorr.dialog.title=Cannot Run ANT -could.not.start.process.erorr.dialog.title=Could Not Start Process +run.ant.error.dialog.title=Run ANT +cant.run.ant.error.dialog.title=Cannot Run ANT +could.not.start.process.error.dialog.title=Could Not Start Process ant.build.started.status.message=Ant build started canceled.by.user.error.message=Canceled by user user.inout.request.ant.build.input.dialog.title=Ant Build Input @@ -76,6 +76,7 @@ run.ant.file.or.target.action.description=Run the selected build file or selecte run.ant.build.action.name=Run Build run.ant.target.action.name=Run Target run.ant.targets.action.name=Run Targets +make.ant.runconfiguration.name=Create run configuration filter.ant.targets.action.name=Filter targets filter.ant.targets.action.description=Filter targets executes.before.run.debug.acton.name=Before Run/Debug... diff --git a/resources/src/META-INF/IdeaPlugin.xml b/resources/src/META-INF/IdeaPlugin.xml index 594ff9711bbb..a8b8a240affe 100644 --- a/resources/src/META-INF/IdeaPlugin.xml +++ b/resources/src/META-INF/IdeaPlugin.xml @@ -90,6 +90,9 @@ + + diff --git a/resources/src/idea/JavaActions.xml b/resources/src/idea/JavaActions.xml index d22afe07318a..7e17aae5945d 100644 --- a/resources/src/idea/JavaActions.xml +++ b/resources/src/idea/JavaActions.xml @@ -102,9 +102,17 @@ + + - + + + + + + + @@ -115,6 +123,7 @@ + @@ -146,11 +155,18 @@ - + + + - - + + + + + + + @@ -159,8 +175,10 @@ - - + + + + @@ -218,7 +236,7 @@ - + @@ -238,7 +256,7 @@ - + @@ -259,7 +277,7 @@ - + @@ -301,7 +319,7 @@ - + diff --git a/xml/impl/resources/com/intellij/codeInsight/completion/HtmlTextCompletionConfidence.java b/xml/impl/src/com/intellij/codeInsight/completion/HtmlTextCompletionConfidence.java similarity index 100% rename from xml/impl/resources/com/intellij/codeInsight/completion/HtmlTextCompletionConfidence.java rename to xml/impl/src/com/intellij/codeInsight/completion/HtmlTextCompletionConfidence.java diff --git a/xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java b/xml/impl/src/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java similarity index 100% rename from xml/impl/resources/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java rename to xml/impl/src/com/intellij/codeInsight/completion/TagNameReferenceCompletionProvider.java diff --git a/xml/impl/resources/com/intellij/codeInsight/completion/XmlNameCompletionConfidence.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlNameCompletionConfidence.java similarity index 100% rename from xml/impl/resources/com/intellij/codeInsight/completion/XmlNameCompletionConfidence.java rename to xml/impl/src/com/intellij/codeInsight/completion/XmlNameCompletionConfidence.java