mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge commit 'origin/master'
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
<project name="IntelliJ IDEA Community Edition" default="all">
|
||||
<property name="project.home" value="${basedir}"/>
|
||||
<property name="out.dir" value="${project.home}/out"/>
|
||||
<property name="tmp.dir" value="${project.home}/out/tmp"/>
|
||||
<property name="gant.home" value="${project.home}/build/lib/gant"/>
|
||||
|
||||
<target name="cleanup">
|
||||
@@ -9,6 +10,7 @@
|
||||
|
||||
<target name="init">
|
||||
<mkdir dir="${out.dir}"/>
|
||||
<mkdir dir="${tmp.dir}"/>
|
||||
</target>
|
||||
|
||||
<macrodef name="call_gant">
|
||||
@@ -17,6 +19,8 @@
|
||||
<java failonerror="true" classname="org.apache.tools.ant.Main" fork="true">
|
||||
<jvmarg line="-Xms64m -Xmx512m"/>
|
||||
<jvmarg line=""-Dgant.script=@{script}""/>
|
||||
<jvmarg line=""-Dteamcity.build.tempDir=${tmp.dir}""/>
|
||||
<jvmarg line=""-Didea.test.group=ALL_EXCLUDE_DEFINED""/>
|
||||
|
||||
<classpath>
|
||||
<fileset dir="${project.home}/lib/ant/lib">
|
||||
@@ -37,5 +41,9 @@
|
||||
<call_gant script="${project.home}/build/scripts/dist.gant"/>
|
||||
</target>
|
||||
|
||||
<target name="test" depends="init">
|
||||
<call_gant script="${project.home}/build/scripts/tests.gant"/>
|
||||
</target>
|
||||
|
||||
<target name="all" depends="cleanup,build"/>
|
||||
</project>
|
||||
|
||||
@@ -28,7 +28,6 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.cls.BytePointer;
|
||||
import com.intellij.util.cls.ClsFormatException;
|
||||
import com.intellij.util.cls.ClsUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -54,7 +53,8 @@ public class ClassFileReader {
|
||||
private final SymbolTable mySymbolTable;
|
||||
private AnnotationConstantValue[] myRuntimeVisibleAnnotations;
|
||||
private AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
|
||||
@NonNls private static final String CONSTRUCTOR_NAME = "<init>";
|
||||
private static final String CONSTRUCTOR_NAME = "<init>";
|
||||
private boolean myParsingDone;
|
||||
|
||||
public ClassFileReader(@NotNull File file, SymbolTable symbolTable, @Nullable final byte[] fileContent) {
|
||||
mySymbolTable = symbolTable;
|
||||
@@ -72,20 +72,19 @@ public class ClassFileReader {
|
||||
}
|
||||
|
||||
public MethodInfo[] getMethods() throws ClsFormatException{
|
||||
if (myMethods == null) {
|
||||
parseMembers();
|
||||
}
|
||||
parseMembers();
|
||||
return myMethods.toArray(new MethodInfo[myMethods.size()]);
|
||||
}
|
||||
|
||||
public FieldInfo[] getFields() throws ClsFormatException{
|
||||
if (myFields == null) {
|
||||
parseMembers();
|
||||
}
|
||||
parseMembers();
|
||||
return myFields.toArray(new FieldInfo[myFields.size()]);
|
||||
}
|
||||
|
||||
private void parseMembers() throws ClsFormatException {
|
||||
if (myParsingDone) {
|
||||
return;
|
||||
}
|
||||
initConstantPool();
|
||||
myMethods = new ArrayList<MethodInfo>();
|
||||
myFields = new ArrayList<FieldInfo>();
|
||||
@@ -121,6 +120,7 @@ public class ClassFileReader {
|
||||
myGenericSignature = attributeTable.genericSignature;
|
||||
myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations;
|
||||
myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations;
|
||||
myParsingDone = true;
|
||||
}
|
||||
|
||||
private String getSymbol(final int id) throws ClsFormatException {
|
||||
@@ -253,43 +253,27 @@ public class ClassFileReader {
|
||||
|
||||
|
||||
public String getSourceFileName() throws ClsFormatException {
|
||||
if (mySourceFileName == null) {
|
||||
parseMembers();
|
||||
if (mySourceFileName == null) {
|
||||
mySourceFileName = "";
|
||||
}
|
||||
}
|
||||
return mySourceFileName;
|
||||
parseMembers();
|
||||
final String fName = mySourceFileName;
|
||||
return fName != null? fName : "";
|
||||
}
|
||||
|
||||
public String getGenericSignature() throws ClsFormatException {
|
||||
if (myGenericSignature == null) {
|
||||
parseMembers();
|
||||
if (myGenericSignature == null) {
|
||||
myGenericSignature = "";
|
||||
}
|
||||
}
|
||||
return myGenericSignature.length() == 0 ? null : myGenericSignature;
|
||||
parseMembers();
|
||||
final String genericSignature = myGenericSignature;
|
||||
return genericSignature != null && !genericSignature.isEmpty() ? genericSignature : null;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException {
|
||||
if (myRuntimeVisibleAnnotations == null) {
|
||||
parseMembers();
|
||||
if (myRuntimeVisibleAnnotations == null) {
|
||||
myRuntimeVisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
return myRuntimeVisibleAnnotations;
|
||||
parseMembers();
|
||||
final AnnotationConstantValue[] annotations = myRuntimeVisibleAnnotations;
|
||||
return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException {
|
||||
if (myRuntimeInvisibleAnnotations == null) {
|
||||
parseMembers();
|
||||
if (myRuntimeInvisibleAnnotations == null) {
|
||||
myRuntimeInvisibleAnnotations = AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
return myRuntimeInvisibleAnnotations;
|
||||
parseMembers();
|
||||
final AnnotationConstantValue[] annotations = myRuntimeInvisibleAnnotations;
|
||||
return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
private boolean isInterface(){
|
||||
|
||||
@@ -190,7 +190,7 @@ public class CompileDriver {
|
||||
}
|
||||
scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
|
||||
|
||||
final CompilerTask task = new CompilerTask(myProject, true, "", true);
|
||||
final CompilerTask task = new CompilerTask(myProject, true, "Classes up-to-date check", true);
|
||||
final CompileContextImpl compileContext = new CompileContextImpl(myProject, task, scope, createDependencyCache(), true, false);
|
||||
|
||||
checkCachesVersion(compileContext, ((PersistentFS)ManagingFS.getInstance()).getCreationTimestamp());
|
||||
|
||||
@@ -37,7 +37,6 @@ public interface DebuggerActions extends XDebuggerActions {
|
||||
@NonNls String REMOVE_WATCH = "Debugger.RemoveWatch";
|
||||
@NonNls String NEW_WATCH = "Debugger.NewWatch";
|
||||
@NonNls String EDIT_WATCH = "Debugger.EditWatch";
|
||||
@NonNls String MARK_OBJECT = "Debugger.MarkObject";
|
||||
@NonNls String COPY_VALUE = "Debugger.CopyValue";
|
||||
@NonNls String SET_VALUE = "Debugger.SetValue";
|
||||
@NonNls String EDIT_FRAME_SOURCE = "Debugger.EditFrameSource";
|
||||
|
||||
+30
-26
@@ -16,6 +16,7 @@
|
||||
package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.debugger.engine.DebugProcess;
|
||||
import com.intellij.debugger.engine.DebugProcessImpl;
|
||||
import com.intellij.debugger.engine.DebuggerUtils;
|
||||
import com.intellij.debugger.engine.events.DebuggerContextCommandImpl;
|
||||
@@ -26,17 +27,18 @@ import com.intellij.debugger.ui.impl.watch.DebuggerTreeNodeImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.NodeDescriptorImpl;
|
||||
import com.intellij.debugger.ui.impl.watch.ValueDescriptorImpl;
|
||||
import com.intellij.debugger.ui.tree.ValueDescriptor;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.sun.jdi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -51,14 +53,13 @@ import java.util.Map;
|
||||
* Class SetValueAction
|
||||
* @author Jeka
|
||||
*/
|
||||
public class MarkObjectAction extends DebuggerAction {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.MarkObjectAction");
|
||||
public class JavaMarkObjectActionHandler extends MarkObjectActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.debugger.actions.JavaMarkObjectActionHandler");
|
||||
public static final long AUTO_MARKUP_REFERRING_OBJECTS_LIMIT = 100L; // todo: some reasonable limit
|
||||
private final String MARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.text");
|
||||
private final String UNMARK_TEXT = ActionsBundle.message("action.Debugger.MarkObject.unmark.text");
|
||||
|
||||
public void actionPerformed(final AnActionEvent event) {
|
||||
final DebuggerTreeNodeImpl node = getSelectedNode(event.getDataContext());
|
||||
@Override
|
||||
public void perform(@NotNull Project project, AnActionEvent event) {
|
||||
final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext());
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
@@ -233,24 +234,27 @@ public class MarkObjectAction extends DebuggerAction {
|
||||
return builder.append("<br><b>").append(refType.name()).append(".").append(fieldName).append("</b>").toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
|
||||
final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext());
|
||||
return node != null && node.getDescriptor() instanceof ValueDescriptor;
|
||||
}
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
boolean enable = false;
|
||||
String text = MARK_TEXT;
|
||||
final DebuggerTreeNodeImpl node = getSelectedNode(e.getDataContext());
|
||||
if (node != null) {
|
||||
final NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
enable = (descriptor instanceof ValueDescriptor);
|
||||
if (enable) {
|
||||
final ValueMarkup markup = ((ValueDescriptor)descriptor).getMarkup(node.getTree().getDebuggerContext().getDebugProcess());
|
||||
if (markup != null) { // already exists
|
||||
text = UNMARK_TEXT;
|
||||
}
|
||||
}
|
||||
}
|
||||
final Presentation presentation = e.getPresentation();
|
||||
presentation.setVisible(enable);
|
||||
presentation.setText(text);
|
||||
@Override
|
||||
public boolean isHidden(@NotNull Project project, AnActionEvent event) {
|
||||
return DebuggerAction.getSelectedNode(event.getDataContext()) == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event) {
|
||||
final DebuggerTreeNodeImpl node = DebuggerAction.getSelectedNode(event.getDataContext());
|
||||
if (node == null) return false;
|
||||
|
||||
final NodeDescriptorImpl descriptor = node.getDescriptor();
|
||||
if (!(descriptor instanceof ValueDescriptor)) return false;
|
||||
|
||||
DebugProcess debugProcess = node.getTree().getDebuggerContext().getDebugProcess();
|
||||
return ((ValueDescriptor)descriptor).getMarkup(debugProcess) != null;
|
||||
}
|
||||
|
||||
public static Color getAutoMarkupColor() {
|
||||
+2
-2
@@ -17,7 +17,7 @@ package com.intellij.debugger.actions;
|
||||
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.ui.ex.MultiLineLabel;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialogBase;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -28,7 +28,7 @@ import java.awt.*;
|
||||
* @author Eugene Zhuravlev
|
||||
* Date: Feb 4, 2007
|
||||
*/
|
||||
public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialog {
|
||||
public class ObjectMarkupPropertiesDialog extends ValueMarkerPresentationDialogBase {
|
||||
@NonNls private static final String MARK_ALL_REFERENCED_VALUES_KEY = "debugger.mark.all.referenced.values";
|
||||
private JCheckBox myCbMarkAdditionalFields;
|
||||
private final boolean mySuggestAdditionalMarkup;
|
||||
|
||||
@@ -29,8 +29,8 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.xdebugger.AbstractDebuggerSession;
|
||||
import com.intellij.xdebugger.impl.DebuggerSupport;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.*;
|
||||
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
|
||||
import com.intellij.xdebugger.impl.breakpoints.ui.AbstractBreakpointPanel;
|
||||
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
|
||||
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
|
||||
@@ -63,6 +63,7 @@ public class JavaDebuggerSupport extends DebuggerSupport {
|
||||
private final MuteBreakpointsActionHandler myMuteBreakpointsHandler = new MuteBreakpointsActionHandler();
|
||||
private final DebuggerActionHandler mySmartStepIntoHandler = new SmartStepIntoActionHandler();
|
||||
private final DebuggerActionHandler myAddToWatchedActionHandler = new AddToWatchActionHandler();
|
||||
private JavaMarkObjectActionHandler myMarkObjectActionHandler = new JavaMarkObjectActionHandler();
|
||||
|
||||
@NotNull
|
||||
public BreakpointPanelProvider<?> getBreakpointPanelProvider() {
|
||||
@@ -150,6 +151,12 @@ public class JavaDebuggerSupport extends DebuggerSupport {
|
||||
return myMuteBreakpointsHandler;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MarkObjectActionHandler getMarkObjectHandler() {
|
||||
return myMarkObjectActionHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDebuggerSession getCurrentSession(@NotNull Project project) {
|
||||
final DebuggerContextImpl context = (DebuggerManagerEx.getInstanceEx(project)).getContext();
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
package com.intellij.debugger.ui.impl;
|
||||
|
||||
import com.intellij.debugger.actions.DebuggerActions;
|
||||
import com.intellij.debugger.impl.DebuggerSession;
|
||||
import com.intellij.debugger.impl.DebuggerStateManager;
|
||||
import com.intellij.debugger.ui.impl.watch.DebuggerTree;
|
||||
@@ -30,6 +29,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.wm.ex.IdeFocusTraversalPolicy;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -68,7 +68,7 @@ public abstract class DebuggerTreePanel extends UpdatableDebuggerView implements
|
||||
|
||||
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("ToggleBookmark");
|
||||
final CustomShortcutSet shortcutSet = shortcuts.length > 0? new CustomShortcutSet(shortcuts) : new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0));
|
||||
overrideShortcut(myTree, DebuggerActions.MARK_OBJECT, shortcutSet);
|
||||
overrideShortcut(myTree, XDebuggerActions.MARK_OBJECT, shortcutSet);
|
||||
}
|
||||
|
||||
protected abstract DebuggerTree createTreeView();
|
||||
|
||||
+18
-6
@@ -48,6 +48,8 @@ import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.occurences.OccurenceManager;
|
||||
import com.intellij.ui.StateRestoringCheckBox;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -261,14 +263,24 @@ public class InplaceIntroduceConstantPopup {
|
||||
}
|
||||
|
||||
public void performInplaceIntroduce() {
|
||||
startIntroduceTemplate(false);
|
||||
startIntroduceTemplate(false, null);
|
||||
}
|
||||
|
||||
private void startIntroduceTemplate(final boolean replaceAllOccurrences) {
|
||||
private void startIntroduceTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
if (fieldDefaultType != null) {
|
||||
if (replaceAllOccurrences) {
|
||||
if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
final String propName = myLocalVariable != null ? JavaCodeStyleManager
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVariable.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final String[] names = IntroduceConstantDialog.createNameSuggestionGenerator(propName, myExpr, JavaCodeStyleManager.getInstance(myProject))
|
||||
@@ -337,7 +349,7 @@ public class InplaceIntroduceConstantPopup {
|
||||
private SmartTypePointer myFieldTypePointer;
|
||||
|
||||
public FieldInplaceIntroducer(PsiField field) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
super(myProject, new TypeExpression(myProject, myReplaceAllCb.isSelected() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()),
|
||||
myEditor, field, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myExpr != null && myExpr.isPhysical() ? myEditor.getDocument().createRangeMarker(myExpr.getTextRange()) : null, InplaceIntroduceConstantPopup.this.getOccurrenceMarkers(),
|
||||
@@ -456,8 +468,8 @@ public class InplaceIntroduceConstantPopup {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myFieldTypePointer.getType(), null, myExpr, myOccurrences);
|
||||
startIntroduceTemplate(isReplaceAllOccurrences());
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myExpr, myOccurrences);
|
||||
startIntroduceTemplate(isReplaceAllOccurrences(), myFieldTypePointer.getType());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+21
-6
@@ -35,6 +35,8 @@ import com.intellij.refactoring.rename.inplace.VariableInplaceRenamer;
|
||||
import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
|
||||
import com.intellij.refactoring.util.occurences.OccurenceManager;
|
||||
import com.intellij.ui.TitlePanel;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
@@ -151,15 +153,24 @@ public class InplaceIntroduceFieldPopup {
|
||||
}
|
||||
|
||||
public void startTemplate() {
|
||||
startTemplate(false);
|
||||
startTemplate(false, null);
|
||||
}
|
||||
|
||||
public void startTemplate(final boolean replaceAllOccurrences) {
|
||||
public void startTemplate(final boolean replaceAllOccurrences, @Nullable final PsiType fieldDefaultType) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
|
||||
final PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
PsiType defaultType = myTypeSelectorManager.getTypeSelector().getSelectedType();
|
||||
if (fieldDefaultType != null) {
|
||||
if (replaceAllOccurrences) {
|
||||
if (ArrayUtil.find(myTypeSelectorManager.getTypesForAll(), fieldDefaultType) != -1) {
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
} else if (ArrayUtil.find(myTypeSelectorManager.getTypesForOne(), fieldDefaultType) != -1){
|
||||
defaultType = fieldDefaultType;
|
||||
}
|
||||
}
|
||||
|
||||
final SuggestedNameInfo suggestedNameInfo =
|
||||
IntroduceFieldDialog.createGenerator(myStatic, myLocalVariable, myInitializerExpression, myLocalVariable != null)
|
||||
@@ -227,7 +238,7 @@ public class InplaceIntroduceFieldPopup {
|
||||
private SmartTypePointer myFieldTypePointer;
|
||||
|
||||
public FieldInplaceIntroducer(PsiVariable psiVariable) {
|
||||
super(myProject, new TypeExpression(myProject, myTypeSelectorManager.getTypesForAll()),
|
||||
super(myProject, new TypeExpression(myProject, myIntroduceFieldPanel.isReplaceAllOccurrences() ? myTypeSelectorManager.getTypesForAll() : myTypeSelectorManager.getTypesForOne()),
|
||||
myEditor, psiVariable, false,
|
||||
myTypeSelectorManager.getTypesForAll().length > 1,
|
||||
myInitializerExpression != null && myInitializerExpression.isPhysical() ? myEditor.getDocument().createRangeMarker(myInitializerExpression.getTextRange()) : null, InplaceIntroduceFieldPopup.this.getOccurrenceMarkers(),
|
||||
@@ -296,8 +307,8 @@ public class InplaceIntroduceFieldPopup {
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
templateState.gotoEnd(true);
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myFieldTypePointer.getType(), null, myInitializerExpression, myOccurrences);
|
||||
startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences());
|
||||
myTypeSelectorManager = new TypeSelectorManagerImpl(myProject, myDefaultParameterTypePointer.getType(), null, myInitializerExpression, myOccurrences);
|
||||
startTemplate(myIntroduceFieldPanel.isReplaceAllOccurrences(), myFieldTypePointer.getType());
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -312,6 +323,10 @@ public class InplaceIntroduceFieldPopup {
|
||||
if (element instanceof PsiWhiteSpace) {
|
||||
element = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class);
|
||||
}
|
||||
if (element instanceof PsiField) return (PsiVariable)element;
|
||||
final PsiField field = PsiTreeUtil.getParentOfType(element, PsiField.class, false);
|
||||
if (field != null) return field;
|
||||
element = PsiTreeUtil.skipSiblingsBackward(element, PsiWhiteSpace.class);
|
||||
return PsiTreeUtil.getParentOfType(element, PsiField.class, false);
|
||||
}
|
||||
|
||||
|
||||
+7
-1
@@ -116,7 +116,9 @@ public abstract class IntroduceFieldCentralPanel {
|
||||
if (myCbReplaceAll != null && myAllowInitInMethod) {
|
||||
updateInitializerSelection();
|
||||
}
|
||||
updateTypeSelector();
|
||||
if (shouldUpdateTypeSelector()) {
|
||||
updateTypeSelector();
|
||||
}
|
||||
}
|
||||
};
|
||||
ItemListener finalUpdater = new ItemListener() {
|
||||
@@ -137,6 +139,10 @@ public abstract class IntroduceFieldCentralPanel {
|
||||
protected void updateInitializerSelection() {
|
||||
}
|
||||
|
||||
protected boolean shouldUpdateTypeSelector() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private JPanel appendCheckboxes(ItemListener itemListener) {
|
||||
GridBagConstraints gbConstraints = new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1,1,0,0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0,0,0,0), 0,0);
|
||||
JPanel panel = new JPanel(new GridBagLayout());
|
||||
|
||||
+5
@@ -232,6 +232,11 @@ public class IntroduceFieldPopupPanel extends IntroduceFieldCentralPanel {
|
||||
return allowFinal;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean shouldUpdateTypeSelector() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected JPanel composeWholePanel(JComponent initializerPlacePanel, JPanel checkboxPanel) {
|
||||
final JPanel panel = new JPanel(new GridBagLayout());
|
||||
final GridBagConstraints constraints =
|
||||
|
||||
+12
-6
@@ -20,9 +20,7 @@ import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
|
||||
import com.intellij.codeInsight.template.impl.TemplateState;
|
||||
import com.intellij.ide.ui.ListCellRendererWrapper;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
@@ -184,6 +182,11 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
}
|
||||
|
||||
private void startIntroduceTemplate(final boolean replaceAllOccurrences) {
|
||||
startIntroduceTemplate(replaceAllOccurrences, hasFinalModifier());
|
||||
}
|
||||
|
||||
private void startIntroduceTemplate(final boolean replaceAllOccurrences,
|
||||
final boolean hasFinalModifier) {
|
||||
CommandProcessor.getInstance().executeCommand(myProject, new Runnable() {
|
||||
public void run() {
|
||||
myTypeSelectorManager.setAllOccurences(replaceAllOccurrences);
|
||||
@@ -192,7 +195,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
.getInstance(myProject).variableNameToPropertyName(myLocalVar.getName(), VariableKind.LOCAL_VARIABLE) : null;
|
||||
final String[] names = IntroduceParameterHandler.createNameSuggestionGenerator(myExpr, propName, myProject)
|
||||
.getSuggestedNameInfo(defaultType).names;
|
||||
final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType);
|
||||
final PsiParameter parameter = createParameterToStartTemplateOn(names, defaultType, hasFinalModifier);
|
||||
if (parameter != null) {
|
||||
myParameterIndex = myMethod.getParameterList().getParameterIndex(parameter);
|
||||
myEditor.getCaretModel().moveToOffset(parameter.getTextOffset());
|
||||
@@ -399,14 +402,17 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
if (myParameterIndex < 0) return;
|
||||
final TemplateState templateState = TemplateManagerImpl.getTemplateState(myEditor);
|
||||
if (templateState != null) {
|
||||
PsiDocumentManager.getInstance(myProject).commitDocument(myEditor.getDocument());
|
||||
final PsiParameter parameter = getParameter();
|
||||
final boolean hasFinalModifier = parameter.hasModifierProperty(PsiModifier.FINAL);
|
||||
templateState.gotoEnd(true);
|
||||
startIntroduceTemplate(isReplaceAllOccurences());
|
||||
startIntroduceTemplate(isReplaceAllOccurences(), hasFinalModifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private PsiParameter createParameterToStartTemplateOn(final String[] names,
|
||||
final PsiType defaultType) {
|
||||
final PsiType defaultType, final boolean hasFinalModifier) {
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myMethod.getProject());
|
||||
return ApplicationManager.getApplication().runWriteAction(new Computable<PsiParameter>() {
|
||||
@Override
|
||||
@@ -415,7 +421,7 @@ class InplaceIntroduceParameterPopup extends IntroduceParameterSettingsUI {
|
||||
final PsiParameter anchor = JavaIntroduceParameterMethodUsagesProcessor.getAnchorParameter(myMethod);
|
||||
final PsiParameter psiParameter = (PsiParameter)myMethod.getParameterList()
|
||||
.addAfter(elementFactory.createParameter(name, defaultType), anchor);
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier());
|
||||
PsiUtil.setModifierProperty(psiParameter, PsiModifier.FINAL, hasFinalModifier);
|
||||
return psiParameter;
|
||||
}
|
||||
});
|
||||
|
||||
+3
-2
@@ -456,8 +456,9 @@ public abstract class IntroduceVariableBase extends IntroduceHandlerBase impleme
|
||||
final IntroduceVariableSettings settings =
|
||||
getSettings(project, editor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, choice);
|
||||
if (!settings.isOK()) return;
|
||||
typeSelectorManager.setAllOccurences(choice != OccurrencesChooser.ReplaceChoice.NO);
|
||||
final TypeExpression expression = new TypeExpression(project, typeSelectorManager.getTypesForAll());
|
||||
final boolean allOccurences = choice != OccurrencesChooser.ReplaceChoice.NO;
|
||||
typeSelectorManager.setAllOccurences(allOccurences);
|
||||
final TypeExpression expression = new TypeExpression(project, allOccurences ? typeSelectorManager.getTypesForAll() : typeSelectorManager.getTypesForOne());
|
||||
final RangeMarker exprMarker = editor.getDocument().createRangeMarker(expr.getTextRange());
|
||||
final SuggestedNameInfo suggestedName = getSuggestedName(settings.getSelectedType(), expr);
|
||||
final List<RangeMarker> occurrenceMarkers = new ArrayList<RangeMarker>();
|
||||
|
||||
@@ -179,10 +179,12 @@ public class PullUpConflictsUtil {
|
||||
}
|
||||
});
|
||||
if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) {
|
||||
String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) +
|
||||
" abstract as it won't be accessible from the subclass.";
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(abstractMethod, message);
|
||||
if (!isInterfaceTarget) {
|
||||
String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) +
|
||||
" abstract as it won't be accessible from the subclass.";
|
||||
message = CommonRefactoringUtil.capitalize(message);
|
||||
conflicts.putValue(abstractMethod, message);
|
||||
}
|
||||
}
|
||||
}
|
||||
return conflicts;
|
||||
|
||||
@@ -133,6 +133,10 @@ public class TypeSelectorManagerImpl implements TypeSelectorManager {
|
||||
return myTypesForAll;
|
||||
}
|
||||
|
||||
public PsiType[] getTypesForOne() {
|
||||
return myTypesForMain;
|
||||
}
|
||||
|
||||
public PsiType getDefaultType() {
|
||||
if (myDefaultType.isValid()) {
|
||||
return myDefaultType;
|
||||
|
||||
@@ -23,7 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
public abstract class CompletionResultSet {
|
||||
private final PrefixMatcher myPrefixMatcher;
|
||||
private final Consumer<LookupElement> myConsumer;
|
||||
private final CompletionService myCompletionService = CompletionService.getCompletionService();
|
||||
protected final CompletionService myCompletionService = CompletionService.getCompletionService();
|
||||
protected final CompletionContributor myContributor;
|
||||
private boolean myStopped;
|
||||
|
||||
@@ -41,11 +41,7 @@ public abstract class CompletionResultSet {
|
||||
* If a given element matches the prefix, give it for further processing (which may eventually result in its appearing in the completion list)
|
||||
* @param element
|
||||
*/
|
||||
public void addElement(@NotNull final LookupElement element) {
|
||||
if (myCompletionService.prefixMatches(element, getPrefixMatcher())) {
|
||||
myConsumer.consume(element);
|
||||
}
|
||||
}
|
||||
public abstract void addElement(@NotNull final LookupElement element);
|
||||
|
||||
public void addAllElements(@NotNull final Iterable<LookupElement> elements) {
|
||||
for (LookupElement element : elements) {
|
||||
|
||||
+4
-4
@@ -23,7 +23,6 @@ import com.intellij.codeInsight.lookup.Lookup;
|
||||
import com.intellij.codeInsight.lookup.LookupArranger;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.impl.LookupImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.WeighingService;
|
||||
import com.intellij.psi.statistics.StatisticsInfo;
|
||||
@@ -38,13 +37,14 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.*;
|
||||
|
||||
public class CompletionLookupArranger extends LookupArranger {
|
||||
public static final Key<CompletionSorterImpl> SORTER_KEY = Key.create("SORTER_KEY");
|
||||
private static final String SELECTED = "selected";
|
||||
static final String IGNORED = "ignored";
|
||||
private final CompletionLocation myLocation;
|
||||
private final Map<LookupElement, Comparable> mySortingWeights = new THashMap<LookupElement, Comparable>(TObjectHashingStrategy.IDENTITY);
|
||||
private final CompletionProgressIndicator myProcess;
|
||||
|
||||
public CompletionLookupArranger(final CompletionParameters parameters) {
|
||||
public CompletionLookupArranger(final CompletionParameters parameters, CompletionProgressIndicator process) {
|
||||
myProcess = process;
|
||||
myLocation = new CompletionLocation(parameters);
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class CompletionLookupArranger extends LookupArranger {
|
||||
|
||||
@NotNull
|
||||
private CompletionSorterImpl obtainSorter(LookupElement element) {
|
||||
return element.getUserData(SORTER_KEY);
|
||||
return myProcess.getSorter(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+13
-1
@@ -18,6 +18,7 @@ package com.intellij.codeInsight.completion;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.completion.impl.CompletionServiceImpl;
|
||||
import com.intellij.codeInsight.completion.impl.CompletionSorterImpl;
|
||||
import com.intellij.codeInsight.editorActions.CompletionAutoPopupHandler;
|
||||
import com.intellij.codeInsight.hint.EditorHintListener;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
@@ -62,6 +63,7 @@ import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
@@ -103,6 +105,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
};
|
||||
private volatile int myCount;
|
||||
private final ConcurrentHashMap<LookupElement, CompletionSorterImpl> myItemSorters = new ConcurrentHashMap<LookupElement, CompletionSorterImpl>();
|
||||
|
||||
public CompletionProgressIndicator(final Editor editor, CompletionParameters parameters, CodeCompletionHandlerBase handler, Semaphore freezeSemaphore,
|
||||
final OffsetMap offsetMap, LookupImpl lookup, boolean hasModifiers) {
|
||||
@@ -113,7 +116,7 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
myOffsetMap = offsetMap;
|
||||
myLookup = lookup;
|
||||
|
||||
myLookup.setArranger(new CompletionLookupArranger(parameters));
|
||||
myLookup.setArranger(new CompletionLookupArranger(parameters, this));
|
||||
|
||||
myLookup.addLookupListener(myLookupListener);
|
||||
myLookup.setCalculating(true);
|
||||
@@ -187,6 +190,15 @@ public class CompletionProgressIndicator extends ProgressIndicatorBase implement
|
||||
}
|
||||
}
|
||||
|
||||
public void setItemSorter(LookupElement element, CompletionSorterImpl sorter) {
|
||||
myItemSorters.putIfAbsent(element, sorter);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletionSorterImpl getSorter(LookupElement element) {
|
||||
return myItemSorters.get(element);
|
||||
}
|
||||
|
||||
private static int findReplacementOffset(int selectionEndOffset, PsiReference reference) {
|
||||
final List<TextRange> ranges = ReferenceRange.getAbsoluteRanges(reference);
|
||||
for (TextRange range : ranges) {
|
||||
|
||||
+16
-8
@@ -46,7 +46,7 @@ import java.util.ArrayList;
|
||||
public class CompletionServiceImpl extends CompletionService{
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.impl.CompletionServiceImpl");
|
||||
private Throwable myTrace = null;
|
||||
private CompletionProgressIndicator myCurrentCompletion;
|
||||
private volatile CompletionProgressIndicator myCurrentCompletion;
|
||||
private static volatile CompletionPhase ourPhase = CompletionPhase.NoCompletion;
|
||||
private static String ourPhaseTrace;
|
||||
|
||||
@@ -82,7 +82,11 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
final PsiElement position = parameters.getPosition();
|
||||
final String prefix = CompletionData.findPrefixStatic(position, parameters.getOffset());
|
||||
final String textBeforePosition = parameters.getPosition().getContainingFile().getText().substring(0, parameters.getOffset());
|
||||
return new CompletionResultSetImpl(consumer, textBeforePosition, new CamelHumpMatcher(prefix, true, parameters.relaxMatching()), contributor, parameters, defaultSorter(parameters), null);
|
||||
CompletionProgressIndicator process = myCurrentCompletion;
|
||||
LOG.assertTrue(process != null, "createResultSet may be invoked only during completion");
|
||||
CamelHumpMatcher matcher = new CamelHumpMatcher(prefix, true, parameters.relaxMatching());
|
||||
CompletionSorterImpl sorter = defaultSorter(parameters);
|
||||
return new CompletionResultSetImpl(consumer, textBeforePosition, matcher, contributor,parameters, sorter, process, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,6 +114,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
private final String myTextBeforePosition;
|
||||
private final CompletionParameters myParameters;
|
||||
private final CompletionSorterImpl mySorter;
|
||||
private final CompletionProgressIndicator myProcess;
|
||||
@Nullable private final CompletionResultSetImpl myOriginal;
|
||||
|
||||
public CompletionResultSetImpl(final Consumer<LookupElement> consumer, final String textBeforePosition,
|
||||
@@ -117,18 +122,21 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
CompletionContributor contributor,
|
||||
CompletionParameters parameters,
|
||||
@NotNull CompletionSorterImpl sorter,
|
||||
@NotNull CompletionProgressIndicator process,
|
||||
CompletionResultSetImpl original) {
|
||||
super(prefixMatcher, consumer, contributor);
|
||||
myTextBeforePosition = textBeforePosition;
|
||||
myParameters = parameters;
|
||||
mySorter = sorter;
|
||||
myProcess = process;
|
||||
myOriginal = original;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addElement(@NotNull LookupElement element) {
|
||||
element.putUserDataIfAbsent(CompletionLookupArranger.SORTER_KEY, mySorter);
|
||||
super.addElement(element);
|
||||
public void addElement(@NotNull final LookupElement element) {
|
||||
if (myCompletionService.prefixMatches(element, getPrefixMatcher())) {
|
||||
myProcess.setItemSorter(element, mySorter);
|
||||
getConsumer().consume(element);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -142,7 +150,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
"\ninjected=" + (InjectedLanguageUtil.getTopLevelFile(positionFile) != positionFile) +
|
||||
"\nlang=" + positionFile.getLanguage());
|
||||
}
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, this);
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, matcher, myContributor, myParameters, mySorter, myProcess, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,7 +170,7 @@ public class CompletionServiceImpl extends CompletionService{
|
||||
@NotNull
|
||||
@Override
|
||||
public CompletionResultSet withRelevanceSorter(@NotNull CompletionSorter sorter) {
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, this);
|
||||
return new CompletionResultSetImpl(getConsumer(), myTextBeforePosition, getPrefixMatcher(), myContributor, myParameters, (CompletionSorterImpl)sorter, myProcess, this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+8
-2
@@ -40,6 +40,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilBase;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -281,17 +282,22 @@ public class ChangeSignatureGestureDetector extends PsiTreeChangeAdapter impleme
|
||||
return myCurrentInfo;
|
||||
}
|
||||
|
||||
private final @NonNls String PASTE_COMMAND_NAME = EditorBundle.message("paste.command.name");
|
||||
private final @NonNls String TYPING_COMMAND_NAME = EditorBundle.message("typing.in.editor.command.name");
|
||||
|
||||
@Override
|
||||
public void beforeDocumentChange(DocumentEvent e) {
|
||||
if (myDeaf) return;
|
||||
if (myInitialText == null) {
|
||||
final Document document = e.getDocument();
|
||||
final PsiDocumentManager documentManager = myPsiDocumentManager;
|
||||
|
||||
if (!documentManager.isUncommited(document)) {
|
||||
final CommandProcessor processor = CommandProcessor.getInstance();
|
||||
final String currentCommandName = processor.getCurrentCommandName();
|
||||
if (!Comparing.strEqual(EditorBundle.message("typing.in.editor.command.name"), currentCommandName) &&
|
||||
!Comparing.strEqual(EditorBundle.message("paste.command.name"), currentCommandName) &&
|
||||
|
||||
if (!Comparing.strEqual(TYPING_COMMAND_NAME, currentCommandName) &&
|
||||
!Comparing.strEqual(PASTE_COMMAND_NAME, currentCommandName) &&
|
||||
!Comparing.strEqual("Cut", currentCommandName) &&
|
||||
!Comparing.strEqual(LanguageChangeSignatureDetector.MOVE_PARAMETER, currentCommandName) &&
|
||||
!Comparing.equal(EditorActionUtil.DELETE_COMMAND_GROUP, processor.getCurrentCommandGroupId())) {
|
||||
|
||||
+5
-3
@@ -413,9 +413,11 @@ public class VariableInplaceRenamer {
|
||||
ourRenamersStack.pop();
|
||||
}
|
||||
if (myHighlighters != null) {
|
||||
final HighlightManager highlightManager = HighlightManager.getInstance(myProject);
|
||||
for (RangeHighlighter highlighter : myHighlighters) {
|
||||
highlightManager.removeSegmentHighlighter(myEditor, highlighter);
|
||||
if (!myProject.isDisposed()) {
|
||||
final HighlightManager highlightManager = HighlightManager.getInstance(myProject);
|
||||
for (RangeHighlighter highlighter : myHighlighters) {
|
||||
highlightManager.removeSegmentHighlighter(myEditor, highlighter);
|
||||
}
|
||||
}
|
||||
|
||||
myHighlighters = null;
|
||||
|
||||
@@ -78,34 +78,50 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public final void select(final Object element) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().userSelect(new Object[] {element}, null, false, true);
|
||||
}
|
||||
|
||||
public final void select(final Object element, @Nullable final Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), false, true);
|
||||
}
|
||||
|
||||
public final void select(final Object element, @Nullable final Runnable onDone, boolean addToSelection) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().userSelect(new Object[] {element}, new UserRunnable(onDone), addToSelection, true);
|
||||
}
|
||||
|
||||
public final void select(final Object[] elements, @Nullable final Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().userSelect(elements, new UserRunnable(onDone), false, true);
|
||||
}
|
||||
|
||||
public final void select(final Object[] elements, @Nullable final Runnable onDone, boolean addToSelection) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().userSelect(elements, new UserRunnable(onDone), addToSelection, true);
|
||||
}
|
||||
|
||||
public final void expand(Object element, @Nullable Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().expand(element, new UserRunnable(onDone));
|
||||
}
|
||||
|
||||
public final void expand(Object[] element, @Nullable Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().expand(element, new UserRunnable(onDone));
|
||||
}
|
||||
|
||||
public final void collapseChildren(Object element, @Nullable Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().collapseChildren(element, new UserRunnable(onDone));
|
||||
}
|
||||
|
||||
@@ -115,37 +131,54 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public final AbstractTreeBuilder setClearOnHideDelay(final long clearOnHideDelay) {
|
||||
if (isDisposed()) return this;
|
||||
|
||||
getUi().setClearOnHideDelay(clearOnHideDelay);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
protected AbstractTreeUpdater createUpdater() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
AbstractTreeUpdater updater = new AbstractTreeUpdater(this);
|
||||
updater.setModalityStateComponent(MergingUpdateQueue.ANY_COMPONENT);
|
||||
return updater;
|
||||
}
|
||||
|
||||
protected final AbstractTreeUpdater getUpdater() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getUpdater();
|
||||
}
|
||||
|
||||
public final boolean addSubtreeToUpdateByElement(Object element) {
|
||||
if (isDisposed()) return false;
|
||||
|
||||
return getUpdater().addSubtreeToUpdateByElement(element);
|
||||
}
|
||||
|
||||
public final void addSubtreeToUpdate(DefaultMutableTreeNode node) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().addSubtreeToUpdate(node);
|
||||
}
|
||||
|
||||
public final void addSubtreeToUpdate(DefaultMutableTreeNode node, Runnable afterUpdate) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().addSubtreeToUpdate(node, afterUpdate);
|
||||
}
|
||||
|
||||
public final DefaultMutableTreeNode getRootNode() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getRootNode();
|
||||
}
|
||||
|
||||
public final void setNodeDescriptorComparator(Comparator<NodeDescriptor> nodeDescriptorComparator) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().setNodeDescriptorComparator(nodeDescriptorComparator);
|
||||
}
|
||||
|
||||
@@ -161,6 +194,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
|
||||
|
||||
protected void updateNode(final DefaultMutableTreeNode node) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().doUpdateNode(node);
|
||||
}
|
||||
|
||||
@@ -173,14 +208,20 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public final JTree getTree() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getTree();
|
||||
}
|
||||
|
||||
public final AbstractTreeStructure getTreeStructure() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getTreeStructure();
|
||||
}
|
||||
|
||||
public final void setTreeStructure(final AbstractTreeStructure structure) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().setTreeStructure(structure);
|
||||
}
|
||||
|
||||
@@ -201,6 +242,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public void initRootNode() {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().initRootNode();
|
||||
}
|
||||
|
||||
@@ -216,16 +259,29 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
return queueUpdateFrom(element, forceResort, true);
|
||||
}
|
||||
|
||||
public ActionCallback queueUpdateFrom(final Object element, final boolean forceResort, boolean updateStructure) {
|
||||
if (!updateStructure) {
|
||||
return getUi().queueUpdate(element, false);
|
||||
} else {
|
||||
if (forceResort) {
|
||||
getUi().incComparatorStamp();
|
||||
}
|
||||
public ActionCallback queueUpdateFrom(final Object element, final boolean forceResort, final boolean updateStructure) {
|
||||
if (getUi() == null) return new ActionCallback.Rejected();
|
||||
|
||||
return getUi().queueUpdate(element, true);
|
||||
}
|
||||
final ActionCallback result = new ActionCallback();
|
||||
|
||||
getUi().invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (!updateStructure) {
|
||||
getUi().queueUpdate(element, false).notify(result);
|
||||
}
|
||||
else {
|
||||
if (forceResort) {
|
||||
getUi().incComparatorStamp();
|
||||
}
|
||||
|
||||
getUi().queueUpdate(element, true).notify(result);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,6 +289,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
* @param element
|
||||
*/
|
||||
public void buildNodeForElement(Object element) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().buildNodeForElement(element);
|
||||
}
|
||||
|
||||
@@ -243,10 +301,14 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
*/
|
||||
@Nullable
|
||||
public DefaultMutableTreeNode getNodeForElement(Object element) {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getNodeForElement(element, false);
|
||||
}
|
||||
|
||||
public void cleanUp() {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().doCleanUp();
|
||||
}
|
||||
|
||||
@@ -256,10 +318,14 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
protected void expandNodeChildren(final DefaultMutableTreeNode node) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().doExpandNodeChildren(node);
|
||||
}
|
||||
|
||||
protected boolean isAutoExpandNode(final NodeDescriptor nodeDescriptor) {
|
||||
if (isDisposed()) return false;
|
||||
|
||||
return getTreeStructure().getRootElement() == getTreeStructureElement(nodeDescriptor);
|
||||
}
|
||||
|
||||
@@ -282,14 +348,20 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
* @param node
|
||||
*/
|
||||
public final void updateSubtree(final DefaultMutableTreeNode node) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().updateSubtree(node, true);
|
||||
}
|
||||
|
||||
public final boolean wasRootNodeInitialized() {
|
||||
if (isDisposed()) return false;
|
||||
|
||||
return getUi().wasRootNodeInitialized();
|
||||
}
|
||||
|
||||
public final boolean isNodeBeingBuilt(final TreePath path) {
|
||||
if (isDisposed()) return false;
|
||||
|
||||
return getUi().isNodeBeingBuilt(path);
|
||||
}
|
||||
|
||||
@@ -298,6 +370,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
* @param path
|
||||
*/
|
||||
public final void buildNodeForPath(final Object[] path) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().buildNodeForPath(path);
|
||||
}
|
||||
|
||||
@@ -305,10 +379,14 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
* @deprecated
|
||||
*/
|
||||
public final DefaultMutableTreeNode getNodeForPath(final Object[] path) {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().getNodeForPath(path);
|
||||
}
|
||||
|
||||
protected Object findNodeByElement(final Object element) {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return getUi().findNodeByElement(element);
|
||||
}
|
||||
|
||||
@@ -321,6 +399,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
protected void runOnYeildingDone(Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
if (myUi.isPassthroughMode()) {
|
||||
onDone.run();
|
||||
} else {
|
||||
@@ -329,6 +409,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
protected void yield(Runnable runnable) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
if (myUi.isPassthroughMode()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
@@ -346,6 +428,7 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
|
||||
protected void runBackgroundLoading(final Runnable runnable) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
final Application app = ApplicationManager.getApplication();
|
||||
if (app != null) {
|
||||
app.runReadAction(new Runnable() {
|
||||
@@ -359,6 +442,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
protected void updateAfterLoadedInBackground(Runnable runnable) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
if (myUi.isPassthroughMode()) {
|
||||
runnable.run();
|
||||
} else {
|
||||
@@ -367,10 +452,14 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public final ActionCallback getIntialized() {
|
||||
if (isDisposed()) return new ActionCallback.Rejected();
|
||||
|
||||
return myUi.getInitialized();
|
||||
}
|
||||
|
||||
public final ActionCallback getReady(Object requestor) {
|
||||
if (isDisposed()) return new ActionCallback.Rejected();
|
||||
|
||||
return myUi.getReady(requestor);
|
||||
}
|
||||
|
||||
@@ -379,22 +468,32 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public void setPassthroughMode(boolean passthrough) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
myUi.setPassthroughMode(passthrough);
|
||||
}
|
||||
|
||||
public void expandAll(@Nullable Runnable onDone) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().expandAll(onDone);
|
||||
}
|
||||
|
||||
public ActionCallback cancelUpdate() {
|
||||
if (isDisposed()) return new ActionCallback.Rejected();
|
||||
|
||||
return getUi().cancelUpdate();
|
||||
}
|
||||
|
||||
public ActionCallback batch(Progressive progressive) {
|
||||
if (isDisposed()) return new ActionCallback.Rejected();
|
||||
|
||||
return getUi().batch(progressive);
|
||||
}
|
||||
|
||||
public AsyncResult<Object> revalidateElement(Object element) {
|
||||
if (isDisposed()) return new AsyncResult.Rejected<Object>();
|
||||
|
||||
return getTreeStructure().revalidateElement(element);
|
||||
}
|
||||
|
||||
@@ -427,16 +526,21 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
protected boolean updateNodeDescriptor(final NodeDescriptor descriptor) {
|
||||
if (isDisposed()) return false;
|
||||
|
||||
return getUi().doUpdateNodeDescriptor(descriptor);
|
||||
}
|
||||
|
||||
public final DefaultTreeModel getTreeModel() {
|
||||
if (isDisposed()) return null;
|
||||
|
||||
return (DefaultTreeModel)getTree().getModel();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final Set<Object> getSelectedElements() {
|
||||
if (isDisposed()) return Collections.emptySet();
|
||||
|
||||
return getUi().getSelectedElements();
|
||||
}
|
||||
|
||||
@@ -458,6 +562,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public final void setCanYieldUpdate(boolean yield) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
getUi().setCanYield(yield);
|
||||
}
|
||||
|
||||
@@ -500,6 +606,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
|
||||
public void scrollSelectionToVisible(@Nullable Runnable onDone, boolean shouldBeCentered) {
|
||||
if (isDisposed()) return;
|
||||
|
||||
myUi.scrollSelectionToVisible(onDone, shouldBeCentered);
|
||||
}
|
||||
|
||||
@@ -534,4 +642,8 @@ public class AbstractTreeBuilder implements Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertDisposed() {
|
||||
assert !isDisposed();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -340,13 +340,17 @@ public class AbstractTreeUi {
|
||||
}
|
||||
}
|
||||
|
||||
private ActionCallback invokeLaterIfNeeded(@NotNull final Runnable runnable) {
|
||||
public ActionCallback invokeLaterIfNeeded(@NotNull final Runnable runnable) {
|
||||
final ActionCallback result = new ActionCallback();
|
||||
|
||||
Runnable actual = new Runnable() {
|
||||
public void run() {
|
||||
runnable.run();
|
||||
result.setDone();
|
||||
if (isReleased()) {
|
||||
result.setRejected();
|
||||
} else {
|
||||
runnable.run();
|
||||
result.setDone();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -880,7 +884,7 @@ public class AbstractTreeUi {
|
||||
}
|
||||
}
|
||||
|
||||
private void assertIsDispatchThread() {
|
||||
public void assertIsDispatchThread() {
|
||||
if (isPassthroughMode()) return;
|
||||
|
||||
if ((isTreeShowing() || myWasEverShown) && !isEdt()) {
|
||||
@@ -923,6 +927,8 @@ public class AbstractTreeUi {
|
||||
}
|
||||
|
||||
public ActionCallback queueUpdate(Object element, boolean updateStructure) {
|
||||
assertIsDispatchThread();
|
||||
|
||||
try {
|
||||
AbstractTreeUpdater updater = getUpdater();
|
||||
if (updater == null) {
|
||||
@@ -3387,17 +3393,26 @@ public class AbstractTreeUi {
|
||||
TreeBuilderUtil.restorePaths(getBuilder(), pathsToExpand, selectionPaths, false);
|
||||
}
|
||||
else {
|
||||
myTreeModel.nodeChanged(node);
|
||||
nodeChanged(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
myTreeModel.nodeChanged(node);
|
||||
nodeChanged(node);
|
||||
}
|
||||
} else if (nodeChanged) {
|
||||
myTreeModel.nodeChanged(node);
|
||||
nodeChanged(node);
|
||||
}
|
||||
}
|
||||
|
||||
private void nodeChanged(final DefaultMutableTreeNode node) {
|
||||
invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
myTreeModel.nodeChanged(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public DefaultTreeModel getTreeModel() {
|
||||
return myTreeModel;
|
||||
}
|
||||
@@ -3599,6 +3614,8 @@ public class AbstractTreeUi {
|
||||
final boolean canSmartExpand,
|
||||
final boolean mayQueue) {
|
||||
|
||||
assertIsDispatchThread();
|
||||
|
||||
AbstractTreeUpdater updater = getUpdater();
|
||||
if (mayQueue && updater != null) {
|
||||
updater.queueSelection(
|
||||
|
||||
@@ -57,6 +57,11 @@ public class TreeState implements JDOMExternalizable {
|
||||
myUserObject = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return myItemId + ":" + myItemType;
|
||||
}
|
||||
|
||||
public boolean matchedWith(NodeDescriptor nodeDescriptor) {
|
||||
return Comparing.equal(myItemId, getDescriptorKey(nodeDescriptor)) &&
|
||||
Comparing.equal(myItemType, getDescriptorType(nodeDescriptor));
|
||||
@@ -318,7 +323,9 @@ public class TreeState implements JDOMExternalizable {
|
||||
|
||||
}
|
||||
|
||||
private static boolean applyTo(final int positionInPath, final List<PathElement> path, final Object root, final TreeFacade tree, final ProgressIndicator indicator) {
|
||||
private TreeNode requestedExpand;
|
||||
|
||||
private boolean applyTo(final int positionInPath, final List<PathElement> path, final Object root, final TreeFacade tree, final ProgressIndicator indicator) {
|
||||
if (!(root instanceof DefaultMutableTreeNode)) return false;
|
||||
|
||||
final DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)root;
|
||||
@@ -439,7 +446,7 @@ public class TreeState implements JDOMExternalizable {
|
||||
|
||||
myBuilder.expand(element, new Runnable() {
|
||||
public void run() {
|
||||
myBuilder.getUi().getReady(this).notify(result);
|
||||
result.setDone();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+8
-1
@@ -16,9 +16,11 @@
|
||||
package com.intellij.ui.components.editors;
|
||||
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.awt.RelativePoint;
|
||||
import com.intellij.ui.components.JBLabel;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.Icons;
|
||||
import com.intellij.util.ui.EmptyIcon;
|
||||
|
||||
@@ -40,13 +42,14 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel {
|
||||
private final JBList myList = new JBList();
|
||||
private Object[] myOptions = {};
|
||||
private Object myValue;
|
||||
private Function<Object, String> myToString = StringUtil.createToStringFunction(Object.class);
|
||||
|
||||
private ListCellRenderer myRenderer = new DefaultListCellRenderer() {
|
||||
public Icon myEmptyIcon;
|
||||
|
||||
@Override
|
||||
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
|
||||
final JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
|
||||
final JLabel label = (JLabel)super.getListCellRendererComponent(list, myToString.fun(value), index, isSelected, cellHasFocus);
|
||||
if (value == myValue) {
|
||||
label.setIcon(getIcon(isSelected));
|
||||
} else {
|
||||
@@ -135,4 +138,8 @@ public class JBComboBoxTableCellEditorComponent extends JBLabel {
|
||||
public void setDefaultValue(Object value) {
|
||||
myValue = value;
|
||||
}
|
||||
|
||||
public void setToString(Function<Object, String> toString) {
|
||||
myToString = toString;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2120,13 +2120,18 @@ public class TreeUiTest extends AbstractTreeBuilderTest {
|
||||
buildStructure(myRoot);
|
||||
|
||||
final boolean[] done = new boolean[] {false};
|
||||
getBuilder().select(new NodeElement("jetbrains"), new Runnable() {
|
||||
invokeLaterIfNeeded(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
getBuilder().expand(new NodeElement("fabrique"), new Runnable() {
|
||||
getBuilder().select(new NodeElement("jetbrains"), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
done[0] = true;
|
||||
getBuilder().expand(new NodeElement("fabrique"), new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
done[0] = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ minuscule.humps.matching.description=Camel Case without holding Shift in Ctrl+N/
|
||||
|
||||
jvmbugfix.mac.caccessibleLeak=true
|
||||
|
||||
projectView.showHierarchyErrors=false
|
||||
projectView.showHierarchyErrors=true
|
||||
dir.diff.default.src.folder=
|
||||
dir.diff.default.trg.folder=
|
||||
show.live.templates.in.completion=false
|
||||
|
||||
@@ -672,6 +672,7 @@
|
||||
icon="/debugger/muteBreakpoints.png"/>
|
||||
<action id="XDebugger.AutoTooltip" class="com.intellij.xdebugger.impl.actions.ValueTooltipAutoShowAction"/>
|
||||
<action id="XDebugger.ToggleSortValues" class="com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction" icon="/objectBrowser/sorted.png"/>
|
||||
<action id="Debugger.MarkObject" class="com.intellij.xdebugger.impl.actions.MarkObjectAction"/>
|
||||
</group>
|
||||
|
||||
<group id="XDebugger.ToolWindow.TopToolbar">
|
||||
@@ -699,12 +700,14 @@
|
||||
<reference ref="XDebugger.Inspect"/>
|
||||
<reference ref="XDebugger.SetValue"/>
|
||||
<reference ref="XDebugger.CopyValue"/>
|
||||
<reference ref="Debugger.MarkObject"/>
|
||||
</group>
|
||||
|
||||
<group id="XDebugger.Variables.Tree.Popup">
|
||||
<reference ref="XDebugger.Inspect"/>
|
||||
<reference ref="XDebugger.SetValue"/>
|
||||
<reference ref="XDebugger.CopyValue"/>
|
||||
<reference ref="Debugger.MarkObject"/>
|
||||
<reference ref="XDebugger.JumpToSource"/>
|
||||
<reference ref="XDebugger.AddToWatches"/>
|
||||
</group>
|
||||
@@ -717,6 +720,7 @@
|
||||
<reference ref="XDebugger.Inspect"/>
|
||||
<reference ref="XDebugger.SetValue"/>
|
||||
<reference ref="XDebugger.CopyValue"/>
|
||||
<reference ref="Debugger.MarkObject"/>
|
||||
</group>
|
||||
|
||||
<group id="XDebugger.Watches.Tree.Toolbar">
|
||||
@@ -727,6 +731,7 @@
|
||||
<group id="XDebugger.Inspect.Tree.Popup">
|
||||
<reference ref="XDebugger.Inspect"/>
|
||||
<reference ref="XDebugger.CopyValue"/>
|
||||
<reference ref="Debugger.MarkObject"/>
|
||||
</group>
|
||||
|
||||
<group id="XDebugger.Value.Hint.Tree.Popup">
|
||||
|
||||
@@ -23,17 +23,15 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author peter
|
||||
*/
|
||||
public abstract class NotNullLazyValue<T> {
|
||||
private boolean myComputed;
|
||||
@NotNull private T myValue;
|
||||
private T myValue;
|
||||
|
||||
@NotNull
|
||||
protected abstract T compute();
|
||||
|
||||
@NotNull
|
||||
public T getValue() {
|
||||
if (!myComputed) {
|
||||
if (myValue == null) {
|
||||
myValue = compute();
|
||||
myComputed = true;
|
||||
}
|
||||
return myValue;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.execution.ui.RunnerLayoutUi;
|
||||
import com.intellij.openapi.actionSystem.DefaultActionGroup;
|
||||
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
|
||||
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
|
||||
import com.intellij.xdebugger.frame.XValueMarkerProvider;
|
||||
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -161,6 +162,15 @@ public abstract class XDebugProcess {
|
||||
return consoleBuilder.getConsole();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to enable 'Mark Object' action
|
||||
* @return new instance of {@link XValueMarkerProvider}'s implementation or {@code null} if 'Mark Object' feature isn't supported
|
||||
*/
|
||||
@Nullable
|
||||
public XValueMarkerProvider<?,?> createValueMarkerProvider() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to provide additional tabs for 'Debug' tool window
|
||||
*/
|
||||
|
||||
@@ -116,7 +116,6 @@ public abstract class XDebuggerEvaluator {
|
||||
* Override this method to format selected text before it is shown in 'Evaluate' dialog
|
||||
*/
|
||||
@NotNull
|
||||
@SuppressWarnings({"MethodMayBeStatic"})
|
||||
public String formatTextForEvaluation(@NotNull String text) {
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.frame;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Provides implementation of 'Mark Object' feature. <p>
|
||||
*
|
||||
* If debugger values have unique ids just return these ids from {@link #getMarker(XValue)} method.
|
||||
* Alternatively implement {@link #markValue(XValue)} to store a value in some registry and implement {@link #unmarkValue(XValue, Object)}
|
||||
* to remote it from the registry. In such a case the {@link #getMarker(XValue)} method can return {@code null} if the {@code value} isn't marked.
|
||||
*
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class XValueMarkerProvider<V extends XValue, M> {
|
||||
private final Class<V> myValueClass;
|
||||
|
||||
protected XValueMarkerProvider(Class<V> valueClass) {
|
||||
myValueClass = valueClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@code true} if 'Mark Object' action should be enabled for {@code value}
|
||||
*/
|
||||
public abstract boolean canMark(@NotNull V value);
|
||||
|
||||
/**
|
||||
* This method is used to determine whether the {@code value} was marked or not. The returned object is compared using {@link Object#equals(Object)}
|
||||
* method with markers returned by {@link #markValue(XValue)} methods. <p>
|
||||
* This method may return {@code null} if the {@code value} wasn't marked by {@link #markValue(XValue)} method.
|
||||
* @return a marker for {@code value}
|
||||
*/
|
||||
public abstract M getMarker(@NotNull V value);
|
||||
|
||||
/**
|
||||
* This method is called when 'Mark Object' action is invoked. Return an unique marker for {@code value} and store it in some registry
|
||||
* if necessary.
|
||||
* @return a marker for {@code value}
|
||||
*/
|
||||
@NotNull
|
||||
public M markValue(@NotNull V value) {
|
||||
return getMarker(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called when 'Unmark Object' action is invoked.
|
||||
*/
|
||||
public void unmarkValue(@NotNull V value, @NotNull M marker) {
|
||||
}
|
||||
|
||||
public final Class<V> getValueClass() {
|
||||
return myValueClass;
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.AbstractDebuggerSession;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
|
||||
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
|
||||
import com.intellij.xdebugger.impl.evaluate.quick.common.QuickEvaluateHandler;
|
||||
import com.intellij.xdebugger.impl.settings.DebuggerSettingsPanelProvider;
|
||||
@@ -33,7 +34,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
public abstract class DebuggerSupport {
|
||||
private static final ExtensionPointName<DebuggerSupport> EXTENSION_POINT = ExtensionPointName.create("com.intellij.xdebugger.debuggerSupport");
|
||||
|
||||
@NotNull
|
||||
@NotNull
|
||||
public static DebuggerSupport[] getDebuggerSupports() {
|
||||
return Extensions.getExtensions(EXTENSION_POINT);
|
||||
}
|
||||
@@ -96,6 +97,10 @@ public abstract class DebuggerSupport {
|
||||
@NotNull
|
||||
public abstract DebuggerToggleActionHandler getMuteBreakpointsHandler();
|
||||
|
||||
@NotNull
|
||||
public abstract MarkObjectActionHandler getMarkObjectHandler();
|
||||
|
||||
|
||||
@Nullable
|
||||
public abstract AbstractDebuggerSession getCurrentSession(@NotNull Project project);
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import com.intellij.execution.ui.ConsoleView;
|
||||
import com.intellij.execution.ui.ConsoleViewContentType;
|
||||
import com.intellij.execution.ui.RunContentDescriptor;
|
||||
import com.intellij.execution.ui.RunnerLayoutUi;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -46,8 +47,10 @@ 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.XValueMarkerProvider;
|
||||
import com.intellij.xdebugger.impl.breakpoints.*;
|
||||
import com.intellij.xdebugger.impl.evaluate.quick.common.ValueLookupManager;
|
||||
import com.intellij.xdebugger.impl.frame.XValueMarkers;
|
||||
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
|
||||
import com.intellij.xdebugger.impl.ui.XDebugSessionData;
|
||||
import com.intellij.xdebugger.impl.ui.XDebugSessionTab;
|
||||
@@ -78,6 +81,7 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
private XSourcePosition myCurrentPosition;
|
||||
private boolean myPaused;
|
||||
private MyDependentBreakpointListener myDependentBreakpointListener;
|
||||
private XValueMarkers<?,?> myValueMarkers;
|
||||
private String mySessionName;
|
||||
private XDebugSessionTab mySessionTab;
|
||||
private XDebugSessionData mySessionData;
|
||||
@@ -255,6 +259,17 @@ public class XDebugSessionImpl implements XDebugSession {
|
||||
ExecutionManager.getInstance(getProject()).getContentManager().showRunContent(DefaultDebugExecutor.getDebugExecutorInstance(), descriptor);
|
||||
}
|
||||
|
||||
public XValueMarkers<?, ?> getValueMarkers() {
|
||||
ApplicationManager.getApplication().assertIsDispatchThread();
|
||||
if (myValueMarkers == null) {
|
||||
XValueMarkerProvider<?,?> provider = myDebugProcess.createValueMarkerProvider();
|
||||
if (provider != null) {
|
||||
myValueMarkers = XValueMarkers.createValueMarkers(provider);
|
||||
}
|
||||
}
|
||||
return myValueMarkers;
|
||||
}
|
||||
|
||||
private static <B extends XBreakpoint<?>> XBreakpointType<?, ?> getBreakpointTypeClass(final XBreakpointHandler<B> handler) {
|
||||
return XDebuggerUtil.getInstance().findBreakpointType(handler.getBreakpointTypeClass());
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import com.intellij.xdebugger.XDebugSession;
|
||||
import com.intellij.xdebugger.XDebuggerManager;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.DebuggerToggleActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerSuspendedActionHandler;
|
||||
import com.intellij.xdebugger.impl.actions.handlers.*;
|
||||
import com.intellij.xdebugger.impl.breakpoints.ui.BreakpointPanelProvider;
|
||||
@@ -54,6 +55,7 @@ public class XDebuggerSupport extends DebuggerSupport {
|
||||
private final XAddToWatchesFromEditorActionHandler myAddToWatchesActionHandler;
|
||||
private final DebuggerToggleActionHandler myMuteBreakpointsHandler;
|
||||
private final DebuggerActionHandler mySmartStepIntoHandler;
|
||||
private final XMarkObjectActionHandler myMarkObjectActionHandler;
|
||||
|
||||
public XDebuggerSupport() {
|
||||
myBreakpointPanelProvider = new XBreakpointPanelProvider();
|
||||
@@ -106,6 +108,7 @@ public class XDebuggerSupport extends DebuggerSupport {
|
||||
myEvaluateHandler = new XDebuggerEvaluateActionHandler();
|
||||
myQuickEvaluateHandler = new XQuickEvaluateHandler();
|
||||
mySettingsPanelProvider = new XDebuggerSettingsPanelProviderImpl();
|
||||
myMarkObjectActionHandler = new XMarkObjectActionHandler();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -194,6 +197,12 @@ public class XDebuggerSupport extends DebuggerSupport {
|
||||
return myMuteBreakpointsHandler;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public MarkObjectActionHandler getMarkObjectHandler() {
|
||||
return myMarkObjectActionHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AbstractDebuggerSession getCurrentSession(@NotNull Project project) {
|
||||
return XDebuggerManager.getInstance(project).getCurrentSession();
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.actions;
|
||||
|
||||
import com.intellij.idea.ActionsBundle;
|
||||
import com.intellij.openapi.actionSystem.ActionPlaces;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.actionSystem.Presentation;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.impl.DebuggerSupport;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class MarkObjectAction extends XDebuggerActionBase {
|
||||
@Override
|
||||
public void update(AnActionEvent event) {
|
||||
Project project = event.getData(PlatformDataKeys.PROJECT);
|
||||
boolean enabled = false;
|
||||
Presentation presentation = event.getPresentation();
|
||||
boolean hidden = true;
|
||||
if (project != null) {
|
||||
for (DebuggerSupport support : DebuggerSupport.getDebuggerSupports()) {
|
||||
MarkObjectActionHandler handler = support.getMarkObjectHandler();
|
||||
hidden &= handler.isHidden(project, event);
|
||||
if (handler.isEnabled(project, event)) {
|
||||
enabled = true;
|
||||
String text;
|
||||
if (handler.isMarked(project, event)) {
|
||||
text = ActionsBundle.message("action.Debugger.MarkObject.unmark.text");
|
||||
}
|
||||
else {
|
||||
text = ActionsBundle.message("action.Debugger.MarkObject.text");
|
||||
}
|
||||
presentation.setText(text);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
presentation.setVisible(!hidden && (!ActionPlaces.isPopupPlace(event.getPlace()) || enabled));
|
||||
presentation.setEnabled(enabled);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DebuggerActionHandler getHandler(@NotNull DebuggerSupport debuggerSupport) {
|
||||
return debuggerSupport.getMarkObjectHandler();
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class MarkObjectActionHandler extends DebuggerActionHandler {
|
||||
public abstract boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event);
|
||||
}
|
||||
@@ -62,4 +62,5 @@ public interface XDebuggerActions {
|
||||
@NonNls String TOGGLE_SORT_VALUES = "XDebugger.ToggleSortValues";
|
||||
|
||||
@NonNls String AUTO_TOOLTIP = "XDebugger.AutoTooltip";
|
||||
@NonNls String MARK_OBJECT = "Debugger.MarkObject";
|
||||
}
|
||||
|
||||
+90
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.actions.handlers;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.xdebugger.XDebugSession;
|
||||
import com.intellij.xdebugger.XDebuggerManager;
|
||||
import com.intellij.xdebugger.frame.XValue;
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl;
|
||||
import com.intellij.xdebugger.impl.actions.MarkObjectActionHandler;
|
||||
import com.intellij.xdebugger.impl.frame.XValueMarkers;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class XMarkObjectActionHandler extends MarkObjectActionHandler {
|
||||
@Override
|
||||
public void perform(@NotNull Project project, AnActionEvent event) {
|
||||
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
|
||||
if (session == null) return;
|
||||
|
||||
XValueMarkers<?, ?> markers = ((XDebugSessionImpl)session).getValueMarkers();
|
||||
XValueNodeImpl node = XDebuggerTreeActionBase.getSelectedNode(event.getDataContext());
|
||||
if (markers == null || node == null) return;
|
||||
XValue value = node.getValueContainer();
|
||||
|
||||
ValueMarkup existing = markers.getMarkup(value);
|
||||
if (existing != null) {
|
||||
markers.unmarkValue(value);
|
||||
}
|
||||
else {
|
||||
ValueMarkerPresentationDialog dialog = new ValueMarkerPresentationDialog(node.getName());
|
||||
dialog.show();
|
||||
ValueMarkup markup = dialog.getConfiguredMarkup();
|
||||
if (dialog.isOK() && markup != null) {
|
||||
markers.markValue(value, markup);
|
||||
}
|
||||
}
|
||||
session.rebuildViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(@NotNull Project project, AnActionEvent event) {
|
||||
XValueMarkers<?, ?> markers = getValueMarkers(project);
|
||||
if (markers == null) return false;
|
||||
|
||||
XValue value = XDebuggerTreeActionBase.getSelectedValue(event.getDataContext());
|
||||
return value != null && markers.canMarkValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMarked(@NotNull Project project, @NotNull AnActionEvent event) {
|
||||
XValueMarkers<?, ?> markers = getValueMarkers(project);
|
||||
if (markers == null) return false;
|
||||
|
||||
XValue value = XDebuggerTreeActionBase.getSelectedValue(event.getDataContext());
|
||||
return value != null && markers.getMarkup(value) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(@NotNull Project project, AnActionEvent event) {
|
||||
return getValueMarkers(project) == null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static XValueMarkers<?, ?> getValueMarkers(@NotNull Project project) {
|
||||
XDebugSession session = XDebuggerManager.getInstance(project).getCurrentSession();
|
||||
return session != null ? ((XDebugSessionImpl)session).getValueMarkers() : null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.frame;
|
||||
|
||||
import com.intellij.xdebugger.frame.XValue;
|
||||
import com.intellij.xdebugger.frame.XValueMarkerProvider;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class XValueMarkers<V extends XValue, M> {
|
||||
private final XValueMarkerProvider<V, M> myProvider;
|
||||
private final Map<M, ValueMarkup> myMarkers;
|
||||
|
||||
private XValueMarkers(@NotNull XValueMarkerProvider<V, M> provider) {
|
||||
myProvider = provider;
|
||||
myMarkers = new HashMap<M, ValueMarkup>();
|
||||
}
|
||||
|
||||
public static <V extends XValue, M> XValueMarkers<V, M> createValueMarkers(@NotNull XValueMarkerProvider<V, M> provider) {
|
||||
return new XValueMarkers<V, M>(provider);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ValueMarkup getMarkup(@NotNull XValue value) {
|
||||
Class<V> valueClass = myProvider.getValueClass();
|
||||
if (!valueClass.isInstance(value)) return null;
|
||||
|
||||
V v = valueClass.cast(value);
|
||||
if (!myProvider.canMark(v)) return null;
|
||||
|
||||
M m = myProvider.getMarker(v);
|
||||
if (m == null) return null;
|
||||
|
||||
return myMarkers.get(m);
|
||||
}
|
||||
|
||||
public boolean canMarkValue(@NotNull XValue value) {
|
||||
Class<V> valueClass = myProvider.getValueClass();
|
||||
if (!valueClass.isInstance(value)) return false;
|
||||
|
||||
return myProvider.canMark(valueClass.cast(value));
|
||||
}
|
||||
|
||||
public void markValue(@NotNull XValue value, @NotNull ValueMarkup markup) {
|
||||
//noinspection unchecked
|
||||
M m = myProvider.markValue((V)value);
|
||||
myMarkers.put(m, markup);
|
||||
}
|
||||
|
||||
public void unmarkValue(@NotNull XValue value) {
|
||||
//noinspection unchecked
|
||||
M m = myProvider.getMarker((V)value);
|
||||
if (m != null) {
|
||||
myMarkers.remove(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
-73
@@ -15,83 +15,14 @@
|
||||
*/
|
||||
package com.intellij.xdebugger.impl.ui.tree;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.FixedSizeButton;
|
||||
import com.intellij.ui.ColorChooser;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class ValueMarkerPresentationDialog extends DialogWrapper {
|
||||
private static final Color DEFAULT_COLOR = Color.RED;
|
||||
private SimpleColoredComponent myColorSample;
|
||||
private Color myColor;
|
||||
private JPanel myMainPanel;
|
||||
private JTextField myLabelField;
|
||||
private FixedSizeButton myChooseColorButton;
|
||||
private JPanel mySamplePanel;
|
||||
|
||||
public ValueMarkerPresentationDialog(final @Nullable String defaultText) {
|
||||
super(true);
|
||||
setTitle("Select Object Label");
|
||||
setModal(true);
|
||||
myLabelField.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
protected void textChanged(final DocumentEvent e) {
|
||||
updateLabelSample();
|
||||
}
|
||||
});
|
||||
myChooseColorButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final Color color = ColorChooser.chooseColor(myColorSample, "Choose Label Color", myColor);
|
||||
if (color != null) {
|
||||
myColor = color;
|
||||
updateLabelSample();
|
||||
}
|
||||
}
|
||||
});
|
||||
myColor = DEFAULT_COLOR;
|
||||
if (defaultText != null) {
|
||||
myLabelField.setText(defaultText.trim());
|
||||
updateLabelSample();
|
||||
}
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myLabelField;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
private void updateLabelSample() {
|
||||
myColorSample.clear();
|
||||
SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, myColor);
|
||||
myColorSample.append(myLabelField.getText().trim(), attributes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ValueMarkup getConfiguredMarkup() {
|
||||
final String text = myLabelField.getText().trim();
|
||||
return text.isEmpty() ? null : new ValueMarkup(text, myColor, null);
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myColorSample = new SimpleColoredComponent();
|
||||
mySamplePanel = new JPanel(new BorderLayout());
|
||||
mySamplePanel.setBorder(BorderFactory.createEtchedBorder());
|
||||
mySamplePanel.add(BorderLayout.CENTER, myColorSample);
|
||||
myChooseColorButton = new FixedSizeButton(mySamplePanel);
|
||||
public class ValueMarkerPresentationDialog extends ValueMarkerPresentationDialogBase {
|
||||
public ValueMarkerPresentationDialog(@Nullable String defaultText) {
|
||||
super(defaultText);
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialog">
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.xdebugger.impl.ui.tree.ValueMarkerPresentationDialogBase">
|
||||
<grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.ui.tree;
|
||||
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.FixedSizeButton;
|
||||
import com.intellij.ui.ColorChooser;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public abstract class ValueMarkerPresentationDialogBase extends DialogWrapper {
|
||||
private static final Color DEFAULT_COLOR = Color.RED;
|
||||
private SimpleColoredComponent myColorSample;
|
||||
private Color myColor;
|
||||
private JPanel myMainPanel;
|
||||
private JTextField myLabelField;
|
||||
private FixedSizeButton myChooseColorButton;
|
||||
private JPanel mySamplePanel;
|
||||
|
||||
public ValueMarkerPresentationDialogBase(final @Nullable String defaultText) {
|
||||
super(true);
|
||||
setTitle("Select Object Label");
|
||||
setModal(true);
|
||||
myLabelField.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
protected void textChanged(final DocumentEvent e) {
|
||||
updateLabelSample();
|
||||
}
|
||||
});
|
||||
myChooseColorButton.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(final ActionEvent e) {
|
||||
final Color color = ColorChooser.chooseColor(myColorSample, "Choose Label Color", myColor);
|
||||
if (color != null) {
|
||||
myColor = color;
|
||||
updateLabelSample();
|
||||
}
|
||||
}
|
||||
});
|
||||
myColor = DEFAULT_COLOR;
|
||||
if (defaultText != null) {
|
||||
myLabelField.setText(defaultText.trim());
|
||||
updateLabelSample();
|
||||
}
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myLabelField;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent createCenterPanel() {
|
||||
return myMainPanel;
|
||||
}
|
||||
|
||||
private void updateLabelSample() {
|
||||
myColorSample.clear();
|
||||
SimpleTextAttributes attributes = new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, myColor);
|
||||
myColorSample.append(myLabelField.getText().trim(), attributes);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public ValueMarkup getConfiguredMarkup() {
|
||||
final String text = myLabelField.getText().trim();
|
||||
return text.isEmpty() ? null : new ValueMarkup(text, myColor, null);
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myColorSample = new SimpleColoredComponent();
|
||||
mySamplePanel = new JPanel(new BorderLayout());
|
||||
mySamplePanel.setBorder(BorderFactory.createEtchedBorder());
|
||||
mySamplePanel.add(BorderLayout.CENTER, myColorSample);
|
||||
myChooseColorButton = new FixedSizeButton(mySamplePanel);
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package com.intellij.xdebugger.impl.ui.tree;
|
||||
import com.intellij.ide.dnd.aware.DnDAwareTree;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.changes.issueLinks.TreeLinkMouseListener;
|
||||
import com.intellij.ui.PopupHandler;
|
||||
@@ -210,6 +211,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
|
||||
actionManager.getAction(XDebuggerActions.SET_VALUE).unregisterCustomShortcutSet(this);
|
||||
actionManager.getAction(XDebuggerActions.COPY_VALUE).unregisterCustomShortcutSet(this);
|
||||
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).unregisterCustomShortcutSet(this);
|
||||
actionManager.getAction(XDebuggerActions.MARK_OBJECT).unregisterCustomShortcutSet(this);
|
||||
}
|
||||
|
||||
private void registerShortcuts() {
|
||||
@@ -217,6 +219,7 @@ public class XDebuggerTree extends DnDAwareTree implements DataProvider, Disposa
|
||||
actionManager.getAction(XDebuggerActions.SET_VALUE).registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0)), this);
|
||||
actionManager.getAction(XDebuggerActions.COPY_VALUE).registerCustomShortcutSet(CommonShortcuts.getCopy(), this);
|
||||
actionManager.getAction(XDebuggerActions.JUMP_TO_SOURCE).registerCustomShortcutSet(CommonShortcuts.getEditSource(), this);
|
||||
actionManager.getAction(XDebuggerActions.MARK_OBJECT).registerCustomShortcutSet(new CustomShortcutSet( KeymapManager.getInstance().getActiveKeymap().getShortcuts("ToggleBookmark")), this);
|
||||
}
|
||||
|
||||
private static void markNodesObsolete(final XValueContainerNode<?> node) {
|
||||
|
||||
@@ -24,6 +24,7 @@ import com.intellij.xdebugger.frame.XValue;
|
||||
import com.intellij.xdebugger.impl.actions.XDebuggerActions;
|
||||
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
@@ -34,7 +35,7 @@ import javax.swing.*;
|
||||
public class XInspectDialog extends DialogWrapper {
|
||||
private final XDebuggerTreePanel myTreePanel;
|
||||
|
||||
public XInspectDialog(final XDebugSession session, XDebuggerEditorsProvider editorsProvider, XSourcePosition sourcePosition, String nodeName, XValue value) {
|
||||
public XInspectDialog(final XDebugSession session, XDebuggerEditorsProvider editorsProvider, XSourcePosition sourcePosition, @NotNull String nodeName, @NotNull XValue value) {
|
||||
super(session.getProject(), false);
|
||||
setTitle(XDebuggerBundle.message("inspect.value.dialog.title", nodeName));
|
||||
setModal(false);
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ public abstract class XDebuggerTreeActionBase extends AnAction {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static XValueNodeImpl getSelectedNode(final DataContext dataContext) {
|
||||
public static XValueNodeImpl getSelectedNode(final DataContext dataContext) {
|
||||
XDebuggerTree tree = XDebuggerTree.getTree(dataContext);
|
||||
if (tree == null) return null;
|
||||
|
||||
|
||||
+2
-1
@@ -17,12 +17,13 @@ package com.intellij.xdebugger.impl.ui.tree.nodes;
|
||||
|
||||
import com.intellij.xdebugger.frame.XStackFrame;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author nik
|
||||
*/
|
||||
public class XStackFrameNode extends XValueContainerNode<XStackFrame> {
|
||||
public XStackFrameNode(final XDebuggerTree tree, final XStackFrame xStackFrame) {
|
||||
public XStackFrameNode(final @NotNull XDebuggerTree tree, final @NotNull XStackFrame xStackFrame) {
|
||||
super(tree, null, xStackFrame);
|
||||
setLeaf(false);
|
||||
}
|
||||
|
||||
+2
-1
@@ -39,7 +39,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
|
||||
protected final ValueContainer myValueContainer;
|
||||
private volatile boolean myObsolete;
|
||||
|
||||
protected XValueContainerNode(XDebuggerTree tree, final XDebuggerTreeNode parent, ValueContainer valueContainer) {
|
||||
protected XValueContainerNode(XDebuggerTree tree, final XDebuggerTreeNode parent, @NotNull ValueContainer valueContainer) {
|
||||
super(tree, parent, true);
|
||||
myValueContainer = valueContainer;
|
||||
myText.append(XDebuggerUIConstants.COLLECTING_DATA_MESSAGE, XDebuggerUIConstants.COLLECTING_DATA_HIGHLIGHT_ATTRIBUTES);
|
||||
@@ -162,6 +162,7 @@ public abstract class XValueContainerNode<ValueContainer extends XValueContainer
|
||||
return myCachedAllChildren;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ValueContainer getValueContainer() {
|
||||
return myValueContainer;
|
||||
}
|
||||
|
||||
+11
-1
@@ -20,8 +20,11 @@ import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.StringBuilderSpinAllocator;
|
||||
import com.intellij.xdebugger.frame.*;
|
||||
import com.intellij.xdebugger.impl.XDebugSessionImpl;
|
||||
import com.intellij.xdebugger.impl.frame.XValueMarkers;
|
||||
import com.intellij.xdebugger.impl.ui.DebuggerUIUtil;
|
||||
import com.intellij.xdebugger.impl.ui.XDebuggerUIConstants;
|
||||
import com.intellij.xdebugger.impl.ui.tree.ValueMarkup;
|
||||
import com.intellij.xdebugger.impl.ui.tree.XDebuggerTree;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,7 +51,7 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
|
||||
private String mySeparator;
|
||||
private boolean myChanged;
|
||||
|
||||
public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, String name, final XValue value) {
|
||||
public XValueNodeImpl(XDebuggerTree tree, final XDebuggerTreeNode parent, String name, final @NotNull XValue value) {
|
||||
super(tree, parent, value);
|
||||
myName = name;
|
||||
if (myName != null) {
|
||||
@@ -106,6 +109,13 @@ public class XValueNodeImpl extends XValueContainerNode<XValue> implements XValu
|
||||
|
||||
private void updateText() {
|
||||
myText.clear();
|
||||
XValueMarkers<?,?> markers = ((XDebugSessionImpl)myTree.getSession()).getValueMarkers();
|
||||
if (markers != null) {
|
||||
ValueMarkup markup = markers.getMarkup(myValueContainer);
|
||||
if (markup != null) {
|
||||
myText.append("[" + markup.getText() + "] ", new SimpleTextAttributes(SimpleTextAttributes.STYLE_BOLD, markup.getColor()));
|
||||
}
|
||||
}
|
||||
myText.append(myName, XDebuggerUIConstants.VALUE_NAME_ATTRIBUTES);
|
||||
myText.append(mySeparator, SimpleTextAttributes.REGULAR_ATTRIBUTES);
|
||||
if (myType != null) {
|
||||
|
||||
@@ -299,7 +299,6 @@
|
||||
<action id="Debugger.RemoveAllWatches" class="com.intellij.debugger.actions.RemoveAllWatchesAction"/>
|
||||
<action id="Debugger.RemoveWatch" class="com.intellij.debugger.actions.RemoveWatchAction" icon="/actions/delete.png"/>
|
||||
<action id="Debugger.ViewAsGroup" class="com.intellij.debugger.actions.ViewAsGroup"/>
|
||||
<action id="Debugger.MarkObject" class="com.intellij.debugger.actions.MarkObjectAction"/>
|
||||
<action id="Debugger.SetValue" class="com.intellij.debugger.actions.SetValueAction"/>
|
||||
<!--<action id="Debugger.ShowAsHex" class="com.intellij.debugger.actions.ShowAsHexAction" text="Show as Hex"/>-->
|
||||
<action id="Debugger.ShowFrame" class="com.intellij.debugger.actions.ShowFrameAction"/>
|
||||
|
||||
Reference in New Issue
Block a user