mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-30 10:20:15 +07:00
override methods dialog with sorting by overridings
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightBundle;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.util.MemberChooser;
|
||||
import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.NotNullLazyValue;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich
|
||||
*/
|
||||
public class JavaOverrideImplementMemberChooser extends MemberChooser<PsiMethodMember> {
|
||||
private static final String SORT_METHODS_BY_PERCENT_DESCRIPTION = "Sort by Percent of Classes which Overrides a Method";
|
||||
|
||||
@NonNls public static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
|
||||
@NonNls public static final String PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT = "OverrideImplement.overriding.sorted";
|
||||
|
||||
private ToggleAction mySortByOverridingAction;
|
||||
private ToggleAction myMergeAction;
|
||||
private final PsiMethodMember[] myAllElements;
|
||||
private final PsiMethodMember[] myOnlyPrimaryElements;
|
||||
private final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> myLazyElementsWithPercent;
|
||||
private final boolean myToImplement;
|
||||
private Project myProject;
|
||||
private boolean myMerge;
|
||||
private boolean mySortedByOverriding;
|
||||
|
||||
@Nullable
|
||||
public static JavaOverrideImplementMemberChooser create(final PsiElement aClass,
|
||||
final boolean toImplement,
|
||||
final Collection<CandidateInfo> candidates,
|
||||
final Collection<CandidateInfo> secondary) {
|
||||
final Project project = aClass.getProject();
|
||||
if (candidates.isEmpty() && secondary.isEmpty()) return null;
|
||||
|
||||
final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates);
|
||||
final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary));
|
||||
final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent =
|
||||
new NotNullLazyValue<PsiMethodWithOverridingPercentMember[]>() {
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiMethodWithOverridingPercentMember[] compute() {
|
||||
final PsiMethodWithOverridingPercentMember[] elements =
|
||||
PsiMethodWithOverridingPercentMember.calculateOverridingPercents(candidates);
|
||||
Arrays.sort(elements, PsiMethodWithOverridingPercentMember.COMPARATOR);
|
||||
return elements;
|
||||
}
|
||||
};
|
||||
final boolean merge = PropertiesComponent.getInstance(project).getBoolean(PROP_COMBINED_OVERRIDE_IMPLEMENT, true);
|
||||
final JavaOverrideImplementMemberChooser javaOverrideImplementMemberChooser =
|
||||
new JavaOverrideImplementMemberChooser(all, onlyPrimary, lazyElementsWithPercent, project, PsiUtil.isLanguageLevel5OrHigher(aClass),
|
||||
merge, toImplement, PropertiesComponent.getInstance(project)
|
||||
.getBoolean(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, false));
|
||||
javaOverrideImplementMemberChooser.setTitle(getChooserTitle(toImplement, merge));
|
||||
|
||||
javaOverrideImplementMemberChooser.setCopyJavadocVisible(true);
|
||||
|
||||
if (toImplement) {
|
||||
javaOverrideImplementMemberChooser.selectElements(onlyPrimary);
|
||||
}
|
||||
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) {
|
||||
if (!toImplement || onlyPrimary.length == 0) {
|
||||
javaOverrideImplementMemberChooser.selectElements(all);
|
||||
}
|
||||
javaOverrideImplementMemberChooser.close(DialogWrapper.OK_EXIT_CODE);
|
||||
return javaOverrideImplementMemberChooser;
|
||||
}
|
||||
return javaOverrideImplementMemberChooser;
|
||||
}
|
||||
|
||||
private JavaOverrideImplementMemberChooser(final PsiMethodMember[] allElements,
|
||||
final PsiMethodMember[] onlyPrimaryElements,
|
||||
final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
|
||||
final @NotNull Project project,
|
||||
final boolean isInsertOverrideVisible,
|
||||
final boolean merge,
|
||||
final boolean toImplement,
|
||||
final boolean sortedByOverriding) {
|
||||
super(false, true, project, isInsertOverrideVisible, null, null);
|
||||
myAllElements = allElements;
|
||||
myOnlyPrimaryElements = onlyPrimaryElements;
|
||||
myLazyElementsWithPercent = lazyElementsWithPercent;
|
||||
myProject = project;
|
||||
myMerge = merge;
|
||||
myToImplement = toImplement;
|
||||
mySortedByOverriding = sortedByOverriding;
|
||||
resetElements(getInitialElements(allElements, onlyPrimaryElements, lazyElementsWithPercent, merge, toImplement, sortedByOverriding));
|
||||
init();
|
||||
}
|
||||
|
||||
private static PsiMethodMember[] getInitialElements(PsiMethodMember[] allElements,
|
||||
PsiMethodMember[] onlyPrimaryElements,
|
||||
NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
|
||||
boolean merge,
|
||||
boolean toImplement,
|
||||
boolean sortByOverriding) {
|
||||
final boolean showElementsWithPercents = sortByOverriding && !toImplement;
|
||||
final PsiMethodMember[] defaultElements = toImplement || merge ? allElements : onlyPrimaryElements;
|
||||
return showElementsWithPercents ? lazyElementsWithPercent.getValue() : defaultElements;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onAlphabeticalSortingEnabled(final AnActionEvent event) {
|
||||
resetElements(myToImplement || myMerge ? myAllElements : myOnlyPrimaryElements, null, true);
|
||||
if (mySortByOverridingAction != null) {
|
||||
mySortByOverridingAction.setSelected(event, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doOKAction() {
|
||||
super.doOKAction();
|
||||
PropertiesComponent.getInstance(myProject).setValue(PROP_COMBINED_OVERRIDE_IMPLEMENT, String.valueOf(myMerge));
|
||||
PropertiesComponent.getInstance(myProject).setValue(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, String.valueOf(mySortedByOverriding));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fillToolbarActions(DefaultActionGroup group) {
|
||||
super.fillToolbarActions(group);
|
||||
if (myToImplement) return;
|
||||
|
||||
mySortByOverridingAction = new MySortByOverridingAction();
|
||||
if (mySortedByOverriding) {
|
||||
changeSortComparator(PsiMethodWithOverridingPercentMember.COMPARATOR);
|
||||
}
|
||||
group.add(mySortByOverridingAction, Constraints.FIRST);
|
||||
|
||||
myMergeAction = new MyMergeAction();
|
||||
group.add(myMergeAction);
|
||||
}
|
||||
|
||||
private static String getChooserTitle(final boolean toImplement, final boolean merge) {
|
||||
return toImplement
|
||||
? CodeInsightBundle.message("methods.to.implement.chooser.title")
|
||||
: merge
|
||||
? CodeInsightBundle.message("methods.to.override.implement.chooser.title")
|
||||
: CodeInsightBundle.message("methods.to.override.chooser.title");
|
||||
}
|
||||
|
||||
private static PsiMethodMember[] convertToMethodMembers(Collection<CandidateInfo> candidates) {
|
||||
return ContainerUtil.map2Array(candidates, PsiMethodMember.class, new Function<CandidateInfo, PsiMethodMember>() {
|
||||
@Override
|
||||
public PsiMethodMember fun(final CandidateInfo s) {
|
||||
return new PsiMethodMember(s);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private class MySortByOverridingAction extends ToggleAction {
|
||||
public MySortByOverridingAction() {
|
||||
super(SORT_METHODS_BY_PERCENT_DESCRIPTION, SORT_METHODS_BY_PERCENT_DESCRIPTION, AllIcons.ObjectBrowser.SortedByUsage);
|
||||
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK)), myTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(final AnActionEvent e) {
|
||||
return mySortedByOverriding;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(final AnActionEvent e, final boolean state) {
|
||||
mySortedByOverriding = state;
|
||||
if (state) {
|
||||
if (myMerge) {
|
||||
myMergeAction.setSelected(e, false);
|
||||
}
|
||||
disableAlphabeticalSorting(e);
|
||||
final PsiMethodWithOverridingPercentMember[] elementsWithPercent = myLazyElementsWithPercent.getValue();
|
||||
resetElements(elementsWithPercent, PsiMethodWithOverridingPercentMember.COMPARATOR, false);
|
||||
}
|
||||
else {
|
||||
final PsiMethodMember[] elementsToRender = myMerge ? myAllElements : myOnlyPrimaryElements;
|
||||
resetElementsWithDefaultComparator(elementsToRender, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MyMergeAction extends ToggleAction {
|
||||
private MyMergeAction() {
|
||||
super("Show methods to implement", "Show methods to implement", AllIcons.General.Show_to_implement);
|
||||
registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.ALT_MASK)), myTree);
|
||||
final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("OverrideMethods");
|
||||
registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent e) {
|
||||
return myMerge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent e, boolean state) {
|
||||
myMerge = state;
|
||||
if (state && mySortByOverridingAction.isSelected(e)) {
|
||||
mySortByOverridingAction.setSelected(e, false);
|
||||
}
|
||||
resetElements(state ? myAllElements : myOnlyPrimaryElements, null, true);
|
||||
setTitle(getChooserTitle(false, myMerge));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -50,7 +50,6 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
@@ -223,7 +222,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
|
||||
}
|
||||
|
||||
annotateOnOverrideImplement(result, aClass, method, insertOverrideIfPossible);
|
||||
|
||||
|
||||
if (CodeStyleSettingsManager.getSettings(aClass.getProject()).REPEAT_SYNCHRONIZED && method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
|
||||
result.getModifierList().setModifierProperty(PsiModifier.SYNCHRONIZED, true);
|
||||
}
|
||||
@@ -394,9 +393,10 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
|
||||
JVMElementFactory factory = JVMElementFactories.getFactory(targetClass.getLanguage(), originalMethod.getProject());
|
||||
if (factory == null) factory = JavaPsiFacade.getInstance(originalMethod.getProject()).getElementFactory();
|
||||
@NonNls String methodText;
|
||||
|
||||
try {
|
||||
methodText = "void foo () {\n" + template.getText(properties) + "\n}";
|
||||
String bodyText = template.getText(properties);
|
||||
if (bodyText != null && !bodyText.isEmpty()) bodyText += "\n";
|
||||
methodText = "void foo () {\n" + bodyText + "}";
|
||||
methodText = FileTemplateUtil.indent(methodText, result.getProject(), fileType);
|
||||
} catch (Exception e) {
|
||||
throw new IncorrectOperationException("Failed to parse file template",e);
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
package com.intellij.codeInsight.generation;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.PsiExtensibleClass;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.ui.SimpleColoredComponent;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
|
||||
*/
|
||||
public class PsiMethodWithOverridingPercentMember extends PsiMethodMember {
|
||||
|
||||
private final int myOverridingPercent;
|
||||
|
||||
public PsiMethodWithOverridingPercentMember(final CandidateInfo info, final int overridingPercent) {
|
||||
super(info);
|
||||
myOverridingPercent = overridingPercent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void renderTreeNode(final SimpleColoredComponent component, final JTree tree) {
|
||||
component.append(myOverridingPercent + "% ", SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
super.renderTreeNode(component, tree);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
public int getOverridingPercent() {
|
||||
return myOverridingPercent;
|
||||
}
|
||||
|
||||
public static final Comparator<PsiMethodMember> COMPARATOR = new Comparator<PsiMethodMember>() {
|
||||
@Override
|
||||
public int compare(PsiMethodMember e1, PsiMethodMember e2) {
|
||||
if (!(e1 instanceof PsiMethodWithOverridingPercentMember)) {
|
||||
if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
|
||||
return e1.equals(e2) ? 0 : -1;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
|
||||
return 1;
|
||||
}
|
||||
int sub =
|
||||
((PsiMethodWithOverridingPercentMember)e2).myOverridingPercent - ((PsiMethodWithOverridingPercentMember)e1).myOverridingPercent;
|
||||
if (sub != 0) return sub;
|
||||
return String.CASE_INSENSITIVE_ORDER.compare(e1.getText(), e2.getText());
|
||||
}
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static PsiMethodWithOverridingPercentMember[] calculateOverridingPercents(@NotNull final Collection<CandidateInfo> candidateInfos) {
|
||||
final List<PsiMethodWithOverridingPercentMember> result = new ArrayList<PsiMethodWithOverridingPercentMember>(candidateInfos.size());
|
||||
final Map<String, Collection<PsiClass>> classShortNames2Inheritors = new HashMap<String, Collection<PsiClass>>();
|
||||
for (final CandidateInfo candidateInfo : candidateInfos) {
|
||||
final PsiMethod method = (PsiMethod)candidateInfo.getElement();
|
||||
if (!method.hasModifierProperty(PsiModifier.FINAL) &&
|
||||
!method.isConstructor() &&
|
||||
!method.isDeprecated() &&
|
||||
!EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES.contains(method.getName())) {
|
||||
final PsiClass containingClass = method.getContainingClass();
|
||||
if (containingClass == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String classShortName = containingClass.getName();
|
||||
|
||||
Collection<PsiClass> allInheritors = classShortNames2Inheritors.get(classShortName);
|
||||
if (allInheritors == null) {
|
||||
allInheritors = ClassInheritorsSearch.search(containingClass, true).findAll();
|
||||
classShortNames2Inheritors.put(classShortName, allInheritors);
|
||||
}
|
||||
|
||||
final int allInheritorsCount = allInheritors.size() - 1;
|
||||
if (allInheritorsCount > 0) {
|
||||
final int percent = searchForOverridingCount(method, allInheritors) * 100 / allInheritorsCount;
|
||||
if (percent > 1) {
|
||||
result.add(new PsiMethodWithOverridingPercentMember(candidateInfo, percent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.toArray(new PsiMethodWithOverridingPercentMember[result.size()]);
|
||||
}
|
||||
|
||||
private static int searchForOverridingCount(final PsiMethod method, final Collection<PsiClass> containingClassInheritors) {
|
||||
int counter = 0;
|
||||
for (final PsiClass inheritor : containingClassInheritors) {
|
||||
if (inheritor instanceof PsiExtensibleClass) {
|
||||
final List<PsiMethod> ownMethods = ((PsiExtensibleClass)inheritor).getOwnMethods();
|
||||
for (PsiMethod ownMethod : ownMethods) {
|
||||
if (maybeSuper(method, ownMethod)) {
|
||||
counter++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
private static boolean maybeSuper(@NotNull final PsiMethod superMethod, @NotNull final PsiMethod method) {
|
||||
if (!superMethod.getName().equals(method.getName())) {
|
||||
return false;
|
||||
}
|
||||
final PsiParameterList superMethodParameterList = superMethod.getParameterList();
|
||||
final PsiParameterList methodParameterList = method.getParameterList();
|
||||
if (superMethodParameterList.getParametersCount() != methodParameterList.getParametersCount()) {
|
||||
return false;
|
||||
}
|
||||
final PsiParameter[] superMethodParameters = superMethodParameterList.getParameters();
|
||||
final PsiParameter[] methodParameters = methodParameterList.getParameters();
|
||||
for (int i = 0; i < methodParameters.length; i++) {
|
||||
if (!StringUtil.equals(getTypeShortName(superMethodParameters[i].getType()), getTypeShortName(methodParameters[i].getType()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getTypeShortName(@NotNull final PsiType type) {
|
||||
if (type instanceof PsiPrimitiveType) {
|
||||
return ((PsiPrimitiveType)type).getBoxedTypeName();
|
||||
}
|
||||
if (type instanceof PsiClassType) {
|
||||
return ((PsiClassType)type).getClassName();
|
||||
}
|
||||
if (type instanceof PsiArrayType) {
|
||||
return getTypeShortName(((PsiArrayType)type).getComponentType()) + "[]";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static final Set<String> EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES =
|
||||
ContainerUtil.newHashSet("hashCode", "finalize", "clone", "equals", "toString");
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "PsiMethodWithOverridingPercentMember{" +
|
||||
"myOverridingPercent=" + myOverridingPercent + ", myElement=" + getElement() +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
|
||||
class BaseClass {
|
||||
public void method() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx1 extends BaseClass {
|
||||
@Override
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx2 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
|
||||
public void method(String aString) {
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass extends B<caret>aseClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
|
||||
class BaseClass {
|
||||
public void method() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void method(String s) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx1 extends BaseClass {
|
||||
@Override
|
||||
public void method() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx2 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass extends B<caret>aseClass {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
|
||||
class BaseClass {
|
||||
public void method() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void method(String s) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx1 extends BaseClass {
|
||||
@Override
|
||||
public void method() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx11 extends ClassEx1 {
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx2 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass extends Cl<caret>assEx1 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
|
||||
class BaseClass {
|
||||
public void method() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void method(String s) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx1 extends BaseClass {
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx11 extends ClassEx1 {
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx2 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx3 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class MyClass extends Cl<caret>assEx1 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
import java.lang.Override;
|
||||
import java.lang.String;
|
||||
|
||||
class BaseClass {
|
||||
public void method() {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
public void method(String s) {
|
||||
//do nothing
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx2 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx3 extends BaseClass {
|
||||
public void method() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx1 extends BaseClass {
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx11 extends ClassEx1 {
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx12 extends ClassEx1 {
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
class ClassEx13 extends ClassEx1 {
|
||||
@Override
|
||||
public void method(String s) {
|
||||
}
|
||||
|
||||
public void method2() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class MyClass extends Cl<caret>assEx1 {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.intellij.codeInsight.generation.methodsOverridingStatistics;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
|
||||
import com.intellij.codeInsight.generation.OverrideImplementUtil;
|
||||
import com.intellij.codeInsight.generation.PsiMethodWithOverridingPercentMember;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.infos.CandidateInfo;
|
||||
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public class JavaMethodsOverridingStatisticsTest extends JavaCodeInsightFixtureTestCase {
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/generation/javaMethodsOverridingStatistics/";
|
||||
}
|
||||
|
||||
public void testMethods() {
|
||||
doTest(1, pair("method", 100));
|
||||
}
|
||||
|
||||
public void testMethods2() {
|
||||
doTest(2, pair("method", 50), pair("method", 100));
|
||||
}
|
||||
|
||||
public void testMethods3() {
|
||||
doTest(1, pair("method2", 100));
|
||||
}
|
||||
|
||||
public void testMethods4() {
|
||||
doTest(2, pair("method2", 100), pair("method", 50));
|
||||
}
|
||||
|
||||
public void testMethods5() {
|
||||
doTest(3, pair("method", 100), pair("method2", 100), pair("method", 33));
|
||||
}
|
||||
|
||||
private void doTest(final int resultSize, final Pair<String, Integer>... expectedValues) {
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
|
||||
final PsiClass contextClass =
|
||||
OverrideImplementUtil.getContextClass(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), true);
|
||||
assert contextClass != null;
|
||||
|
||||
if (OverrideImplementExploreUtil.getMethodSignaturesToOverride(contextClass).isEmpty() && expectedValues.length != 0) {
|
||||
fail();
|
||||
}
|
||||
|
||||
final Collection<CandidateInfo> candidateInfos = OverrideImplementExploreUtil.getMethodsToOverrideImplement(contextClass, false);
|
||||
final PsiMethodWithOverridingPercentMember[] searchResults = PsiMethodWithOverridingPercentMember
|
||||
.calculateOverridingPercents(candidateInfos);
|
||||
assertSize(resultSize, searchResults);
|
||||
|
||||
final Set<Pair<String, Integer>> actualValues = new HashSet<Pair<String, Integer>>();
|
||||
for (PsiMethodWithOverridingPercentMember searchResult : searchResults) {
|
||||
actualValues.add(Pair.<String, Integer>create(searchResult.getElement().getName(), searchResult.getOverridingPercent()));
|
||||
}
|
||||
|
||||
final Set<Pair<String, Integer>> expectedValuesSet = ContainerUtil.newHashSet(expectedValues);
|
||||
|
||||
assertEquals(expectedValuesSet, actualValues);
|
||||
}
|
||||
|
||||
private static Pair<String, Integer> pair(final String methodName, final int percent) {
|
||||
return Pair.create(methodName, percent);
|
||||
}
|
||||
}
|
||||
@@ -58,10 +58,11 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
protected JComponent[] myOptionControls;
|
||||
private JCheckBox myCopyJavadocCheckbox;
|
||||
private JCheckBox myInsertOverrideAnnotationCheckbox;
|
||||
|
||||
private final ArrayList<MemberNode> mySelectedNodes = new ArrayList<MemberNode>();
|
||||
|
||||
private boolean mySorted = false;
|
||||
private final SortEmAction mySortAction;
|
||||
|
||||
private boolean myAlphabeticallySorted = false;
|
||||
private boolean myShowClasses = true;
|
||||
protected boolean myAllowEmptySelection = false;
|
||||
private boolean myAllowMultiSelection;
|
||||
@@ -70,29 +71,31 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
private final JComponent myHeaderPanel;
|
||||
|
||||
protected T[] myElements;
|
||||
protected Comparator<ElementNode> myComparator = new OrderComparator();
|
||||
|
||||
protected final HashMap<MemberNode,ParentNode> myNodeToParentMap = new HashMap<MemberNode, ParentNode>();
|
||||
protected final HashMap<ClassMember, MemberNode> myElementToNodeMap = new HashMap<ClassMember, MemberNode>();
|
||||
protected final ArrayList<ContainerNode> myContainerNodes = new ArrayList<ContainerNode>();
|
||||
|
||||
protected LinkedHashSet<T> mySelectedElements;
|
||||
|
||||
@NonNls private static final String PROP_SORTED = "MemberChooser.sorted";
|
||||
@NonNls private static final String PROP_SHOWCLASSES = "MemberChooser.showClasses";
|
||||
@NonNls private static final String PROP_COPYJAVADOC = "MemberChooser.copyJavadoc";
|
||||
|
||||
public MemberChooser(T[] elements,
|
||||
boolean allowEmptySelection,
|
||||
boolean allowMultiSelection,
|
||||
@NotNull Project project) {
|
||||
this(elements, allowEmptySelection, allowMultiSelection, project, false);
|
||||
}
|
||||
|
||||
public MemberChooser(T[] elements,
|
||||
boolean allowEmptySelection,
|
||||
boolean allowMultiSelection,
|
||||
@NotNull Project project,
|
||||
@Nullable JComponent headerPanel,
|
||||
JComponent[] optionControls) {
|
||||
this(elements, allowEmptySelection, allowMultiSelection, project, false, headerPanel, optionControls);
|
||||
this(allowEmptySelection, allowMultiSelection, project, false, headerPanel, optionControls);
|
||||
resetElements(elements);
|
||||
init();
|
||||
}
|
||||
|
||||
public MemberChooser(T[] elements, boolean allowEmptySelection, boolean allowMultiSelection, @NotNull Project project) {
|
||||
this(elements, allowEmptySelection, allowMultiSelection, project, false);
|
||||
}
|
||||
|
||||
public MemberChooser(T[] elements,
|
||||
@@ -108,19 +111,19 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
boolean allowMultiSelection,
|
||||
@NotNull Project project,
|
||||
boolean isInsertOverrideVisible,
|
||||
JComponent headerPanel
|
||||
@Nullable JComponent headerPanel
|
||||
) {
|
||||
this(elements, allowEmptySelection, allowMultiSelection, project, isInsertOverrideVisible, headerPanel, null);
|
||||
this(allowEmptySelection, allowMultiSelection, project, isInsertOverrideVisible, headerPanel, null);
|
||||
resetElements(elements);
|
||||
init();
|
||||
}
|
||||
|
||||
private MemberChooser(T[] elements,
|
||||
boolean allowEmptySelection,
|
||||
boolean allowMultiSelection,
|
||||
@NotNull Project project,
|
||||
boolean isInsertOverrideVisible,
|
||||
JComponent headerPanel,
|
||||
@Nullable JComponent[] optionControls
|
||||
) {
|
||||
protected MemberChooser(boolean allowEmptySelection,
|
||||
boolean allowMultiSelection,
|
||||
@NotNull Project project,
|
||||
boolean isInsertOverrideVisible,
|
||||
@Nullable JComponent headerPanel,
|
||||
@Nullable JComponent[] optionControls) {
|
||||
super(project, true);
|
||||
myAllowEmptySelection = allowEmptySelection;
|
||||
myAllowMultiSelection = allowMultiSelection;
|
||||
@@ -129,12 +132,26 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
myHeaderPanel = headerPanel;
|
||||
myTree = createTree();
|
||||
myOptionControls = optionControls;
|
||||
resetElements(elements);
|
||||
init();
|
||||
mySortAction = new SortEmAction();
|
||||
mySortAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.ALT_MASK)), myTree);
|
||||
}
|
||||
|
||||
protected void resetElementsWithDefaultComparator(T[] elements, final boolean restoreSelectedElements) {
|
||||
myComparator = myAlphabeticallySorted ? new AlphaComparator() : new OrderComparator();
|
||||
resetElements(elements, null, restoreSelectedElements);
|
||||
}
|
||||
|
||||
public void resetElements(T[] elements) {
|
||||
resetElements(elements, null, false);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void resetElements(T[] elements, final @Nullable Comparator<T> sortComparator, final boolean restoreSelectedElements) {
|
||||
final List<T> selectedElements = restoreSelectedElements && mySelectedElements != null ? new ArrayList<T>(mySelectedElements) : null;
|
||||
myElements = elements;
|
||||
if (sortComparator != null) {
|
||||
myComparator = new ElementNodeComparatorWrapper(sortComparator);
|
||||
}
|
||||
mySelectedNodes.clear();
|
||||
myNodeToParentMap.clear();
|
||||
myElementToNodeMap.clear();
|
||||
@@ -150,9 +167,7 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
myTree.setModel(myTreeModel);
|
||||
myTree.setRootVisible(false);
|
||||
|
||||
doSort();
|
||||
|
||||
defaultExpandTree();
|
||||
restoreTree();
|
||||
|
||||
if (myOptionControls == null) {
|
||||
myCopyJavadocCheckbox = new NonFocusableCheckBox(IdeBundle.message("checkbox.copy.javadoc"));
|
||||
@@ -167,6 +182,13 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
|
||||
myTree.doLayout();
|
||||
setOKActionEnabled(myElements != null && myElements.length > 0);
|
||||
|
||||
if (selectedElements != null) {
|
||||
selectElements(selectedElements.toArray(new ClassMember[selectedElements.size()]));
|
||||
}
|
||||
if (mySelectedElements == null || mySelectedElements.isEmpty()) {
|
||||
expandFirst();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -175,7 +197,7 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
private DefaultTreeModel buildModel() {
|
||||
final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
|
||||
final Ref<Integer> count = new Ref<Integer>(0);
|
||||
final FactoryMap<MemberChooserObject,ParentNode> map = new FactoryMap<MemberChooserObject,ParentNode>() {
|
||||
final FactoryMap<MemberChooserObject, ParentNode> map = new FactoryMap<MemberChooserObject, ParentNode>() {
|
||||
@Override
|
||||
protected ParentNode create(final MemberChooserObject key) {
|
||||
ParentNode node = null;
|
||||
@@ -322,37 +344,10 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
BorderLayout.NORTH);
|
||||
|
||||
// Tree
|
||||
|
||||
myTree.setCellRenderer(getTreeCellRenderer());
|
||||
UIUtil.setLineStyleAngled(myTree);
|
||||
myTree.setRootVisible(false);
|
||||
myTree.setShowsRootHandles(true);
|
||||
myTree.addKeyListener(new TreeKeyListener());
|
||||
myTree.addTreeSelectionListener(new MyTreeSelectionListener());
|
||||
|
||||
if (!myAllowMultiSelection) {
|
||||
myTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
}
|
||||
|
||||
if (getRootNode().getChildCount() > 0) {
|
||||
myTree.expandRow(0);
|
||||
myTree.setSelectionRow(1);
|
||||
}
|
||||
expandFirst();
|
||||
defaultExpandTree();
|
||||
installSpeedSearch();
|
||||
|
||||
new DoubleClickListener() {
|
||||
@Override
|
||||
protected boolean onDoubleClick(MouseEvent e) {
|
||||
if (myTree.getPathForLocation(e.getX(), e.getY()) != null) {
|
||||
doOKAction();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}.installOn(myTree);
|
||||
|
||||
TreeUtil.installActions(myTree);
|
||||
JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTree);
|
||||
scrollPane.setPreferredSize(new Dimension(350, 450));
|
||||
panel.add(scrollPane, BorderLayout.CENTER);
|
||||
@@ -360,8 +355,40 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
return panel;
|
||||
}
|
||||
|
||||
private void expandFirst() {
|
||||
if (getRootNode().getChildCount() > 0) {
|
||||
myTree.expandRow(0);
|
||||
myTree.setSelectionRow(1);
|
||||
}
|
||||
}
|
||||
|
||||
protected Tree createTree() {
|
||||
return new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
|
||||
final Tree tree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
|
||||
|
||||
tree.setCellRenderer(getTreeCellRenderer());
|
||||
UIUtil.setLineStyleAngled(tree);
|
||||
tree.setRootVisible(false);
|
||||
tree.setShowsRootHandles(true);
|
||||
tree.addKeyListener(new TreeKeyListener());
|
||||
tree.addTreeSelectionListener(new MyTreeSelectionListener());
|
||||
|
||||
if (!myAllowMultiSelection) {
|
||||
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
|
||||
}
|
||||
|
||||
new DoubleClickListener() {
|
||||
@Override
|
||||
protected boolean onDoubleClick(MouseEvent e) {
|
||||
if (tree.getPathForLocation(e.getX(), e.getY()) != null) {
|
||||
doOKAction();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}.installOn(tree);
|
||||
|
||||
TreeUtil.installActions(tree);
|
||||
return tree;
|
||||
}
|
||||
|
||||
protected TreeCellRenderer getTreeCellRenderer() {
|
||||
@@ -411,15 +438,26 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
return new SpeedSearchComparator(false);
|
||||
}
|
||||
|
||||
protected void disableAlphabeticalSorting(final AnActionEvent event) {
|
||||
mySortAction.setSelected(event, false);
|
||||
}
|
||||
|
||||
protected void onAlphabeticalSortingEnabled(final AnActionEvent event) {
|
||||
//do nothing by default
|
||||
}
|
||||
|
||||
protected void fillToolbarActions(DefaultActionGroup group) {
|
||||
SortEmAction sortAction = new SortEmAction();
|
||||
sortAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.ALT_MASK)), myTree);
|
||||
setSorted(PropertiesComponent.getInstance().isTrueValue(PROP_SORTED));
|
||||
group.add(sortAction);
|
||||
final boolean alphabeticallySorted = PropertiesComponent.getInstance().isTrueValue(PROP_SORTED);
|
||||
if (alphabeticallySorted) {
|
||||
setSortComparator(new OrderComparator());
|
||||
}
|
||||
myAlphabeticallySorted = alphabeticallySorted;
|
||||
group.add(mySortAction);
|
||||
|
||||
if (!supportsNestedContainers()) {
|
||||
ShowContainersAction showContainersAction = getShowContainersAction();
|
||||
showContainersAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK)), myTree);
|
||||
showContainersAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.ALT_MASK)),
|
||||
myTree);
|
||||
setShowClasses(PropertiesComponent.getInstance().isTrueValue(PROP_SHOWCLASSES));
|
||||
group.add(showContainersAction);
|
||||
}
|
||||
@@ -469,41 +507,46 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
return myCopyJavadocCheckbox.isSelected();
|
||||
}
|
||||
|
||||
public boolean isInsertOverrideAnnotation () {
|
||||
public boolean isInsertOverrideAnnotation() {
|
||||
return myIsInsertOverrideVisible && myInsertOverrideAnnotationCheckbox.isSelected();
|
||||
}
|
||||
|
||||
private boolean isSorted() {
|
||||
return mySorted;
|
||||
private boolean isAlphabeticallySorted() {
|
||||
return myAlphabeticallySorted;
|
||||
}
|
||||
|
||||
private void setSorted(boolean sorted) {
|
||||
if (mySorted == sorted) return;
|
||||
mySorted = sorted;
|
||||
@SuppressWarnings("unchecked")
|
||||
protected void changeSortComparator(final Comparator<T> comparator) {
|
||||
setSortComparator(new ElementNodeComparatorWrapper(comparator));
|
||||
}
|
||||
|
||||
private void setSortComparator(Comparator<ElementNode> sortComparator) {
|
||||
if (myComparator.equals(sortComparator)) return;
|
||||
myComparator = sortComparator;
|
||||
doSort();
|
||||
}
|
||||
|
||||
private void doSort() {
|
||||
Pair<ElementNode,List<ElementNode>> pair = storeSelection();
|
||||
protected void doSort() {
|
||||
Pair<ElementNode, List<ElementNode>> pair = storeSelection();
|
||||
|
||||
Enumeration<ParentNode> children = getRootNodeChildren();
|
||||
while (children.hasMoreElements()) {
|
||||
ParentNode classNode = children.nextElement();
|
||||
sortNode(classNode, mySorted);
|
||||
sortNode(classNode, myComparator);
|
||||
myTreeModel.nodeStructureChanged(classNode);
|
||||
}
|
||||
|
||||
restoreSelection(pair);
|
||||
}
|
||||
|
||||
private static void sortNode(ParentNode node, boolean sorted) {
|
||||
private static void sortNode(ParentNode node, final Comparator<ElementNode> sortComparator) {
|
||||
ArrayList<MemberNode> arrayList = new ArrayList<MemberNode>();
|
||||
Enumeration<MemberNode> children = node.children();
|
||||
while (children.hasMoreElements()) {
|
||||
arrayList.add(children.nextElement());
|
||||
}
|
||||
|
||||
Collections.sort(arrayList, sorted ? new AlphaComparator() : new OrderComparator());
|
||||
Collections.sort(arrayList, sortComparator);
|
||||
|
||||
replaceChildren(node, arrayList);
|
||||
}
|
||||
@@ -515,10 +558,8 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
}
|
||||
}
|
||||
|
||||
private void setShowClasses(boolean showClasses) {
|
||||
myShowClasses = showClasses;
|
||||
|
||||
Pair<ElementNode,List<ElementNode>> selection = storeSelection();
|
||||
protected void restoreTree() {
|
||||
Pair<ElementNode, List<ElementNode>> selection = storeSelection();
|
||||
|
||||
DefaultMutableTreeNode root = getRootNode();
|
||||
if (!myShowClasses || myContainerNodes.isEmpty()) {
|
||||
@@ -537,23 +578,25 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
for (MemberNode memberNode : memberNodesList) {
|
||||
newRoot.add(memberNode);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
otherObjects.add(nextElement);
|
||||
}
|
||||
}
|
||||
replaceChildren(root, otherObjects);
|
||||
sortNode(newRoot, mySorted);
|
||||
sortNode(newRoot, myComparator);
|
||||
if (newRoot.children().hasMoreElements()) root.add(newRoot);
|
||||
}
|
||||
else {
|
||||
Enumeration<ParentNode> children = getRootNodeChildren();
|
||||
if (children.hasMoreElements()) {
|
||||
while (children.hasMoreElements()) {
|
||||
ParentNode allClassesNode = children.nextElement();
|
||||
Enumeration<MemberNode> memberNodes = allClassesNode.children();
|
||||
ArrayList<MemberNode> arrayList = new ArrayList<MemberNode>();
|
||||
while (memberNodes.hasMoreElements()) {
|
||||
arrayList.add(memberNodes.nextElement());
|
||||
}
|
||||
Collections.sort(arrayList, myComparator);
|
||||
for (MemberNode memberNode : arrayList) {
|
||||
myNodeToParentMap.get(memberNode).add(memberNode);
|
||||
}
|
||||
@@ -567,6 +610,11 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
restoreSelection(selection);
|
||||
}
|
||||
|
||||
private void setShowClasses(boolean showClasses) {
|
||||
myShowClasses = showClasses;
|
||||
restoreTree();
|
||||
}
|
||||
|
||||
protected String getAllContainersNodeName() {
|
||||
return IdeBundle.message("node.memberchooser.all.classes");
|
||||
}
|
||||
@@ -618,7 +666,7 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
@Override
|
||||
public void dispose() {
|
||||
PropertiesComponent instance = PropertiesComponent.getInstance();
|
||||
instance.setValue(PROP_SORTED, Boolean.toString(isSorted()));
|
||||
instance.setValue(PROP_SORTED, Boolean.toString(isAlphabeticallySorted()));
|
||||
instance.setValue(PROP_SHOWCLASSES, Boolean.toString(myShowClasses));
|
||||
|
||||
if (myCopyJavadocCheckbox != null) {
|
||||
@@ -640,7 +688,7 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
if (mySelectedElements != null && !mySelectedElements.isEmpty()) {
|
||||
T selectedElement = mySelectedElements.iterator().next();
|
||||
if (selectedElement instanceof ClassMemberWithElement) {
|
||||
sink.put(LangDataKeys.PSI_ELEMENT, ((ClassMemberWithElement) selectedElement).getElement());
|
||||
sink.put(LangDataKeys.PSI_ELEMENT, ((ClassMemberWithElement)selectedElement).getElement());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -773,17 +821,21 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
|
||||
@Override
|
||||
public boolean isSelected(AnActionEvent event) {
|
||||
return isSorted();
|
||||
return isAlphabeticallySorted();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(AnActionEvent event, boolean flag) {
|
||||
setSorted(flag);
|
||||
myAlphabeticallySorted = flag;
|
||||
setSortComparator(flag ? new AlphaComparator() : new OrderComparator());
|
||||
if (flag) {
|
||||
MemberChooser.this.onAlphabeticalSortingEnabled(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ShowContainersAction getShowContainersAction() {
|
||||
return new ShowContainersAction(IdeBundle.message("action.show.classes"), PlatformIcons.CLASS_ICON);
|
||||
return new ShowContainersAction(IdeBundle.message("action.show.classes"), PlatformIcons.CLASS_ICON);
|
||||
}
|
||||
|
||||
protected class ShowContainersAction extends ToggleAction {
|
||||
@@ -841,16 +893,30 @@ public class MemberChooser<T extends ClassMember> extends DialogWrapper implemen
|
||||
}
|
||||
|
||||
protected static class OrderComparator implements Comparator<ElementNode> {
|
||||
public OrderComparator() {} // To make this class instanceable from the subclasses
|
||||
public OrderComparator() {
|
||||
} // To make this class instanceable from the subclasses
|
||||
|
||||
@Override
|
||||
public int compare(ElementNode n1, ElementNode n2) {
|
||||
if (n1.getDelegate() instanceof ClassMemberWithElement
|
||||
&& n2.getDelegate() instanceof ClassMemberWithElement) {
|
||||
return ((ClassMemberWithElement)n1.getDelegate()).getElement().getTextOffset()
|
||||
- ((ClassMemberWithElement)n2.getDelegate()).getElement().getTextOffset();
|
||||
if (n1.getDelegate() instanceof ClassMemberWithElement && n2.getDelegate() instanceof ClassMemberWithElement) {
|
||||
return ((ClassMemberWithElement)n1.getDelegate()).getElement().getTextOffset() -
|
||||
((ClassMemberWithElement)n2.getDelegate()).getElement().getTextOffset();
|
||||
}
|
||||
return n1.getOrder() - n2.getOrder();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ElementNodeComparatorWrapper<T> implements Comparator<ElementNode> {
|
||||
private final Comparator<T> myDelegate;
|
||||
|
||||
public ElementNodeComparatorWrapper(final Comparator<T> delegate) {
|
||||
myDelegate = delegate;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public int compare(final ElementNode o1, final ElementNode o2) {
|
||||
return myDelegate.compare((T) o1.getDelegate(), (T) o2.getDelegate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user