From d510ea90862262bfaa2edf57e6b09510f3781367 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Tue, 4 Aug 2009 15:48:43 +0400 Subject: [PATCH] class members refactoring refactoring --- .../generation/ui/GenerateEqualsWizard.java | 56 +-- ...LanguageDependentMembersRefactoringSupport.java | 30 ++ .../ClassMembersRefactoringSupport.java | 25 + .../DependentMembersCollectorBase.java | 50 ++ .../classMembers/MemberDependencyGraph.java | 12 +- .../refactoring/classMembers/MemberInfoBase.java | 98 ++++ .../refactoring/classMembers/MemberInfoChange.java | 41 ++ .../classMembers/MemberInfoChangeListener.java | 17 + .../refactoring}/classMembers/MemberInfoModel.java | 19 +- .../classMembers/ANDCombinedMemberInfoModel.java | 35 +- .../classMembers/AbstractMemberInfoStorage.java | 135 ++++++ .../AbstractUsesDependencyMemberInfoModel.java | 41 ++ .../classMembers/DelegatingMemberInfoModel.java | 25 +- .../classMembers/DependencyMemberInfoModel.java | 74 +++ .../classMembers/MemberDependenciesStorage.java | 40 ++ .../classMembers/MemberInfoTooltipManager.java | 33 ++ .../UsedByDependencyMemberInfoModel.java | 27 ++ .../classMembers/UsedByMemberDependencyGraph.java | 98 ++++ .../classMembers/UsesMemberDependencyGraph.java | 65 +-- .../ui/AbstractMemberSelectionTable.java | 389 +++++++++++++++ .../src/META-INF/LangExtensionPoints.xml | 2 + .../extractInterface/ExtractInterfaceDialog.java | 18 +- .../ExtractMethodObjectProcessor.java | 8 +- .../extractSuperclass/ExtractSuperBaseDialog.java | 9 +- .../extractSuperclass/ExtractSuperclassDialog.java | 18 +- .../ExtractSuperclassHandler.java | 4 +- .../extractclass/ExtractClassDialog.java | 17 +- .../InheritanceToDelegationDialog.java | 22 +- .../InheritanceToDelegationHandler.java | 12 +- .../InlineSuperClassRefactoringProcessor.java | 2 +- .../memberPullUp/JavaPullUpHandler.java | 7 +- .../refactoring/memberPullUp/PullUpDialog.java | 16 +- .../refactoring/memberPullUp/PullUpHelper.java | 2 +- .../memberPushDown/JavaPushDownHandler.java | 5 +- .../refactoring/memberPushDown/PushDownDialog.java | 23 +- .../move/moveMembers/MoveMembersDialog.java | 14 +- .../removemiddleman/RemoveMiddlemanDialog.java | 10 +- .../removemiddleman/RemoveMiddlemanProcessor.java | 4 +- .../refactoring/ui/MemberSelectionPanel.java | 3 +- .../refactoring/ui/MemberSelectionTable.java | 527 ++++----------------- .../util/classMembers/ClassMembersUtil.java | 10 +- .../classMembers/DependencyMemberInfoModel.java | 72 --- .../classMembers/DependentMembersCollector.java | 35 ++ .../InterfaceDependencyMemberInfoModel.java | 9 +- .../InterfaceMemberDependencyGraph.java | 3 +- .../classMembers/MemberDependenciesStorage.java | 56 --- .../refactoring/util/classMembers/MemberInfo.java | 78 +-- .../util/classMembers/MemberInfoChange.java | 23 - .../classMembers/MemberInfoChangeListener.java | 15 - .../util/classMembers/MemberInfoStorage.java | 226 +++------ .../classMembers/MemberInfoTooltipManager.java | 64 --- .../UsedByDependencyMemberInfoModel.java | 26 - .../classMembers/UsedByMemberDependencyGraph.java | 96 ---- ...UsesAndInterfacesDependencyMemberInfoModel.java | 10 +- .../UsesDependencyMemberInfoModel.java | 86 ++-- .../intellij/refactoring/RemoveMiddleManTest.java | 2 +- .../java/JavaClassMembersRefactoringSupport.java | 21 + .../testIntegration/TestIntegrationUtils.java | 2 +- .../createTest/CreateTestAction.java | 4 +- .../createTest/CreateTestDialog.java | 6 +- 60 files changed, 1612 insertions(+), 1265 deletions(-) create mode 100644 lang-api/src/com/intellij/lang/LanguageDependentMembersRefactoringSupport.java create mode 100644 lang-api/src/com/intellij/refactoring/classMembers/ClassMembersRefactoringSupport.java create mode 100644 lang-api/src/com/intellij/refactoring/classMembers/DependentMembersCollectorBase.java rename {refactoring/impl/com/intellij/refactoring/util => lang-api/src/com/intellij/refactoring}/classMembers/MemberDependencyGraph.java (69%) create mode 100644 lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java create mode 100644 lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChange.java create mode 100644 lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChangeListener.java rename {refactoring/impl/com/intellij/refactoring/util => lang-api/src/com/intellij/refactoring}/classMembers/MemberInfoModel.java (51%) rename {refactoring/impl/com/intellij/refactoring/util => lang-impl/src/com/intellij/refactoring}/classMembers/ANDCombinedMemberInfoModel.java (56%) create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/AbstractMemberInfoStorage.java create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java rename {refactoring/impl/com/intellij/refactoring/util => lang-impl/src/com/intellij/refactoring}/classMembers/DelegatingMemberInfoModel.java (55%) create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/DependencyMemberInfoModel.java create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/MemberInfoTooltipManager.java create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/UsedByDependencyMemberInfoModel.java create mode 100644 lang-impl/src/com/intellij/refactoring/classMembers/UsedByMemberDependencyGraph.java rename {refactoring/impl/com/intellij/refactoring/util => lang-impl/src/com/intellij/refactoring}/classMembers/UsesMemberDependencyGraph.java (54%) create mode 100644 lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionTable.java rewrite refactoring/impl/com/intellij/refactoring/ui/MemberSelectionTable.java (96%) delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java create mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/DependentMembersCollector.java delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChange.java delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java rewrite refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java (78%) delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java delete mode 100644 refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java rewrite refactoring/impl/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java (64%) create mode 100644 source/com/intellij/lang/java/JavaClassMembersRefactoringSupport.java diff --git a/codeInsight/impl/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java b/codeInsight/impl/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java index ac84989a1b..7ee87786f6 100644 --- a/codeInsight/impl/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java +++ b/codeInsight/impl/com/intellij/codeInsight/generation/ui/GenerateEqualsWizard.java @@ -9,11 +9,12 @@ import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.VerticalFlowLayout; import com.intellij.psi.*; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoModel; +import com.intellij.refactoring.classMembers.MemberInfoTooltipManager; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; -import com.intellij.refactoring.util.classMembers.MemberInfoModel; -import com.intellij.refactoring.util.classMembers.MemberInfoTooltipManager; import com.intellij.ui.NonFocusableCheckBox; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -25,8 +26,8 @@ import javax.swing.event.TableModelListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.util.ArrayList; -import java.util.Map; +import java.util.*; +import java.util.List; /** * @author dsl @@ -45,7 +46,7 @@ public class GenerateEqualsWizard extends AbstractWizard { private final int myEqualsStepCode; private final int myHashcodeStepCode; - private final MemberInfo[] myClassFields; + private final List myClassFields; private static final MyMemberInfoFilter MEMBER_INFO_FILTER = new MyMemberInfoFilter(); @@ -69,10 +70,10 @@ public class GenerateEqualsWizard extends AbstractWizard { myEqualsPanel = null; } if (needHashCode) { - final MemberInfo[] hashCodeMemberInfos; + final List hashCodeMemberInfos; if (needEquals) { myFieldsToHashCode = createFieldToMemberInfoMap(true); - hashCodeMemberInfos = new MemberInfo[0]; + hashCodeMemberInfos = Collections.emptyList(); } else { hashCodeMemberInfos = myClassFields; @@ -92,7 +93,7 @@ public class GenerateEqualsWizard extends AbstractWizard { } myTestBoxedStep=testBoxedStep; myNonNullPanel = new MemberSelectionPanel(CodeInsightBundle.message("generate.equals.hashcode.non.null.fields.chooser.title"), - new MemberInfo[0], null); + Collections.emptyList(), null); myFieldsToNonNull = createFieldToMemberInfoMap(false); for (final Map.Entry entry : myFieldsToNonNull.entrySet()) { entry.getValue().setChecked(((PsiField)entry.getKey()).getModifierList().findAnnotation(NotNull.class.getName()) != null); @@ -146,7 +147,7 @@ public class GenerateEqualsWizard extends AbstractWizard { return memberInfosToFields(myNonNullPanel.getTable().getSelectedMemberInfos()); } - private static PsiField[] memberInfosToFields(MemberInfo[] infos) { + private static PsiField[] memberInfosToFields(Collection infos) { ArrayList list = new ArrayList(); for (MemberInfo info : infos) { list.add((PsiField)info.getMember()); @@ -159,7 +160,7 @@ public class GenerateEqualsWizard extends AbstractWizard { equalsFieldsSelected(); } else if (getCurrentStep() == myHashcodeStepCode && myHashCodePanel != null) { - MemberInfo[] selectedMemberInfos = myHashCodePanel.getTable().getSelectedMemberInfos(); + Collection selectedMemberInfos = myHashCodePanel.getTable().getSelectedMemberInfos(); updateNonNullMemberInfos(selectedMemberInfos); } @@ -180,7 +181,7 @@ public class GenerateEqualsWizard extends AbstractWizard { } private void equalsFieldsSelected() { - MemberInfo[] selectedMemberInfos = myEqualsPanel.getTable().getSelectedMemberInfos(); + Collection selectedMemberInfos = myEqualsPanel.getTable().getSelectedMemberInfos(); updateHashCodeMemberInfos(selectedMemberInfos); updateNonNullMemberInfos(selectedMemberInfos); } @@ -194,7 +195,7 @@ public class GenerateEqualsWizard extends AbstractWizard { } private HashMap createFieldToMemberInfoMap(boolean checkedByDefault) { - MemberInfo[] memberInfos = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false); + Collection memberInfos = MemberInfo.extractClassMembers(myClass, MEMBER_INFO_FILTER, false); final HashMap result = new HashMap(); for (MemberInfo memberInfo : memberInfos) { memberInfo.setChecked(checkedByDefault); @@ -203,26 +204,27 @@ public class GenerateEqualsWizard extends AbstractWizard { return result; } - private void updateHashCodeMemberInfos(MemberInfo[] equalsMemberInfos) { + private void updateHashCodeMemberInfos(Collection equalsMemberInfos) { if (myHashCodePanel == null) return; - MemberInfo[] hashCodeFields = new MemberInfo[equalsMemberInfos.length]; + List hashCodeFields = new ArrayList(); - for (int i = 0; i < equalsMemberInfos.length; i++) { - hashCodeFields[i] = (MemberInfo)myFieldsToHashCode.get(equalsMemberInfos[i].getMember()); + for (MemberInfo equalsMemberInfo : equalsMemberInfos) { + hashCodeFields.add((MemberInfo)myFieldsToHashCode.get(equalsMemberInfo.getMember())); } + myHashCodePanel.getTable().setMemberInfos(hashCodeFields); } - private void updateNonNullMemberInfos(MemberInfo[] equalsMemberInfos) { + private void updateNonNullMemberInfos(Collection equalsMemberInfos) { final ArrayList list = new ArrayList(); - for (MemberInfo equalsMemberInfo : equalsMemberInfos) { + for (MemberInfoBase equalsMemberInfo : equalsMemberInfos) { PsiField field = (PsiField)equalsMemberInfo.getMember(); if (!(field.getType() instanceof PsiPrimitiveType)) { list.add(myFieldsToNonNull.get(equalsMemberInfo.getMember())); } } - myNonNullPanel.getTable().setMemberInfos(list.toArray(new MemberInfo[list.size()])); + myNonNullPanel.getTable().setMemberInfos(list); } private void updateStatus() { @@ -334,15 +336,15 @@ public class GenerateEqualsWizard extends AbstractWizard { } - private static class MyMemberInfoFilter implements MemberInfo.Filter { + private static class MyMemberInfoFilter implements MemberInfoBase.Filter { public boolean includeMember(PsiMember element) { return element instanceof PsiField && !element.hasModifierProperty(PsiModifier.STATIC); } } - private static class EqualsMemberInfoModel implements MemberInfoModel { - MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { + private static class EqualsMemberInfoModel implements MemberInfoModel { + MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { public String getTooltip(MemberInfo memberInfo) { if (checkForProblems(memberInfo) == OK) return null; if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error"); @@ -387,7 +389,7 @@ public class GenerateEqualsWizard extends AbstractWizard { return OK; } - public void memberInfoChanged(MemberInfoChange event) { + public void memberInfoChanged(MemberInfoChange event) { } public String getTooltipText(MemberInfo member) { @@ -395,8 +397,8 @@ public class GenerateEqualsWizard extends AbstractWizard { } } - private static class HashCodeMemberInfoModel implements MemberInfoModel { - private final MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { + private static class HashCodeMemberInfoModel implements MemberInfoModel { + private final MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { public String getTooltip(MemberInfo memberInfo) { if (isMemberEnabled(memberInfo)) return null; if (!(memberInfo.getMember() instanceof PsiField)) return CodeInsightBundle.message("generate.equals.hashcode.internal.error"); @@ -431,7 +433,7 @@ public class GenerateEqualsWizard extends AbstractWizard { return OK; } - public void memberInfoChanged(MemberInfoChange event) { + public void memberInfoChanged(MemberInfoChange event) { } public String getTooltipText(MemberInfo member) { diff --git a/lang-api/src/com/intellij/lang/LanguageDependentMembersRefactoringSupport.java b/lang-api/src/com/intellij/lang/LanguageDependentMembersRefactoringSupport.java new file mode 100644 index 0000000000..591d2b9cb1 --- /dev/null +++ b/lang-api/src/com/intellij/lang/LanguageDependentMembersRefactoringSupport.java @@ -0,0 +1,30 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.lang; + +import com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport; + +/** + * @author Dennis.Ushakov + */ +public class LanguageDependentMembersRefactoringSupport extends LanguageExtension { + public static final LanguageDependentMembersRefactoringSupport INSTANCE = new LanguageDependentMembersRefactoringSupport(); + + private LanguageDependentMembersRefactoringSupport() { + super("com.intellij.lang.refactoringSupport.classMembersRefactoringSupport"); + } +} diff --git a/lang-api/src/com/intellij/refactoring/classMembers/ClassMembersRefactoringSupport.java b/lang-api/src/com/intellij/refactoring/classMembers/ClassMembersRefactoringSupport.java new file mode 100644 index 0000000000..8894ac5f71 --- /dev/null +++ b/lang-api/src/com/intellij/refactoring/classMembers/ClassMembersRefactoringSupport.java @@ -0,0 +1,25 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.refactoring.classMembers; + +/** + * @author Dennis.Ushakov + */ +public interface ClassMembersRefactoringSupport { + DependentMembersCollectorBase createDependentMembersCollector(Object clazz, Object superClass); + boolean isProperMember(MemberInfoBase member); +} diff --git a/lang-api/src/com/intellij/refactoring/classMembers/DependentMembersCollectorBase.java b/lang-api/src/com/intellij/refactoring/classMembers/DependentMembersCollectorBase.java new file mode 100644 index 0000000000..4a2f740ac5 --- /dev/null +++ b/lang-api/src/com/intellij/refactoring/classMembers/DependentMembersCollectorBase.java @@ -0,0 +1,50 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; + +import java.util.HashSet; +import java.util.Set; + +/** + * @author Dennis.Ushakov + */ +public abstract class DependentMembersCollectorBase { + protected final HashSet myCollection = new HashSet(); + private final C myClass; + private final C mySuperClass; + + public DependentMembersCollectorBase(C clazz, C superClass) { + myClass = clazz; + mySuperClass = superClass; + } + + public abstract void collect(T member); + + public C getClazz() { + return myClass; + } + + public Set getCollection() { + return myCollection; + } + + public C getSuperClass() { + return mySuperClass; + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java b/lang-api/src/com/intellij/refactoring/classMembers/MemberDependencyGraph.java similarity index 69% rename from refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java rename to lang-api/src/com/intellij/refactoring/classMembers/MemberDependencyGraph.java index 38d86e9590..b4cc2fb863 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependencyGraph.java +++ b/lang-api/src/com/intellij/refactoring/classMembers/MemberDependencyGraph.java @@ -6,25 +6,25 @@ * To change template for new interface use * Code Style | Class Templates options (Tools | IDE Options). */ -package com.intellij.refactoring.util.classMembers; +package com.intellij.refactoring.classMembers; -import com.intellij.psi.*; +import com.intellij.psi.PsiElement; import java.util.Set; -public interface MemberDependencyGraph { +public interface MemberDependencyGraph> { /** * Call this to notify that a new member info have been added * or a state of some memberInfo have been changed. * @param memberInfo */ - void memberChanged(MemberInfo memberInfo); + void memberChanged(M memberInfo); /** * Returns class members that are dependent on checked MemberInfos. * @return set of PsiMembers */ - Set getDependent(); + Set getDependent(); /** * Returns PsiMembers of checked MemberInfos that member depends on. @@ -32,5 +32,5 @@ public interface MemberDependencyGraph { * @param member * @return set of PsiMembers */ - Set getDependenciesOf(PsiMember member); + Set getDependenciesOf(T member); } diff --git a/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java new file mode 100644 index 0000000000..04182c7b5d --- /dev/null +++ b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoBase.java @@ -0,0 +1,98 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; +import com.intellij.openapi.diagnostic.Logger; + +/** + * @author Dennis.Ushakov + */ +public abstract class MemberInfoBase { + protected static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.MemberInfo"); + protected T myMember; + protected boolean isStatic; + protected String displayName; + private boolean isChecked = false; + /** + * TRUE if is overriden, FALSE if implemented, null if not implemented or overriden + */ + protected Boolean overrides; + private boolean toAbstract = false; + + public MemberInfoBase(T member) { + myMember = member; + } + + public boolean isStatic() { + return isStatic; + } + + public String getDisplayName() { + return displayName; + } + + public boolean isChecked() { + return isChecked; + } + + public void setChecked(boolean checked) { + isChecked = checked; + } + + /** + * Returns Boolean.TRUE if getMember() overrides something, Boolean.FALSE if getMember() + * implements something, null if neither is the case. + * If getMember() is a PsiClass, returns Boolean.TRUE if this class comes + * from 'extends', Boolean.FALSE if it comes from 'implements' list, null + * if it is an inner class. + */ + public Boolean getOverrides() { + return overrides; + } + + public T getMember() { + LOG.assertTrue(myMember.isValid()); + return myMember; + } + + /** + * Use this method solely to update element from smart pointer and the likes + * @param element + */ + public void updateMember(T element) { + myMember = element; + } + + public boolean isToAbstract() { + return toAbstract; + } + + public void setToAbstract(boolean toAbstract) { + this.toAbstract = toAbstract; + } + + public static interface Filter { + boolean includeMember(T member); + } + + public static class EmptyFilter implements Filter { + public boolean includeMember(T member) { + return true; + } + } +} diff --git a/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChange.java b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChange.java new file mode 100644 index 0000000000..f1e91a92bd --- /dev/null +++ b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChange.java @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2009 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:41:29 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; + +import java.util.Collection; + +public class MemberInfoChange> { + private final Collection myChangedMembers; + + public MemberInfoChange(Collection changedMembers) { + myChangedMembers = changedMembers; + } + + public Collection getChangedMembers() { + return myChangedMembers; + } +} diff --git a/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChangeListener.java b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChangeListener.java new file mode 100644 index 0000000000..947bd5c14a --- /dev/null +++ b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoChangeListener.java @@ -0,0 +1,17 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:41:09 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; + +import java.util.EventListener; + +public interface MemberInfoChangeListener> extends EventListener { + void memberInfoChanged(MemberInfoChange event); +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoModel.java b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoModel.java similarity index 51% rename from refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoModel.java rename to lang-api/src/com/intellij/refactoring/classMembers/MemberInfoModel.java index f953d6ec0f..8f99501e44 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoModel.java +++ b/lang-api/src/com/intellij/refactoring/classMembers/MemberInfoModel.java @@ -6,32 +6,33 @@ * To change template for new class use * Code Style | Class Templates options (Tools | IDE Options). */ -package com.intellij.refactoring.util.classMembers; +package com.intellij.refactoring.classMembers; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -public interface MemberInfoModel extends MemberInfoChangeListener { +public interface MemberInfoModel> extends MemberInfoChangeListener { int OK = 0; int WARNING = 1; int ERROR = 2; - boolean isMemberEnabled(MemberInfo member); + boolean isMemberEnabled(M member); - boolean isCheckedWhenDisabled(MemberInfo member); + boolean isCheckedWhenDisabled(M member); - boolean isAbstractEnabled(MemberInfo member); + boolean isAbstractEnabled(M member); - boolean isAbstractWhenDisabled(MemberInfo member); + boolean isAbstractWhenDisabled(M member); /** * Returns state of abstract checkbox for particular abstract member. * @param member MemberInfo for an ABSTRACT member * @return TRUE if fixed and true, FALSE if fixed and false, null if dont care */ - Boolean isFixedAbstract(MemberInfo member); + Boolean isFixedAbstract(M member); - int checkForProblems(@NotNull MemberInfo member); + int checkForProblems(@NotNull M member); - String getTooltipText(MemberInfo member); + String getTooltipText(M member); } diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java b/lang-impl/src/com/intellij/refactoring/classMembers/ANDCombinedMemberInfoModel.java similarity index 56% rename from refactoring/impl/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java rename to lang-impl/src/com/intellij/refactoring/classMembers/ANDCombinedMemberInfoModel.java index 48824afa60..b087b9c40a 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/ANDCombinedMemberInfoModel.java +++ b/lang-impl/src/com/intellij/refactoring/classMembers/ANDCombinedMemberInfoModel.java @@ -6,15 +6,16 @@ * To change template for new class use * Code Style | Class Templates options (Tools | IDE Options). */ -package com.intellij.refactoring.util.classMembers; +package com.intellij.refactoring.classMembers; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -public class ANDCombinedMemberInfoModel implements MemberInfoModel { - private final MemberInfoModel myModel1; - private final MemberInfoModel myModel2; - private final MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { - public String getTooltip(MemberInfo memberInfo) { +public class ANDCombinedMemberInfoModel> implements MemberInfoModel { + private final MemberInfoModel myModel1; + private final MemberInfoModel myModel2; + private final MemberInfoTooltipManager myTooltipManager = new MemberInfoTooltipManager(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(M memberInfo) { final String tooltipText1 = myModel1.getTooltipText(memberInfo); if (tooltipText1 != null) return tooltipText1; return myModel2.getTooltipText(memberInfo); @@ -22,53 +23,53 @@ public class ANDCombinedMemberInfoModel implements MemberInfoModel { }); - public ANDCombinedMemberInfoModel(MemberInfoModel model1, MemberInfoModel model2) { + public ANDCombinedMemberInfoModel(MemberInfoModel model1, MemberInfoModel model2) { myModel1 = model1; myModel2 = model2; } - public boolean isMemberEnabled(MemberInfo member) { + public boolean isMemberEnabled(M member) { return myModel1.isMemberEnabled(member) && myModel2.isMemberEnabled(member); } - public boolean isCheckedWhenDisabled(MemberInfo member) { + public boolean isCheckedWhenDisabled(M member) { return myModel1.isCheckedWhenDisabled(member) && myModel2.isCheckedWhenDisabled(member); } - public boolean isAbstractEnabled(MemberInfo member) { + public boolean isAbstractEnabled(M member) { return myModel1.isAbstractEnabled(member) && myModel2.isAbstractEnabled(member); } - public boolean isAbstractWhenDisabled(MemberInfo member) { + public boolean isAbstractWhenDisabled(M member) { return myModel1.isAbstractWhenDisabled(member) && myModel2.isAbstractWhenDisabled(member); } - public int checkForProblems(@NotNull MemberInfo member) { + public int checkForProblems(@NotNull M member) { return Math.max(myModel1.checkForProblems(member), myModel2.checkForProblems(member)); } - public void memberInfoChanged(MemberInfoChange event) { + public void memberInfoChanged(MemberInfoChange event) { myTooltipManager.invalidate(); myModel1.memberInfoChanged(event); myModel2.memberInfoChanged(event); } - public Boolean isFixedAbstract(MemberInfo member) { + public Boolean isFixedAbstract(M member) { final Boolean fixedAbstract1 = myModel1.isFixedAbstract(member); if(fixedAbstract1 == null) return null; if(fixedAbstract1.equals(myModel2.isFixedAbstract(member))) return fixedAbstract1; return null; } - public MemberInfoModel getModel1() { + public MemberInfoModel getModel1() { return myModel1; } - public MemberInfoModel getModel2() { + public MemberInfoModel getModel2() { return myModel2; } - public String getTooltipText(MemberInfo member) { + public String getTooltipText(M member) { return myTooltipManager.getTooltip(member); } } diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/AbstractMemberInfoStorage.java b/lang-impl/src/com/intellij/refactoring/classMembers/AbstractMemberInfoStorage.java new file mode 100644 index 0000000000..e9ebbde634 --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/AbstractMemberInfoStorage.java @@ -0,0 +1,135 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; + +import java.util.*; + +/** + * @author Dennis.Ushakov + */ +public abstract class AbstractMemberInfoStorage> { + protected final HashMap> myClassToSubclassesMap = new HashMap>(); + private final HashMap> myTargetClassToExtendingMap = new HashMap>(); + private final HashMap> myClassToMemberInfoMap = new HashMap>(); + private final C myClass; + protected final MemberInfoBase.Filter myFilter; + private final HashMap> myTargetClassToMemberInfosMap = new HashMap>(); + private final HashMap> myTargetClassToMemberInfosListMap = new HashMap>(); + private final HashMap> myTargetClassToDuplicatedMemberInfosMap = new HashMap>(); + + public AbstractMemberInfoStorage(C aClass, MemberInfoBase.Filter memberInfoFilter) { + myClass = aClass; + buildSubClassesMap(aClass); + myFilter = memberInfoFilter; + } + + private Set getAllClasses() { + return myClassToSubclassesMap.keySet(); + } + + public Set getExtending(C baseClass) { + Set result = myTargetClassToExtendingMap.get(baseClass); + if(result == null) { + result = new HashSet(); + result.add(baseClass); + final Set allClasses = getAllClasses(); + for (C aClass : allClasses) { + if (isInheritor(baseClass, aClass)) { + result.add(aClass); + } + } + myTargetClassToExtendingMap.put(baseClass, result); + } + + return result; + } + + protected abstract boolean isInheritor(C baseClass, C aClass); + + protected abstract void buildSubClassesMap(C aClass); + + public List getClassMemberInfos(C aClass) { + List result = myClassToMemberInfoMap.get(aClass); + if(result == null) { + ArrayList temp = new ArrayList(); + extractClassMembers(aClass, temp); + result = Collections.unmodifiableList(temp); + myClassToMemberInfoMap.put(aClass, result); + } + return result; + } + + protected abstract void extractClassMembers(C aClass, ArrayList temp); + + public List getMemberInfosList(C baseClass) { + List result = myTargetClassToMemberInfosMap.get(baseClass); + + if (result == null) { + Set list = getIntermediateClassesMemberInfosList(baseClass); + result = Collections.unmodifiableList(new ArrayList(list)); + myTargetClassToMemberInfosMap.put(baseClass, result); + } + + return result; + } + + private Set getIntermediateClassesMemberInfosList(C targetClass) { + LinkedHashSet result = myTargetClassToMemberInfosListMap.get(targetClass); + if(result == null) { + result = new LinkedHashSet(); + Set subclasses = getSubclasses(targetClass); + for (C subclass : subclasses) { + List memberInfos = getClassMemberInfos(subclass); + result.addAll(memberInfos); + } + for (C subclass : subclasses) { + result.addAll(getIntermediateClassesMemberInfosList(subclass)); + } + myTargetClassToMemberInfosListMap.put(targetClass, result); + } + return result; + } + + protected LinkedHashSet getSubclasses(C aClass) { + LinkedHashSet result = myClassToSubclassesMap.get(aClass); + if(result == null) { + result = new LinkedHashSet(); + myClassToSubclassesMap.put(aClass, result); + } + return result; + } + + public Set getDuplicatedMemberInfos(C baseClass) { + HashSet result = myTargetClassToDuplicatedMemberInfosMap.get(baseClass); + + if(result == null) { + result = buildDuplicatedMemberInfos(baseClass); + myTargetClassToDuplicatedMemberInfosMap.put(baseClass, result); + } + return result; + } + + private HashSet buildDuplicatedMemberInfos(C baseClass) { + HashSet result = new HashSet(); + List memberInfos = getMemberInfosList(baseClass); + + for (int i = 0; i < memberInfos.size(); i++) { + final M memberInfo = memberInfos.get(i); + final PsiElement member = memberInfo.getMember(); + + for(int j = 0; j < i; j++) { + final M memberInfo1 = memberInfos.get(j); + final PsiElement member1 = memberInfo1.getMember(); + if(memberConflict(member1, member)) { + result.add(memberInfo); +// We let the first one be... +// result.add(memberInfo1); + } + } + } + return result; + } + + protected abstract boolean memberConflict(PsiElement member1, PsiElement member); +} diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java b/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java new file mode 100644 index 0000000000..d7563b6bad --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/AbstractUsesDependencyMemberInfoModel.java @@ -0,0 +1,41 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +/** + * @author Dennis.Ushakov + */ +public abstract class AbstractUsesDependencyMemberInfoModel> extends DependencyMemberInfoModel { + protected final C myClass; + + public AbstractUsesDependencyMemberInfoModel(C aClass, C superClass, boolean recursive) { + super(new UsesMemberDependencyGraph(aClass, superClass, recursive), ERROR); + myClass = aClass; + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(M memberInfo) { + return ((UsesMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); + } + }); + } + + public int checkForProblems(@NotNull M memberInfo) { + final int problem = super.checkForProblems(memberInfo); + return doCheck(memberInfo, problem); + } + + protected abstract int doCheck(@NotNull M memberInfo, int problem); + + public void setSuperClass(C superClass) { + setMemberDependencyGraph(new UsesMemberDependencyGraph(myClass, superClass, false)); + } + + public boolean isCheckedWhenDisabled(M member) { + return false; + } + + public Boolean isFixedAbstract(M member) { + return null; + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java b/lang-impl/src/com/intellij/refactoring/classMembers/DelegatingMemberInfoModel.java similarity index 55% rename from refactoring/impl/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java rename to lang-impl/src/com/intellij/refactoring/classMembers/DelegatingMemberInfoModel.java index e30e9d1432..604276eda9 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/DelegatingMemberInfoModel.java +++ b/lang-impl/src/com/intellij/refactoring/classMembers/DelegatingMemberInfoModel.java @@ -6,14 +6,15 @@ * To change template for new class use * Code Style | Class Templates options (Tools | IDE Options). */ -package com.intellij.refactoring.util.classMembers; +package com.intellij.refactoring.classMembers; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; -public class DelegatingMemberInfoModel implements MemberInfoModel { - private MemberInfoModel myDelegatingTarget; +public class DelegatingMemberInfoModel> implements MemberInfoModel { + private MemberInfoModel myDelegatingTarget; - public DelegatingMemberInfoModel(MemberInfoModel delegatingTarget) { + public DelegatingMemberInfoModel(MemberInfoModel delegatingTarget) { myDelegatingTarget = delegatingTarget; } @@ -25,35 +26,35 @@ public class DelegatingMemberInfoModel implements MemberInfoModel { return myDelegatingTarget; } - public boolean isMemberEnabled(MemberInfo member) { + public boolean isMemberEnabled(M member) { return myDelegatingTarget.isMemberEnabled(member); } - public boolean isCheckedWhenDisabled(MemberInfo member) { + public boolean isCheckedWhenDisabled(M member) { return myDelegatingTarget.isCheckedWhenDisabled(member); } - public boolean isAbstractEnabled(MemberInfo member) { + public boolean isAbstractEnabled(M member) { return myDelegatingTarget.isAbstractEnabled(member); } - public boolean isAbstractWhenDisabled(MemberInfo member) { + public boolean isAbstractWhenDisabled(M member) { return myDelegatingTarget.isAbstractWhenDisabled(member); } - public int checkForProblems(@NotNull MemberInfo member) { + public int checkForProblems(@NotNull M member) { return myDelegatingTarget.checkForProblems(member); } - public void memberInfoChanged(MemberInfoChange event) { + public void memberInfoChanged(MemberInfoChange event) { myDelegatingTarget.memberInfoChanged(event); } - public Boolean isFixedAbstract(MemberInfo member) { + public Boolean isFixedAbstract(M member) { return myDelegatingTarget.isFixedAbstract(member); } - public String getTooltipText(MemberInfo member) { + public String getTooltipText(M member) { return myDelegatingTarget.getTooltipText(member); } } diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/DependencyMemberInfoModel.java b/lang-impl/src/com/intellij/refactoring/classMembers/DependencyMemberInfoModel.java new file mode 100644 index 0000000000..a05b5b532e --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/DependencyMemberInfoModel.java @@ -0,0 +1,74 @@ +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 09.07.2002 + * Time: 15:03:42 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +import java.util.Collection; + +public abstract class DependencyMemberInfoModel> implements MemberInfoModel { + protected MemberDependencyGraph myMemberDependencyGraph; + private final int myProblemLevel; + private MemberInfoTooltipManager myTooltipManager; + + public DependencyMemberInfoModel(MemberDependencyGraph memberDependencyGraph, int problemLevel) { + myMemberDependencyGraph = memberDependencyGraph; + myProblemLevel = problemLevel; + } + + public void setTooltipProvider(MemberInfoTooltipManager.TooltipProvider tooltipProvider) { + myTooltipManager = new MemberInfoTooltipManager(tooltipProvider); + } + + public boolean isAbstractEnabled(M member) { + return true; + } + + public boolean isAbstractWhenDisabled(M member) { + return false; + } + + public boolean isMemberEnabled(M member) { + return true; + } + + public int checkForProblems(@NotNull M memberInfo) { + if (memberInfo.isChecked()) return OK; + final T member = memberInfo.getMember(); + + if (myMemberDependencyGraph.getDependent().contains(member)) { + return myProblemLevel; + } + return OK; + } + + public void setMemberDependencyGraph(MemberDependencyGraph memberDependencyGraph) { + myMemberDependencyGraph = memberDependencyGraph; + } + + public void memberInfoChanged(MemberInfoChange event) { + memberInfoChanged(event.getChangedMembers()); + } + + public void memberInfoChanged(final Collection changedMembers) { + if (myTooltipManager != null) myTooltipManager.invalidate(); + for (M changedMember : changedMembers) { + myMemberDependencyGraph.memberChanged(changedMember); + } + } + + public String getTooltipText(M member) { + if (myTooltipManager != null) { + return myTooltipManager.getTooltip(member); + } else { + return null; + } + } +} diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java b/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java new file mode 100644 index 0000000000..98ea02a948 --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/MemberDependenciesStorage.java @@ -0,0 +1,40 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.lang.LanguageDependentMembersRefactoringSupport; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; + +import java.util.Map; +import java.util.Set; + + +public class MemberDependenciesStorage { + protected final C myClass; + private final C mySuperClass; + private final Map> myDependencyGraph; + + public MemberDependenciesStorage(C aClass, C superClass) { + myClass = aClass; + mySuperClass = superClass; + myDependencyGraph = new HashMap>(); + } + + protected Set getMemberDependencies(T member) { + Set result = myDependencyGraph.get(member); + if (result == null) { + DependentMembersCollectorBase collector = getCollector(); + if (collector != null) { + collector.collect(member); + result = collector.getCollection(); + } + myDependencyGraph.put(member, result); + } + return result; + } + + private DependentMembersCollectorBase getCollector() { + final ClassMembersRefactoringSupport factory = LanguageDependentMembersRefactoringSupport.INSTANCE.forLanguage(myClass.getLanguage()); + return factory != null ? factory.createDependentMembersCollector(myClass, mySuperClass) : null; + } +} diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/MemberInfoTooltipManager.java b/lang-impl/src/com/intellij/refactoring/classMembers/MemberInfoTooltipManager.java new file mode 100644 index 0000000000..30dcede8ba --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/MemberInfoTooltipManager.java @@ -0,0 +1,33 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.PsiElement; +import com.intellij.util.containers.HashMap; + +/** + * @author dsl + */ +public class MemberInfoTooltipManager> { + private final HashMap myTooltips = new HashMap(); + private final TooltipProvider myProvider; + + public interface TooltipProvider> { + String getTooltip(M memberInfo); + } + + public MemberInfoTooltipManager(TooltipProvider provider) { + myProvider = provider; + } + + public void invalidate() { + myTooltips.clear(); + } + + public String getTooltip(M member) { + if(myTooltips.keySet().contains(member)) { + return myTooltips.get(member); + } + String tooltip = myProvider.getTooltip(member); + myTooltips.put(member, tooltip); + return tooltip; + } +} diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/UsedByDependencyMemberInfoModel.java b/lang-impl/src/com/intellij/refactoring/classMembers/UsedByDependencyMemberInfoModel.java new file mode 100644 index 0000000000..aa9c438111 --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/UsedByDependencyMemberInfoModel.java @@ -0,0 +1,27 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiElement; + +/** + * @author dsl + */ +public class UsedByDependencyMemberInfoModel> extends DependencyMemberInfoModel { + + public UsedByDependencyMemberInfoModel(C aClass) { + super(new UsedByMemberDependencyGraph(aClass), ERROR); + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + public String getTooltip(M memberInfo) { + return ((UsedByMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); + } + }); + } + + public boolean isCheckedWhenDisabled(M member) { + return false; + } + + public Boolean isFixedAbstract(M member) { + return null; + } +} diff --git a/lang-impl/src/com/intellij/refactoring/classMembers/UsedByMemberDependencyGraph.java b/lang-impl/src/com/intellij/refactoring/classMembers/UsedByMemberDependencyGraph.java new file mode 100644 index 0000000000..c7b5e3d1df --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/classMembers/UsedByMemberDependencyGraph.java @@ -0,0 +1,98 @@ +package com.intellij.refactoring.classMembers; + +import com.intellij.lang.LanguageDependentMembersRefactoringSupport; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiNamedElement; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.util.containers.HashMap; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + +public class UsedByMemberDependencyGraph> implements MemberDependencyGraph { + protected HashSet mySelectedNormal; + protected HashSet mySelectedAbstract; + protected HashSet myMembers; + protected HashSet myDependencies = null; + protected HashMap> myDependenciesToDependent = null; + private final MemberDependenciesStorage myMemberDependenciesStorage; + + UsedByMemberDependencyGraph(C aClass) { + myMemberDependenciesStorage = new MemberDependenciesStorage(aClass, null); + mySelectedNormal = new HashSet(); + mySelectedAbstract = new HashSet(); + myMembers = new HashSet(); + } + + public void memberChanged(M memberInfo) { + final ClassMembersRefactoringSupport support = + LanguageDependentMembersRefactoringSupport.INSTANCE.forLanguage(memberInfo.getMember().getLanguage()); + if (support != null && support.isProperMember(memberInfo)) { + myDependencies = null; + myDependenciesToDependent = null; + T member = memberInfo.getMember(); + myMembers.add(member); + if (!memberInfo.isChecked()) { + mySelectedNormal.remove(member); + mySelectedAbstract.remove(member); + } + else { + if (memberInfo.isToAbstract()) { + mySelectedNormal.remove(member); + mySelectedAbstract.add(member); + } + else { + mySelectedNormal.add(member); + mySelectedAbstract.remove(member); + } + } + } + } + + public Set getDependent() { + if(myDependencies == null) { + myDependencies = new HashSet(); + myDependenciesToDependent = new HashMap>(); + for (T member : myMembers) { + Set dependent = myMemberDependenciesStorage.getMemberDependencies(member); + for (final T aDependent : dependent) { + if (mySelectedNormal.contains(aDependent) && !mySelectedAbstract.contains(aDependent)) { + myDependencies.add(member); + HashSet deps = myDependenciesToDependent.get(member); + if (deps == null) { + deps = new HashSet(); + myDependenciesToDependent.put(member, deps); + } + deps.add(aDependent); + } + } + } + } + + return myDependencies; + } + + public Set getDependenciesOf(T member) { + final Set dependent = getDependent(); + if(!dependent.contains(member)) return null; + return myDependenciesToDependent.get(member); + } + + public String getElementTooltip(T element) { + final Set dependencies = getDependenciesOf(element); + if (dependencies == null || dependencies.size() == 0) return null; + + ArrayList strings = new ArrayList(); + for (T dep : dependencies) { + if (dep instanceof PsiNamedElement) { + strings.add(((PsiNamedElement)dep).getName()); + } + } + + if (strings.isEmpty()) return null; + return RefactoringBundle.message("uses.0", StringUtil.join(strings, ", ")); + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java b/lang-impl/src/com/intellij/refactoring/classMembers/UsesMemberDependencyGraph.java similarity index 54% rename from refactoring/impl/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java rename to lang-impl/src/com/intellij/refactoring/classMembers/UsesMemberDependencyGraph.java index 1b43d7d17a..3e420578a1 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesMemberDependencyGraph.java +++ b/lang-impl/src/com/intellij/refactoring/classMembers/UsesMemberDependencyGraph.java @@ -6,12 +6,13 @@ * To change template for new class use * Code Style | Class Templates options (Tools | IDE Options). */ -package com.intellij.refactoring.util.classMembers; +package com.intellij.refactoring.classMembers; +import com.intellij.lang.LanguageDependentMembersRefactoringSupport; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMember; +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiElement; import com.intellij.refactoring.RefactoringBundle; import com.intellij.util.containers.HashMap; @@ -19,44 +20,44 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.Set; -public class UsesMemberDependencyGraph implements MemberDependencyGraph { +public class UsesMemberDependencyGraph> implements MemberDependencyGraph { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.util.classMembers.UsesMemberDependencyGraph"); - protected HashSet mySelectedNormal; - protected HashSet mySelectedAbstract; - protected HashSet myDependencies = null; - protected HashMap> myDependenciesToDependentMap = null; + protected HashSet mySelectedNormal; + protected HashSet mySelectedAbstract; + protected HashSet myDependencies = null; + protected HashMap> myDependenciesToDependentMap = null; private final boolean myRecursive; - private final MemberDependenciesStorage myMemberDependenciesStorage; + private final MemberDependenciesStorage myMemberDependenciesStorage; - public UsesMemberDependencyGraph(PsiClass aClass, PsiClass superClass, boolean recursive) { + public UsesMemberDependencyGraph(C aClass, C superClass, boolean recursive) { myRecursive = recursive; - mySelectedNormal = new HashSet(); - mySelectedAbstract = new HashSet(); - myMemberDependenciesStorage = new MemberDependenciesStorage(aClass, superClass); + mySelectedNormal = new HashSet(); + mySelectedAbstract = new HashSet(); + myMemberDependenciesStorage = new MemberDependenciesStorage(aClass, superClass); } - public Set getDependent() { + public Set getDependent() { if (myDependencies == null) { - myDependencies = new HashSet(); - myDependenciesToDependentMap = new HashMap>(); + myDependencies = new HashSet(); + myDependenciesToDependentMap = new HashMap>(); buildDeps(null, mySelectedNormal); } return myDependencies; } - public Set getDependenciesOf(PsiMember member) { + public Set getDependenciesOf(T member) { final Set dependent = getDependent(); if(!dependent.contains(member)) return null; return myDependenciesToDependentMap.get(member); } - public String getElementTooltip(PsiMember element) { - final Set dependencies = getDependenciesOf(element); + public String getElementTooltip(T element) { + final Set dependencies = getDependenciesOf(element); if(dependencies == null || dependencies.size() == 0) return null; ArrayList strings = new ArrayList(); - for (PsiMember dep : dependencies) { + for (T dep : dependencies) { strings.add(dep.getName()); } @@ -65,21 +66,21 @@ public class UsesMemberDependencyGraph implements MemberDependencyGraph { } - private void buildDeps(PsiMember sourceElement, Set members) { + private void buildDeps(T sourceElement, Set members) { if (myRecursive) { buildDepsRecursively(sourceElement, members); } else { - for (final PsiMember member : members) { - for (final PsiMember dependency : myMemberDependenciesStorage.getMemberDependencies(member)) { + for (final T member : members) { + for (final T dependency : myMemberDependenciesStorage.getMemberDependencies(member)) { addDependency(dependency, member); } } } } - private void buildDepsRecursively(final PsiMember sourceElement, final Set members) { - for (PsiMember member : members) { + private void buildDepsRecursively(final T sourceElement, final Set members) { + for (T member : members) { if (!myDependencies.contains(member)) { addDependency(member, sourceElement); if (!mySelectedAbstract.contains(member)) { @@ -89,26 +90,28 @@ public class UsesMemberDependencyGraph implements MemberDependencyGraph { } } - private void addDependency(final PsiMember member, final PsiMember sourceElement) { + private void addDependency(final T member, final T sourceElement) { if (LOG.isDebugEnabled()) { LOG.debug(member.toString()); } myDependencies.add(member); if (sourceElement != null) { - HashSet relations = myDependenciesToDependentMap.get(member); + HashSet relations = myDependenciesToDependentMap.get(member); if (relations == null) { - relations = new HashSet(); + relations = new HashSet(); myDependenciesToDependentMap.put(member, relations); } relations.add(sourceElement); } } - public void memberChanged(MemberInfo memberInfo) { - if (ClassMembersUtil.isProperMember(memberInfo)) { + public void memberChanged(M memberInfo) { + final ClassMembersRefactoringSupport support = + LanguageDependentMembersRefactoringSupport.INSTANCE.forLanguage(memberInfo.getMember().getLanguage()); + if (support != null && support.isProperMember(memberInfo)) { myDependencies = null; myDependenciesToDependentMap = null; - PsiMember member = memberInfo.getMember(); + T member = memberInfo.getMember(); if (!memberInfo.isChecked()) { mySelectedNormal.remove(member); mySelectedAbstract.remove(member); diff --git a/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionTable.java b/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionTable.java new file mode 100644 index 0000000000..bedeb92b5b --- /dev/null +++ b/lang-impl/src/com/intellij/refactoring/ui/AbstractMemberSelectionTable.java @@ -0,0 +1,389 @@ +package com.intellij.refactoring.ui; + +import com.intellij.openapi.actionSystem.DataKey; +import com.intellij.openapi.actionSystem.DataSink; +import com.intellij.openapi.actionSystem.LangDataKeys; +import com.intellij.openapi.actionSystem.TypeSafeDataProvider; +import com.intellij.openapi.util.IconLoader; +import com.intellij.psi.PsiElement; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoChangeListener; +import com.intellij.refactoring.classMembers.MemberInfoModel; +import com.intellij.ui.BooleanTableCellRenderer; +import com.intellij.ui.ColoredTableCellRenderer; +import com.intellij.ui.RowIcon; +import com.intellij.ui.SimpleTextAttributes; +import com.intellij.util.ui.EmptyIcon; +import com.intellij.util.ui.Table; +import org.jetbrains.annotations.NotNull; + +import javax.swing.*; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumnModel; +import java.awt.*; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * @author Dennis.Ushakov + */ +public abstract class AbstractMemberSelectionTable> extends Table implements TypeSafeDataProvider { + protected static final int CHECKED_COLUMN = 0; + protected static final int DISPLAY_NAME_COLUMN = 1; + protected static final int ABSTRACT_COLUMN = 2; + protected static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/general/overridingMethod.png"); + protected static final Icon IMPLEMENTING_METHOD_ICON = IconLoader.getIcon("/general/implementingMethod.png"); + protected static final Icon EMPTY_OVERRIDE_ICON = new EmptyIcon(16, 16); + protected final String myAbstractColumnHeader; + protected static final String DISPLAY_NAME_COLUMN_HEADER = RefactoringBundle.message("member.column"); + protected List myMemberInfos; + protected final boolean myAbstractEnabled; + protected MemberInfoModel myMemberInfoModel; + protected MyTableModel myTableModel; + protected static final int OVERRIDE_ICON_POSITION = 2; + protected static final int VISIBILITY_ICON_POSITION = 1; + protected static final int MEMBER_ICON_POSITION = 0; + + public AbstractMemberSelectionTable(Collection memberInfos, MemberInfoModel memberInfoModel, String abstractColumnHeader) { + myAbstractEnabled = abstractColumnHeader != null; + myAbstractColumnHeader = abstractColumnHeader; + myTableModel = new MyTableModel(this); + + myMemberInfos = new ArrayList(memberInfos); + if (memberInfoModel != null) { + myMemberInfoModel = memberInfoModel; + } + else { + myMemberInfoModel = new DefaultMemberInfoModel(); + } + + setModel(myTableModel); + + TableColumnModel model = getColumnModel(); + model.getColumn(DISPLAY_NAME_COLUMN).setCellRenderer(new MyTableRenderer(this)); + model.getColumn(CHECKED_COLUMN).setCellRenderer(new MyBooleanRenderer(this)); + final int checkBoxWidth = new JCheckBox().getPreferredSize().width; + model.getColumn(CHECKED_COLUMN).setMaxWidth(checkBoxWidth); + model.getColumn(CHECKED_COLUMN).setMinWidth(checkBoxWidth); + + if (myAbstractEnabled) { + int width = + (int)(1.3 * getFontMetrics(getFont()).charsWidth(myAbstractColumnHeader.toCharArray(), 0, + myAbstractColumnHeader.length())); + model.getColumn(ABSTRACT_COLUMN).setMaxWidth(width); + model.getColumn(ABSTRACT_COLUMN).setPreferredWidth(width); + model.getColumn(ABSTRACT_COLUMN).setCellRenderer(new MyBooleanRenderer(this)); + } + + setPreferredScrollableViewportSize(new Dimension(400, getRowHeight() * 12)); + getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + setShowGrid(false); + setIntercellSpacing(new Dimension(0, 0)); + + new MyEnableDisableAction().register(); + } + + public Collection getSelectedMemberInfos() { + ArrayList list = new ArrayList(myMemberInfos.size()); + for (M info : myMemberInfos) { + if (isMemberInfoSelected(info)) { +// if (info.isChecked() || (!myMemberInfoModel.isMemberEnabled(info) && myMemberInfoModel.isCheckedWhenDisabled(info))) { + list.add(info); + } + } + return list; + } + + private boolean isMemberInfoSelected(final M info) { + final boolean memberEnabled = myMemberInfoModel.isMemberEnabled(info); + return (memberEnabled && info.isChecked()) || (!memberEnabled && myMemberInfoModel.isCheckedWhenDisabled(info)); + } + + public MemberInfoModel getMemberInfoModel() { + return myMemberInfoModel; + } + + public void setMemberInfoModel(MemberInfoModel memberInfoModel) { + myMemberInfoModel = memberInfoModel; + } + + public void fireExternalDataChange() { + myTableModel.fireTableDataChanged(); + } + + public void setMemberInfos(Collection memberInfos) { + myMemberInfos = new ArrayList(memberInfos); + fireMemberInfoChange(memberInfos); + myTableModel.fireTableDataChanged(); + } + + public void addMemberInfoChangeListener(MemberInfoChangeListener l) { + listenerList.add(MemberInfoChangeListener.class, l); + } + + protected void fireMemberInfoChange(Collection changedMembers) { + Object[] list = listenerList.getListenerList(); + + MemberInfoChange event = new MemberInfoChange(changedMembers); + for (Object element : list) { + if (element instanceof MemberInfoChangeListener) { + ((MemberInfoChangeListener)element).memberInfoChanged(event); + } + } + } + + public void calcData(final DataKey key, final DataSink sink) { + if (key == LangDataKeys.PSI_ELEMENT) { + final Collection memberInfos = getSelectedMemberInfos(); + if (memberInfos.size() > 0) { + sink.put(LangDataKeys.PSI_ELEMENT, memberInfos.iterator().next().getMember()); + } + } + } + + public void scrollSelectionInView() { + for(int i=0; i> implements MemberInfoModel { + public boolean isMemberEnabled(M member) { + return true; + } + + public boolean isCheckedWhenDisabled(M member) { + return false; + } + + public boolean isAbstractEnabled(M member) { + return true; + } + + public boolean isAbstractWhenDisabled(M member) { + return false; + } + + + public int checkForProblems(@NotNull M member) { + return OK; + } + + public void memberInfoChanged(MemberInfoChange event) { + } + + public Boolean isFixedAbstract(M member) { + return null; + } + + public String getTooltipText(M member) { + return null; + } + } + + private static class MyTableModel> extends AbstractTableModel { + private final AbstractMemberSelectionTable myTable; + + public MyTableModel(AbstractMemberSelectionTable table) { + myTable = table; + } + + public int getColumnCount() { + if (myTable.myAbstractEnabled) { + return 3; + } + else { + return 2; + } + } + + public int getRowCount() { + return myTable.myMemberInfos.size(); + } + + public Class getColumnClass(int columnIndex) { + if (columnIndex == CHECKED_COLUMN || columnIndex == ABSTRACT_COLUMN) { + return Boolean.class; + } + return super.getColumnClass(columnIndex); + } + + public Object getValueAt(int rowIndex, int columnIndex) { + final M memberInfo = myTable.myMemberInfos.get(rowIndex); + switch (columnIndex) { + case CHECKED_COLUMN: + if (myTable.myMemberInfoModel.isMemberEnabled(memberInfo)) { + return memberInfo.isChecked() ? Boolean.TRUE : Boolean.FALSE; + } + else { + return myTable.myMemberInfoModel.isCheckedWhenDisabled(memberInfo); + } + case ABSTRACT_COLUMN: + { + return myTable.getAbstractColumnValue(memberInfo); + } + case DISPLAY_NAME_COLUMN: + return memberInfo.getDisplayName(); + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public String getColumnName(int column) { + switch (column) { + case CHECKED_COLUMN: + return " "; + case ABSTRACT_COLUMN: + return myTable.myAbstractColumnHeader; + case DISPLAY_NAME_COLUMN: + return DISPLAY_NAME_COLUMN_HEADER; + default: + throw new RuntimeException("Incorrect column index"); + } + } + + public boolean isCellEditable(int rowIndex, int columnIndex) { + switch (columnIndex) { + case CHECKED_COLUMN: + return myTable.myMemberInfoModel.isMemberEnabled(myTable.myMemberInfos.get(rowIndex)); + case ABSTRACT_COLUMN: + return myTable.isAbstractColumnEditable(rowIndex); + } + return false; + } + + + public void setValueAt(final Object aValue, final int rowIndex, final int columnIndex) { + if (columnIndex == CHECKED_COLUMN) { + myTable.myMemberInfos.get(rowIndex).setChecked(((Boolean)aValue).booleanValue()); + } + else if (columnIndex == ABSTRACT_COLUMN) { + myTable.myMemberInfos.get(rowIndex).setToAbstract(((Boolean)aValue).booleanValue()); + } + + Collection changed = Collections.singletonList(myTable.myMemberInfos.get(rowIndex)); + myTable.fireMemberInfoChange(changed); + fireTableDataChanged(); +// fireTableRowsUpdated(rowIndex, rowIndex); + } + } + + private class MyEnableDisableAction extends EnableDisableAction { + + protected JTable getTable() { + return AbstractMemberSelectionTable.this; + } + + protected void applyValue(int[] rows, boolean valueToBeSet) { + List changedInfo = new ArrayList(); + for (int row : rows) { + final M memberInfo = myMemberInfos.get(row); + memberInfo.setChecked(valueToBeSet); + changedInfo.add(memberInfo); + } + fireMemberInfoChange(changedInfo); + final int selectedRow = getSelectedRow(); + myTableModel.fireTableDataChanged(); + setRowSelectionInterval(selectedRow, selectedRow); + } + + protected boolean isRowChecked(final int row) { + return myMemberInfos.get(row).isChecked(); + } + } + + private static class MyTableRenderer> extends ColoredTableCellRenderer { + private final AbstractMemberSelectionTable myTable; + + public MyTableRenderer(AbstractMemberSelectionTable table) { + myTable = table; + } + + public void customizeCellRenderer(JTable table, final Object value, + boolean isSelected, boolean hasFocus, final int row, final int column) { + + final int modelColumn = myTable.convertColumnIndexToModel(column); + final M memberInfo = myTable.myMemberInfos.get(row); + setToolTipText(myTable.myMemberInfoModel.getTooltipText(memberInfo)); + T member = memberInfo.getMember(); + switch (modelColumn) { + case DISPLAY_NAME_COLUMN: + { + Icon memberIcon = member.getIcon(MEMBER_ICON_POSITION); + Icon overrideIcon = myTable.getOverrideIcon(memberInfo); + + RowIcon icon = new RowIcon(3); + icon.setIcon(memberIcon, MEMBER_ICON_POSITION); + myTable.setVisibilityIcon(memberInfo, icon); + icon.setIcon(overrideIcon, OVERRIDE_ICON_POSITION); + setIcon(icon); + break; + } + default: + { + setIcon(null); + } + } + final boolean cellEditable = myTable.myMemberInfoModel.isMemberEnabled(memberInfo); + setEnabled(cellEditable); + + if (value == null) return; + final int problem = myTable.myMemberInfoModel.checkForProblems(memberInfo); + Color c = null; + if (problem == MemberInfoModel.ERROR) { + c = Color.red; + } + else if (problem == MemberInfoModel.WARNING && !isSelected) { + c = Color.blue; + } + append((String)value, new SimpleTextAttributes(Font.PLAIN, c)); + } + + } + + private static class MyBooleanRenderer> extends BooleanTableCellRenderer { + private final AbstractMemberSelectionTable myTable; + + public MyBooleanRenderer(AbstractMemberSelectionTable table) { + myTable = table; + } + + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) { + Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (component instanceof JComponent) { + JComponent jComponent = (JComponent)component; + int modelColumn = myTable.convertColumnIndexToModel(column); + final M memberInfo = myTable.myMemberInfos.get(row); + + jComponent.setEnabled( + (modelColumn == CHECKED_COLUMN && myTable.myMemberInfoModel.isMemberEnabled(memberInfo) + || (modelColumn == ABSTRACT_COLUMN && memberInfo.isChecked() && myTable.isAbstractColumnEditable(row))) + ); + } + return component; + } + } +} diff --git a/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform-resources/src/META-INF/LangExtensionPoints.xml index b5f6c40631..080d712db4 100644 --- a/platform-resources/src/META-INF/LangExtensionPoints.xml +++ b/platform-resources/src/META-INF/LangExtensionPoints.xml @@ -88,6 +88,8 @@ beanClass="com.intellij.lang.LanguageExtensionPoint"/> + collectMembers(PsiClass c) { + return MemberInfo.extractClassMembers(c, new MemberInfoBase.Filter() { public boolean includeMember(PsiMember element) { if (element instanceof PsiMethod) { return element.hasModifierProperty(PsiModifier.PUBLIC) @@ -51,7 +53,7 @@ class ExtractInterfaceDialog extends ExtractSuperBaseDialog { int[] rows = getCheckedRows(); MemberInfo[] selectedMethods = new MemberInfo[rows.length]; for (int idx = 0; idx < rows.length; idx++) { - selectedMethods[idx] = myMemberInfos[rows[idx]]; + selectedMethods[idx] = myMemberInfos.get(rows[idx]); } return selectedMethods; } @@ -65,8 +67,8 @@ class ExtractInterfaceDialog extends ExtractSuperBaseDialog { } int[] rows = new int[count]; int currentRow = 0; - for (int idx = 0; idx < myMemberInfos.length; idx++) { - if (myMemberInfos[idx].isChecked()) { + for (int idx = 0; idx < myMemberInfos.size(); idx++) { + if (myMemberInfos.get(idx).isChecked()) { rows[currentRow++] = idx; } } @@ -153,7 +155,7 @@ class ExtractInterfaceDialog extends ExtractSuperBaseDialog { JPanel panel = new JPanel(new BorderLayout()); final MemberSelectionPanel memberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.form.interface"), myMemberInfos, null); - memberSelectionPanel.getTable().setMemberInfoModel(new DelegatingMemberInfoModel(memberSelectionPanel.getTable().getMemberInfoModel()) { + memberSelectionPanel.getTable().setMemberInfoModel(new DelegatingMemberInfoModel(memberSelectionPanel.getTable().getMemberInfoModel()) { public Boolean isFixedAbstract(MemberInfo member) { return Boolean.TRUE; } diff --git a/refactoring/impl/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java b/refactoring/impl/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java index bc1c02b86a..e4d3965c17 100644 --- a/refactoring/impl/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java +++ b/refactoring/impl/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectProcessor.java @@ -25,6 +25,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.BaseRefactoringProcessor; import com.intellij.refactoring.HelpID; +import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor; import com.intellij.refactoring.changeSignature.ParameterInfoImpl; import com.intellij.refactoring.extractMethod.AbstractExtractDialog; @@ -166,10 +167,9 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { protected void moveUsedMethodsToInner() { if (!myUsages.isEmpty()) { - final MemberInfo[] memberInfos = new MemberInfo[myUsages.size()]; - int i = 0; + final List memberInfos = new ArrayList(); for (MethodToMoveUsageInfo usage : myUsages) { - memberInfos[i++] = new MemberInfo((PsiMethod)usage.getElement()); + memberInfos.add(new MemberInfo((PsiMethod)usage.getElement())); } final MemberSelectionPanel panel = new MemberSelectionPanel("Methods to move to the extracted class", memberInfos, null); @@ -187,7 +187,7 @@ public class ExtractMethodObjectProcessor extends BaseRefactoringProcessor { }; dlg.show(); if (dlg.isOK()) { - for (MemberInfo memberInfo : panel.getTable().getSelectedMemberInfos()) { + for (MemberInfoBase memberInfo : panel.getTable().getSelectedMemberInfos()) { if (memberInfo.isChecked()) { myInnerClass.add(memberInfo.getMember().copy()); memberInfo.getMember().delete(); diff --git a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java index 3ed37037a5..49d82831a9 100644 --- a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java +++ b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperBaseDialog.java @@ -4,8 +4,8 @@ import com.intellij.ide.util.PackageUtil; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; -import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.roots.ProjectFileIndex; +import com.intellij.openapi.roots.ProjectRootManager; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -15,13 +15,14 @@ import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringMessageUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.ui.ReferenceEditorWithBrowseButton; import com.intellij.ui.JavaReferenceEditorUtil; +import com.intellij.ui.ReferenceEditorWithBrowseButton; import com.intellij.util.IncorrectOperationException; import javax.swing.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.util.List; /** * @author dsl @@ -30,7 +31,7 @@ public abstract class ExtractSuperBaseDialog extends RefactoringDialog { protected String myRefactoringName; protected PsiClass mySourceClass; protected PsiDirectory myTargetDirectory; - protected MemberInfo[] myMemberInfos; + protected List myMemberInfos; protected JRadioButton myRbExtractSuperclass; protected JRadioButton myRbExtractSubclass; @@ -41,7 +42,7 @@ public abstract class ExtractSuperBaseDialog extends RefactoringDialog { protected JavaDocPanel myJavaDocPanel; - public ExtractSuperBaseDialog(Project project, PsiClass sourceClass, MemberInfo[] members, String refactoringName) { + public ExtractSuperBaseDialog(Project project, PsiClass sourceClass, List members, String refactoringName) { super(project, true); myRefactoringName = refactoringName; diff --git a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java index 155a00ca84..9fcfea5f6d 100644 --- a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java +++ b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassDialog.java @@ -3,21 +3,27 @@ package com.intellij.refactoring.extractSuperclass; import com.intellij.ide.util.PackageChooserDialog; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiPackage; import com.intellij.refactoring.HelpID; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.refactoring.memberPullUp.PullUpHelper; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.util.JavaDocPolicy; -import com.intellij.refactoring.util.classMembers.*; +import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; +import java.util.List; class ExtractSuperclassDialog extends ExtractSuperBaseDialog { private final InterfaceContainmentVerifier myContainmentVerifier = new InterfaceContainmentVerifier() { @@ -34,14 +40,14 @@ class ExtractSuperclassDialog extends ExtractSuperBaseDialog { private JLabel myPackageLabel; private final Callback myCallback; - public ExtractSuperclassDialog(Project project, PsiClass sourceClass, MemberInfo[] selectedMembers, Callback callback) { + public ExtractSuperclassDialog(Project project, PsiClass sourceClass, List selectedMembers, Callback callback) { super(project, sourceClass, selectedMembers, ExtractSuperclassHandler.REFACTORING_NAME); myCallback = callback; init(); } public MemberInfo[] getSelectedMemberInfos() { - ArrayList list = new ArrayList(myMemberInfos.length); + ArrayList list = new ArrayList(myMemberInfos.size()); for (MemberInfo info : myMemberInfos) { if (info.isChecked()) { list.add(info); @@ -122,13 +128,13 @@ class ExtractSuperclassDialog extends ExtractSuperBaseDialog { final MemberSelectionPanel memberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.form.superclass"), myMemberInfos, RefactoringBundle.message("make.abstract")); panel.add(memberSelectionPanel, BorderLayout.CENTER); - final MemberInfoModel memberInfoModel = + final MemberInfoModel memberInfoModel = new UsesAndInterfacesDependencyMemberInfoModel(mySourceClass, null, false, myContainmentVerifier) { public Boolean isFixedAbstract(MemberInfo member) { return Boolean.TRUE; } }; - memberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + memberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); memberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel); memberSelectionPanel.getTable().addMemberInfoChangeListener(memberInfoModel); diff --git a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java index ee92d43d2c..5ed4c92f6d 100644 --- a/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java +++ b/refactoring/impl/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java @@ -28,6 +28,8 @@ import com.intellij.usageView.UsageViewUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import java.util.List; + public class ExtractSuperclassHandler implements RefactoringActionHandler, ExtractSuperclassDialog.Callback { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.ExtractSuperclassHandler"); @@ -78,7 +80,7 @@ public class ExtractSuperclassHandler implements RefactoringActionHandler, Extra } - final MemberInfo[] memberInfos = MemberInfo.extractClassMembers(mySubclass, new MemberInfo.Filter() { + final List memberInfos = MemberInfo.extractClassMembers(mySubclass, new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { return true; } diff --git a/refactoring/impl/com/intellij/refactoring/extractclass/ExtractClassDialog.java b/refactoring/impl/com/intellij/refactoring/extractclass/ExtractClassDialog.java index 6e1421b8fe..8042d09560 100644 --- a/refactoring/impl/com/intellij/refactoring/extractclass/ExtractClassDialog.java +++ b/refactoring/impl/com/intellij/refactoring/extractclass/ExtractClassDialog.java @@ -12,13 +12,14 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactorJBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoChangeListener; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.ui.MemberSelectionTable; import com.intellij.refactoring.ui.RefactoringDialog; -import com.intellij.refactoring.util.classMembers.DelegatingMemberInfoModel; +import com.intellij.refactoring.classMembers.DelegatingMemberInfoModel; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; -import com.intellij.refactoring.util.classMembers.MemberInfoChangeListener; import com.intellij.ui.DocumentAdapter; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NotNull; @@ -34,10 +35,10 @@ import java.util.List; import java.util.Map; @SuppressWarnings({"OverridableMethodCallInConstructor"}) -class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeListener { - private final Map myMember2CauseMap = new HashMap(); +class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeListener { + private final Map, PsiMember> myMember2CauseMap = new HashMap, PsiMember>(); private final PsiClass sourceClass; - private final MemberInfo[] memberInfo; + private final List memberInfo; private final JTextField classNameField; private final JTextField packageTextField; private final FixedSizeButton packageChooserButton; @@ -59,7 +60,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi packageTextField.getDocument().addDocumentListener(docListener); packageChooserButton = new FixedSizeButton(packageTextField); sourceClassTextField = new JTextField(); - final MemberInfo.Filter filter = new MemberInfo.Filter() { + final MemberInfo.Filter filter = new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { if (element instanceof PsiMethod) { return !((PsiMethod)element).isConstructor() && ((PsiMethod)element).getBody() != null; @@ -226,7 +227,7 @@ class ExtractClassDialog extends RefactoringDialog implements MemberInfoChangeLi final MemberSelectionPanel memberSelectionPanel = new MemberSelectionPanel(RefactorJBundle.message("members.to.extract.label"), memberInfo, null); final MemberSelectionTable table = memberSelectionPanel.getTable(); - table.setMemberInfoModel(new DelegatingMemberInfoModel(table.getMemberInfoModel()) { + table.setMemberInfoModel(new DelegatingMemberInfoModel(table.getMemberInfoModel()) { public Boolean isFixedAbstract(MemberInfo member) { return Boolean.TRUE; } diff --git a/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java b/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java index c126cf237a..0ee76d7083 100644 --- a/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java +++ b/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationDialog.java @@ -11,14 +11,14 @@ import com.intellij.psi.codeStyle.VariableKind; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoModel; import com.intellij.refactoring.ui.ClassCellRenderer; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.ui.NameSuggestionsField; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.util.classMembers.InterfaceMemberDependencyGraph; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; -import com.intellij.refactoring.util.classMembers.MemberInfoModel; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -28,12 +28,14 @@ import java.awt.*; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; public class InheritanceToDelegationDialog extends RefactoringDialog { private final PsiClass[] mySuperClasses; private final PsiClass myClass; - private final HashMap myBasesToMemberInfos; + private final HashMap> myBasesToMemberInfos; private NameSuggestionsField myFieldNameField; private NameSuggestionsField myInnerClassNameField; @@ -47,7 +49,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { public InheritanceToDelegationDialog(Project project, PsiClass aClass, PsiClass[] superClasses, - HashMap basesToMemberInfos) { + HashMap> basesToMemberInfos) { super(project, true); myProject = project; myClass = aClass; @@ -103,7 +105,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { } } - public MemberInfo[] getSelectedMemberInfos() { + public Collection getSelectedMemberInfos() { return myMemberSelectionPanel.getTable().getSelectedMemberInfos(); } @@ -119,7 +121,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { protected void doAction() { JavaRefactoringSettings.getInstance().INHERITANCE_TO_DELEGATION_DELEGATE_OTHER = myCbGenerateGetter.isSelected(); - final MemberInfo[] selectedMemberInfos = getSelectedMemberInfos(); + final Collection selectedMemberInfos = getSelectedMemberInfos(); final ArrayList implementedInterfaces = new ArrayList(); final ArrayList delegatedMethods = new ArrayList(); @@ -216,7 +218,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { gbc.gridwidth = 1; gbc.insets = new Insets(4, 8, 4, 4); - myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("delegate.members"), new MemberInfo[0], null); + myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("delegate.members"), Collections.emptyList(), null); panel.add(myMemberSelectionPanel, gbc); MyMemberInfoModel memberInfoModel = new InheritanceToDelegationDialog.MyMemberInfoModel(); myMemberSelectionPanel.getTable().setMemberInfoModel(memberInfoModel); @@ -258,7 +260,7 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { myMemberSelectionPanel.getTable().fireExternalDataChange(); } - private class MyMemberInfoModel implements MemberInfoModel { + private class MyMemberInfoModel implements MemberInfoModel { final HashMap myGraphs; public MyMemberInfoModel() { @@ -301,8 +303,8 @@ public class InheritanceToDelegationDialog extends RefactoringDialog { return null; } - public void memberInfoChanged(MemberInfoChange event) { - final MemberInfo[] changedMembers = event.getChangedMembers(); + public void memberInfoChanged(MemberInfoChange event) { + final Collection changedMembers = event.getChangedMembers(); for (MemberInfo changedMember : changedMembers) { getGraph().memberChanged(changedMember); diff --git a/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java b/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java index 9dc2eb22cd..302666cd44 100644 --- a/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java +++ b/refactoring/impl/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationHandler.java @@ -29,12 +29,14 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Collection; +import java.util.List; public class InheritanceToDelegationHandler implements RefactoringActionHandler { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.inheritanceToDelegation.InheritanceToDelegationHandler"); public static final String REFACTORING_NAME = RefactoringBundle.message("replace.inheritance.with.delegation.title"); - private static final MemberInfo.Filter MEMBER_INFO_FILTER = new MemberInfo.Filter() { + private static final MemberInfo.Filter MEMBER_INFO_FILTER = new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { if (element instanceof PsiMethod) { final PsiMethod method = (PsiMethod)element; @@ -95,7 +97,7 @@ public class InheritanceToDelegationHandler implements RefactoringActionHandler return; } - final HashMap basesToMemberInfos = new HashMap(); + final HashMap> basesToMemberInfos = new HashMap>(); for (PsiClass base : bases) { basesToMemberInfos.put(base, createBaseClassMemberInfos(base)); @@ -106,18 +108,18 @@ public class InheritanceToDelegationHandler implements RefactoringActionHandler bases, basesToMemberInfos).show(); } - private static MemberInfo[] createBaseClassMemberInfos(PsiClass baseClass) { + private static List createBaseClassMemberInfos(PsiClass baseClass) { final PsiClass deepestBase = RefactoringHierarchyUtil.getDeepestNonObjectBase(baseClass); LOG.assertTrue(deepestBase != null); final MemberInfoStorage memberInfoStorage = new MemberInfoStorage(baseClass, MEMBER_INFO_FILTER); ArrayList memberInfoList = new ArrayList(memberInfoStorage.getClassMemberInfos(deepestBase)); - MemberInfo[] memberInfos = memberInfoStorage.getMemberInfosList(deepestBase); + List memberInfos = memberInfoStorage.getMemberInfosList(deepestBase); for (final MemberInfo memberInfo : memberInfos) { memberInfoList.add(memberInfo); } - return memberInfoList.toArray(new MemberInfo[memberInfoList.size()]); + return memberInfoList; } } diff --git a/refactoring/impl/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java b/refactoring/impl/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java index b38ef024d6..5bd6787781 100644 --- a/refactoring/impl/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java +++ b/refactoring/impl/com/intellij/refactoring/inlineSuperClass/InlineSuperClassRefactoringProcessor.java @@ -44,7 +44,7 @@ public class InlineSuperClassRefactoringProcessor extends FixableUsagesRefactori super(project); mySuperClass = superClass; myTargetClasses = targetClasses; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySuperClass, new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { return true; } diff --git a/refactoring/impl/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java b/refactoring/impl/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java index bf5b4725d2..018fa8b47a 100644 --- a/refactoring/impl/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java +++ b/refactoring/impl/com/intellij/refactoring/memberPullUp/JavaPullUpHandler.java @@ -8,8 +8,8 @@ */ package com.intellij.refactoring.memberPullUp; -import com.intellij.history.LocalHistoryAction; import com.intellij.history.LocalHistory; +import com.intellij.history.LocalHistoryAction; import com.intellij.openapi.actionSystem.DataContext; import com.intellij.openapi.actionSystem.PlatformDataKeys; import com.intellij.openapi.application.ApplicationManager; @@ -22,6 +22,7 @@ import com.intellij.psi.*; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.lang.ElementsHandler; import com.intellij.refactoring.ui.ConflictsDialog; import com.intellij.refactoring.util.CommonRefactoringUtil; @@ -107,7 +108,7 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog mySubclass = aClass; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, new MemberInfo.Filter() { + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(mySubclass, new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { return true; } @@ -115,7 +116,7 @@ public class JavaPullUpHandler implements RefactoringActionHandler, PullUpDialog List members = memberInfoStorage.getClassMemberInfos(mySubclass); PsiManager manager = mySubclass.getManager(); - for (MemberInfo member : members) { + for (MemberInfoBase member : members) { if (manager.areElementsEquivalent(member.getMember(), aMember)) { member.setChecked(true); break; diff --git a/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpDialog.java b/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpDialog.java index 97ec60bbf1..11101dd92d 100644 --- a/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpDialog.java +++ b/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpDialog.java @@ -13,12 +13,16 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.psi.*; import com.intellij.refactoring.HelpID; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoChange; import com.intellij.refactoring.ui.ClassCellRenderer; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.util.RefactoringHierarchyUtil; -import com.intellij.refactoring.util.classMembers.*; +import com.intellij.refactoring.util.classMembers.InterfaceContainmentVerifier; +import com.intellij.refactoring.util.classMembers.MemberInfo; +import com.intellij.refactoring.util.classMembers.MemberInfoStorage; +import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.usageView.UsageViewUtil; import org.jetbrains.annotations.NotNull; @@ -37,7 +41,7 @@ public class PullUpDialog extends DialogWrapper { private final PsiClass myClass; private final List mySuperClasses; private final MemberInfoStorage myMemberInfoStorage; - private MemberInfo[] myMemberInfos; + private List myMemberInfos; private JavaDocPanel myJavaDocPanel; private JComboBox myClassCombo; @@ -53,7 +57,7 @@ public class PullUpDialog extends DialogWrapper { myClass = aClass; mySuperClasses = superClasses; myMemberInfoStorage = memberInfoStorage; - myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass).toArray(new MemberInfo[0]); + myMemberInfos = myMemberInfoStorage.getClassMemberInfos(aClass); myCallback = callback; setTitle(JavaPullUpHandler.REFACTORING_NAME); @@ -75,7 +79,7 @@ public class PullUpDialog extends DialogWrapper { } public MemberInfo[] getSelectedMemberInfos() { - ArrayList list = new ArrayList(myMemberInfos.length); + ArrayList list = new ArrayList(myMemberInfos.size()); for (MemberInfo info : myMemberInfos) { if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) { list.add(info); @@ -163,7 +167,7 @@ public class PullUpDialog extends DialogWrapper { JPanel panel = new JPanel(new BorderLayout()); myMemberSelectionPanel = new MemberSelectionPanel(RefactoringBundle.message("members.to.be.pulled.up"), myMemberInfos, RefactoringBundle.message("make.abstract")); myMemberInfoModel = new MyMemberInfoModel(); - myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); myMemberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel); myMemberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel); panel.add(myMemberSelectionPanel, BorderLayout.CENTER); diff --git a/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpHelper.java index 3060450d73..96c6263714 100644 --- a/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpHelper.java +++ b/refactoring/impl/com/intellij/refactoring/memberPullUp/PullUpHelper.java @@ -715,7 +715,7 @@ public class PullUpHelper { return false; } - public static boolean checkedInterfacesContain(MemberInfo[] memberInfos, PsiMethod psiMethod) { + public static boolean checkedInterfacesContain(Collection memberInfos, PsiMethod psiMethod) { for (MemberInfo memberInfo : memberInfos) { if (memberInfo.isChecked() && memberInfo.getMember() instanceof PsiClass && diff --git a/refactoring/impl/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java b/refactoring/impl/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java index ede736993e..30abf62cdb 100644 --- a/refactoring/impl/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java +++ b/refactoring/impl/com/intellij/refactoring/memberPushDown/JavaPushDownHandler.java @@ -9,6 +9,7 @@ import com.intellij.psi.impl.source.jsp.jspJava.JspClass; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactoringActionHandler; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.refactoring.lang.ElementsHandler; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.RefactoringMessageUtil; @@ -68,7 +69,7 @@ public class JavaPushDownHandler implements RefactoringActionHandler, ElementsHa return; if (!CommonRefactoringUtil.checkReadOnlyStatus(project, aClass)) return; - MemberInfoStorage memberInfoStorage = new MemberInfoStorage(aClass, new MemberInfo.Filter() { + MemberInfoStorage memberInfoStorage = new MemberInfoStorage(aClass, new MemberInfo.Filter() { public boolean includeMember(PsiMember element) { return true; } @@ -76,7 +77,7 @@ public class JavaPushDownHandler implements RefactoringActionHandler, ElementsHa List members = memberInfoStorage.getClassMemberInfos(aClass); PsiManager manager = aClass.getManager(); - for (MemberInfo member : members) { + for (MemberInfoBase member : members) { if (manager.areElementsEquivalent(member.getMember(), aMember)) { member.setChecked(true); break; diff --git a/refactoring/impl/com/intellij/refactoring/memberPushDown/PushDownDialog.java b/refactoring/impl/com/intellij/refactoring/memberPushDown/PushDownDialog.java index b52e37d60f..a4c44a7446 100644 --- a/refactoring/impl/com/intellij/refactoring/memberPushDown/PushDownDialog.java +++ b/refactoring/impl/com/intellij/refactoring/memberPushDown/PushDownDialog.java @@ -3,31 +3,34 @@ package com.intellij.refactoring.memberPushDown; import com.intellij.openapi.help.HelpManager; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; import com.intellij.refactoring.HelpID; -import com.intellij.refactoring.RefactoringBundle; import com.intellij.refactoring.JavaRefactoringSettings; +import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoChange; +import com.intellij.refactoring.classMembers.MemberInfoModel; +import com.intellij.refactoring.classMembers.UsedByDependencyMemberInfoModel; import com.intellij.refactoring.memberPullUp.JavaDocPanel; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.util.JavaDocPolicy; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; -import com.intellij.refactoring.util.classMembers.MemberInfoModel; -import com.intellij.refactoring.util.classMembers.UsedByDependencyMemberInfoModel; import javax.swing.*; import java.awt.*; import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; public class PushDownDialog extends RefactoringDialog { - private final MemberInfo[] myMemberInfos; + private final List myMemberInfos; private final PsiClass myClass; private JavaDocPanel myJavaDocPanel; - private MemberInfoModel myMemberInfoModel; + private MemberInfoModel myMemberInfoModel; public PushDownDialog(Project project, MemberInfo[] memberInfos, PsiClass aClass) { super(project, true); - myMemberInfos = memberInfos; + myMemberInfos = Arrays.asList(memberInfos); myClass = aClass; setTitle(JavaPushDownHandler.REFACTORING_NAME); @@ -40,7 +43,7 @@ public class PushDownDialog extends RefactoringDialog { } public MemberInfo[] getSelectedMemberInfos() { - ArrayList list = new ArrayList(myMemberInfos.length); + ArrayList list = new ArrayList(myMemberInfos.size()); for (MemberInfo info : myMemberInfos) { if (info.isChecked() && myMemberInfoModel.isMemberEnabled(info)) { list.add(info); @@ -83,7 +86,7 @@ public class PushDownDialog extends RefactoringDialog { panel.add(memberSelectionPanel, BorderLayout.CENTER); myMemberInfoModel = new MyMemberInfoModel(); - myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); memberSelectionPanel.getTable().setMemberInfoModel(myMemberInfoModel); memberSelectionPanel.getTable().addMemberInfoChangeListener(myMemberInfoModel); @@ -104,7 +107,7 @@ public class PushDownDialog extends RefactoringDialog { new JavaDocPolicy(getJavaDocPolicy()))); } - private class MyMemberInfoModel extends UsedByDependencyMemberInfoModel { + private class MyMemberInfoModel extends UsedByDependencyMemberInfoModel { public MyMemberInfoModel() { super(myClass); } diff --git a/refactoring/impl/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java b/refactoring/impl/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java index e7a2ffbc20..85b98a778f 100644 --- a/refactoring/impl/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java +++ b/refactoring/impl/com/intellij/refactoring/move/moveMembers/MoveMembersDialog.java @@ -17,20 +17,20 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.JavaRefactoringSettings; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoChange; import com.intellij.refactoring.move.MoveCallback; import com.intellij.refactoring.ui.MemberSelectionTable; import com.intellij.refactoring.ui.RefactoringDialog; import com.intellij.refactoring.ui.VisibilityPanel; import com.intellij.refactoring.util.CommonRefactoringUtil; import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; import com.intellij.refactoring.util.classMembers.UsesAndInterfacesDependencyMemberInfoModel; import com.intellij.ui.IdeBorderFactory; import com.intellij.ui.RecentsManager; import com.intellij.ui.ReferenceEditorComboWithBrowseButton; import com.intellij.ui.ScrollPaneFactory; -import com.intellij.util.IncorrectOperationException; import com.intellij.usageView.UsageViewUtil; +import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; import javax.swing.*; @@ -39,6 +39,8 @@ import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import java.util.Set; public class MoveMembersDialog extends RefactoringDialog implements MoveMembersOptions { @@ -48,7 +50,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO private final Project myProject; private final PsiClass mySourceClass; private final String mySourceClassName; - private final MemberInfo[] myMemberInfos; + private final List myMemberInfos; private final ReferenceEditorComboWithBrowseButton myTfTargetClassName; private MemberSelectionTable myTable; private final MoveCallback myMoveCallback; @@ -103,7 +105,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO memberList.add(info); } } - myMemberInfos = memberList.toArray(new MemberInfo[memberList.size()]); + myMemberInfos = memberList; String fqName = initialTargetClass != null && !sourceClass.equals(initialTargetClass) ? initialTargetClass.getQualifiedName() : ""; myTfTargetClassName = new ReferenceEditorComboWithBrowseButton(new ChooseClassAction(), fqName, PsiManager.getInstance(myProject), true, RECENTS_KEY); @@ -127,7 +129,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO myTable = new MemberSelectionTable(myMemberInfos, null); myTable.setMemberInfoModel(myMemberInfoModel); myTable.addMemberInfoChangeListener(myMemberInfoModel); - myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); + myMemberInfoModel.memberInfoChanged(new MemberInfoChange(myMemberInfos)); return myTable; } @@ -194,7 +196,7 @@ public class MoveMembersDialog extends RefactoringDialog implements MoveMembersO } public PsiMember[] getSelectedMembers() { - final MemberInfo[] selectedMemberInfos = myTable.getSelectedMemberInfos(); + final Collection selectedMemberInfos = myTable.getSelectedMemberInfos(); ArrayList list = new ArrayList(); for (MemberInfo selectedMemberInfo : selectedMemberInfos) { list.add(selectedMemberInfo.getMember()); diff --git a/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanDialog.java b/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanDialog.java index 8e128c791c..58ac93a2c4 100644 --- a/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanDialog.java +++ b/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanDialog.java @@ -8,22 +8,24 @@ import com.intellij.psi.PsiSubstitutor; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.refactoring.HelpID; import com.intellij.refactoring.RefactorJBundle; +import com.intellij.refactoring.classMembers.DelegatingMemberInfoModel; import com.intellij.refactoring.ui.MemberSelectionPanel; import com.intellij.refactoring.ui.MemberSelectionTable; import com.intellij.refactoring.ui.RefactoringDialog; -import com.intellij.refactoring.util.classMembers.DelegatingMemberInfoModel; import com.intellij.refactoring.util.classMembers.MemberInfo; import org.jetbrains.annotations.NotNull; import javax.swing.*; import java.awt.*; +import java.util.Arrays; +import java.util.List; @SuppressWarnings({"OverridableMethodCallInConstructor"}) public class RemoveMiddlemanDialog extends RefactoringDialog { private final JTextField fieldNameLabel; - private final MemberInfo[] delegateMethods; + private final List delegateMethods; private final PsiField myField; @@ -31,7 +33,7 @@ public class RemoveMiddlemanDialog extends RefactoringDialog { RemoveMiddlemanDialog(PsiField field, MemberInfo[] delegateMethods) { super(field.getProject(), true); myField = field; - this.delegateMethods = delegateMethods; + this.delegateMethods = Arrays.asList(delegateMethods); fieldNameLabel = new JTextField(); fieldNameLabel.setText( PsiFormatUtil.formatVariable(myField, PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.SHOW_NAME, PsiSubstitutor.EMPTY)); @@ -49,7 +51,7 @@ public class RemoveMiddlemanDialog extends RefactoringDialog { panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 5, 0)); final MemberSelectionPanel selectionPanel = new MemberSelectionPanel("Methods to inline", delegateMethods, "Delete"); final MemberSelectionTable table = selectionPanel.getTable(); - table.setMemberInfoModel(new DelegatingMemberInfoModel(table.getMemberInfoModel()) { + table.setMemberInfoModel(new DelegatingMemberInfoModel(table.getMemberInfoModel()) { @Override public int checkForProblems(@NotNull final MemberInfo member) { return hasSuperMethods(member) ? ERROR : OK; diff --git a/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java b/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java index 94abd3b1f4..b735180dbf 100644 --- a/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java +++ b/refactoring/impl/com/intellij/refactoring/removemiddleman/RemoveMiddlemanProcessor.java @@ -26,10 +26,10 @@ public class RemoveMiddlemanProcessor extends FixableUsagesRefactoringProcessor private final PsiField field; private final PsiClass containingClass; - private final MemberInfo[] myDelegateMethodInfos; + private final List myDelegateMethodInfos; private PsiMethod getter; - public RemoveMiddlemanProcessor(PsiField field, MemberInfo[] memberInfos) { + public RemoveMiddlemanProcessor(PsiField field, List memberInfos) { super(field.getProject()); this.field = field; containingClass = field.getContainingClass(); diff --git a/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionPanel.java b/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionPanel.java index ae1beba44a..57a898edb8 100644 --- a/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionPanel.java +++ b/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionPanel.java @@ -15,11 +15,12 @@ import com.intellij.ui.ScrollPaneFactory; import javax.swing.*; import javax.swing.border.Border; import java.awt.*; +import java.util.List; public class MemberSelectionPanel extends JPanel { private final MemberSelectionTable myTable; - public MemberSelectionPanel(String title, MemberInfo[] memberInfo, String abstractColumnHeader) { + public MemberSelectionPanel(String title, List memberInfo, String abstractColumnHeader) { super(); Border titledBorder = IdeBorderFactory.createTitledBorder(title); Border emptyBorder = BorderFactory.createEmptyBorder(0, 5, 5, 5); diff --git a/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionTable.java b/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionTable.java dissimilarity index 96% index 9d32eb9aad..5e5a914ab7 100644 --- a/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionTable.java +++ b/refactoring/impl/com/intellij/refactoring/ui/MemberSelectionTable.java @@ -1,429 +1,98 @@ -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 17.06.2002 - * Time: 16:35:43 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ -package com.intellij.refactoring.ui; - -import com.intellij.openapi.actionSystem.DataKey; -import com.intellij.openapi.actionSystem.DataSink; -import com.intellij.openapi.actionSystem.LangDataKeys; -import com.intellij.openapi.actionSystem.TypeSafeDataProvider; -import com.intellij.openapi.util.IconLoader; -import com.intellij.psi.*; -import com.intellij.refactoring.RefactoringBundle; -import com.intellij.refactoring.util.classMembers.MemberInfo; -import com.intellij.refactoring.util.classMembers.MemberInfoChange; -import com.intellij.refactoring.util.classMembers.MemberInfoChangeListener; -import com.intellij.refactoring.util.classMembers.MemberInfoModel; -import com.intellij.ui.BooleanTableCellRenderer; -import com.intellij.ui.ColoredTableCellRenderer; -import com.intellij.ui.RowIcon; -import com.intellij.ui.SimpleTextAttributes; -import com.intellij.util.IconUtil; -import com.intellij.util.VisibilityIcons; -import com.intellij.util.ui.EmptyIcon; -import com.intellij.util.ui.Table; -import org.jetbrains.annotations.NotNull; - -import javax.swing.*; -import javax.swing.table.AbstractTableModel; -import javax.swing.table.TableColumnModel; -import java.awt.*; -import java.util.ArrayList; - -public class MemberSelectionTable extends Table implements TypeSafeDataProvider { - private static final int CHECKED_COLUMN = 0; - private static final int DISPLAY_NAME_COLUMN = 1; - private static final int ABSTRACT_COLUMN = 2; - private static final Icon OVERRIDING_METHOD_ICON = IconLoader.getIcon("/general/overridingMethod.png"); - private static final Icon IMPLEMENTING_METHOD_ICON = IconLoader.getIcon("/general/implementingMethod.png"); - private static final Icon EMPTY_OVERRIDE_ICON = new EmptyIcon(16, 16); - - private final String myAbstractColumnHeader; - private static final String DISPLAY_NAME_COLUMN_HEADER = RefactoringBundle.message("member.column"); - - private MemberInfo[] myMemberInfos; - private final boolean myAbstractEnabled; - private MemberInfoModel myMemberInfoModel; - private MyTableModel myTableModel; - - private static class DefaultMemberInfoModel implements MemberInfoModel { - public boolean isMemberEnabled(MemberInfo member) { - return true; - } - - public boolean isCheckedWhenDisabled(MemberInfo member) { - return false; - } - - public boolean isAbstractEnabled(MemberInfo member) { - return true; - } - - public boolean isAbstractWhenDisabled(MemberInfo member) { - return false; - } - - - public int checkForProblems(@NotNull MemberInfo member) { - return OK; - } - - public void memberInfoChanged(MemberInfoChange event) { - } - - public Boolean isFixedAbstract(MemberInfo member) { - return null; - } - - public String getTooltipText(MemberInfo member) { - return null; - } - } - - private static final DefaultMemberInfoModel defaultMemberInfoModel = new DefaultMemberInfoModel(); - - public MemberSelectionTable(final MemberInfo[] memberInfos, String abstractColumnHeader) { - this(memberInfos, null, abstractColumnHeader); - } - - public MemberSelectionTable(final MemberInfo[] memberInfos, - MemberInfoModel memberInfoModel, - String abstractColumnHeader) { - super(); - myAbstractEnabled = abstractColumnHeader != null; - myAbstractColumnHeader = abstractColumnHeader; - myTableModel = new MyTableModel(); - - myMemberInfos = memberInfos; - if (memberInfoModel != null) { - myMemberInfoModel = memberInfoModel; - } - else { - myMemberInfoModel = defaultMemberInfoModel; - } - - setModel(myTableModel); - -// myTable.setTableHeader(null); -// this.setDefaultRenderer(Boolean.class, new MyBooleanRenderer()); - TableColumnModel model = getColumnModel(); - model.getColumn(DISPLAY_NAME_COLUMN).setCellRenderer(new MyTableRenderer()); - model.getColumn(CHECKED_COLUMN).setCellRenderer(new MyBooleanRenderer()); - final int checkBoxWidth = new JCheckBox().getPreferredSize().width; - model.getColumn(CHECKED_COLUMN).setMaxWidth(checkBoxWidth); - model.getColumn(CHECKED_COLUMN).setMinWidth(checkBoxWidth); - - if (myAbstractEnabled) { - int width = - (int)(1.3 * getFontMetrics(getFont()).charsWidth(myAbstractColumnHeader.toCharArray(), 0, - myAbstractColumnHeader.length())); - model.getColumn(ABSTRACT_COLUMN).setMaxWidth(width); - model.getColumn(ABSTRACT_COLUMN).setPreferredWidth(width); - model.getColumn(ABSTRACT_COLUMN).setCellRenderer(new MyBooleanRenderer()); - } - - setPreferredScrollableViewportSize(new Dimension(400, getRowHeight() * 12)); - getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - setShowGrid(false); - setIntercellSpacing(new Dimension(0, 0)); - - new MyEnableDisableAction().register(); - } - - public MemberInfo[] getSelectedMemberInfos() { - ArrayList list = new ArrayList(myMemberInfos.length); - for (MemberInfo info : myMemberInfos) { - if (isMemberInfoSelected(info)) { -// if (info.isChecked() || (!myMemberInfoModel.isMemberEnabled(info) && myMemberInfoModel.isCheckedWhenDisabled(info))) { - list.add(info); - } - } - return list.toArray(new MemberInfo[list.size()]); - } - - private boolean isMemberInfoSelected(final MemberInfo info) { - final boolean memberEnabled = myMemberInfoModel.isMemberEnabled(info); - return (memberEnabled && info.isChecked()) || (!memberEnabled && myMemberInfoModel.isCheckedWhenDisabled(info)); - } - - public MemberInfoModel getMemberInfoModel() { - return myMemberInfoModel; - } - - public void setMemberInfoModel(MemberInfoModel memberInfoModel) { - myMemberInfoModel = memberInfoModel; - } - - public void fireExternalDataChange() { - myTableModel.fireTableDataChanged(); - } - - public void setMemberInfos(MemberInfo[] memberInfos) { - myMemberInfos = memberInfos; - fireMemberInfoChange(memberInfos); - myTableModel.fireTableDataChanged(); - } - - public void addMemberInfoChangeListener(MemberInfoChangeListener l) { - listenerList.add(MemberInfoChangeListener.class, l); - } - - protected void fireMemberInfoChange(MemberInfo[] changedMembers) { - Object[] list = listenerList.getListenerList(); - - MemberInfoChange event = new MemberInfoChange(changedMembers); - for (Object element : list) { - if (element instanceof MemberInfoChangeListener) { - ((MemberInfoChangeListener)element).memberInfoChanged(event); - } - } - } - - public void calcData(final DataKey key, final DataSink sink) { - if (key == LangDataKeys.PSI_ELEMENT) { - final MemberInfo[] memberInfos = getSelectedMemberInfos(); - if (memberInfos.length > 0) { - sink.put(LangDataKeys.PSI_ELEMENT, memberInfos [0].getMember()); - } - } - } - - public void scrollSelectionInView() { - for(int i=0; i { + + public MemberSelectionTable(final List memberInfos, String abstractColumnHeader) { + this(memberInfos, null, abstractColumnHeader); + } + + public MemberSelectionTable(final List memberInfos, MemberInfoModel memberInfoModel, String abstractColumnHeader) { + super(memberInfos, memberInfoModel, abstractColumnHeader); + } + + @Override + protected Object getAbstractColumnValue(MemberInfo memberInfo) { + if (!(memberInfo.getMember() instanceof PsiMethod)) return null; + if (memberInfo.isStatic()) return null; + + PsiMethod method = (PsiMethod)memberInfo.getMember(); + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + final Boolean fixedAbstract = myMemberInfoModel.isFixedAbstract(memberInfo); + if (fixedAbstract != null) return fixedAbstract; + } + + if (!myMemberInfoModel.isAbstractEnabled(memberInfo)) { + return myMemberInfoModel.isAbstractWhenDisabled(memberInfo); + } + else { + return memberInfo.isToAbstract() ? Boolean.TRUE : Boolean.FALSE; + } + } + + @Override + protected boolean isAbstractColumnEditable(int rowIndex) { + MemberInfo info = myMemberInfos.get(rowIndex); + if (!(info.getMember() instanceof PsiMethod)) return false; + + PsiMethod method = (PsiMethod)info.getMember(); + if (method.hasModifierProperty(PsiModifier.ABSTRACT)) { + if (myMemberInfoModel.isFixedAbstract(info) != null) { + return false; + } + } + + return info.isChecked() && myMemberInfoModel.isAbstractEnabled(info); + } + + + @Override + protected void setVisibilityIcon(MemberInfo memberInfo, RowIcon icon) { + PsiMember member = memberInfo.getMember(); + PsiModifierList modifiers = member != null ? member.getModifierList() : null; + if (modifiers != null) { + VisibilityIcons.setVisibilityIcon(modifiers, icon); + } + else { + icon.setIcon(IconUtil.getEmptyIcon(true), VISIBILITY_ICON_POSITION); + } + } + + @Override + protected Icon getOverrideIcon(MemberInfo memberInfo) { + PsiMember member = memberInfo.getMember(); + Icon overrideIcon = MemberSelectionTable.EMPTY_OVERRIDE_ICON; + if (member instanceof PsiMethod) { + if (Boolean.TRUE.equals(memberInfo.getOverrides())) { + overrideIcon = MemberSelectionTable.OVERRIDING_METHOD_ICON; + } + else if (Boolean.FALSE.equals(memberInfo.getOverrides())) { + overrideIcon = MemberSelectionTable.IMPLEMENTING_METHOD_ICON; + } + else { + overrideIcon = MemberSelectionTable.EMPTY_OVERRIDE_ICON; + } + } + return overrideIcon; + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java index 25bb83da59..a17e3d7540 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/ClassMembersUtil.java @@ -1,15 +1,19 @@ package com.intellij.refactoring.util.classMembers; -import com.intellij.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiField; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.classMembers.MemberInfoBase; public class ClassMembersUtil { - public static boolean isProperMember(MemberInfo memberInfo) { + public static boolean isProperMember(MemberInfoBase memberInfo) { final PsiElement member = memberInfo.getMember(); return member instanceof PsiField || member instanceof PsiMethod || (member instanceof PsiClass && memberInfo.getOverrides() == null); } - public static boolean isImplementedInterface(MemberInfo memberInfo) { + public static boolean isImplementedInterface(MemberInfoBase memberInfo) { return memberInfo.getMember() instanceof PsiClass && Boolean.FALSE.equals(memberInfo.getOverrides()); } } diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java deleted file mode 100644 index c93d5817d5..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/DependencyMemberInfoModel.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 09.07.2002 - * Time: 15:03:42 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.psi.*; -import org.jetbrains.annotations.NotNull; - -public abstract class DependencyMemberInfoModel implements MemberInfoModel { - protected MemberDependencyGraph myMemberDependencyGraph; - private final int myProblemLevel; - private MemberInfoTooltipManager myTooltipManager; - - public DependencyMemberInfoModel(MemberDependencyGraph memberDependencyGraph, int problemLevel) { - myMemberDependencyGraph = memberDependencyGraph; - myProblemLevel = problemLevel; - } - - public void setTooltipProvider(MemberInfoTooltipManager.TooltipProvider tooltipProvider) { - myTooltipManager = new MemberInfoTooltipManager(tooltipProvider); - } - - public boolean isAbstractEnabled(MemberInfo member) { - return true; - } - - public boolean isAbstractWhenDisabled(MemberInfo member) { - return false; - } - - public boolean isMemberEnabled(MemberInfo member) { - return true; - } - - public int checkForProblems(@NotNull MemberInfo memberInfo) { - if (memberInfo.isChecked()) return OK; - final PsiElement member = memberInfo.getMember(); - - if (myMemberDependencyGraph.getDependent().contains(member)) { - return myProblemLevel; - } - return OK; - } - - public void setMemberDependencyGraph(MemberDependencyGraph memberDependencyGraph) { - myMemberDependencyGraph = memberDependencyGraph; - } - - public void memberInfoChanged(MemberInfoChange event) { - memberInfoChanged(event.getChangedMembers()); - } - - public void memberInfoChanged(final MemberInfo[] changedMembers) { - if (myTooltipManager != null) myTooltipManager.invalidate(); - for (int i = 0; i < changedMembers.length; i++) { - myMemberDependencyGraph.memberChanged(changedMembers[i]); - } - } - - public String getTooltipText(MemberInfo member) { - if (myTooltipManager != null) { - return myTooltipManager.getTooltip(member); - } else { - return null; - } - } -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/DependentMembersCollector.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/DependentMembersCollector.java new file mode 100644 index 0000000000..0b5367707b --- /dev/null +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/DependentMembersCollector.java @@ -0,0 +1,35 @@ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.refactoring.classMembers.DependentMembersCollectorBase; + +/** +* @author max +*/ +public class DependentMembersCollector extends DependentMembersCollectorBase { + public DependentMembersCollector(PsiClass clazz, PsiClass superClass) { + super(clazz, superClass); + } + + public void collect(PsiMember member) { + member.accept(getVisitor()); + } + + private PsiElementVisitor getVisitor() { + return new ClassMemberReferencesVisitor(getClazz()) { + protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { + if (!existsInSuperClass(classMember)) { + myCollection.add(classMember); + } + } + }; + } + + private boolean existsInSuperClass(PsiMember classMember) { + if (getSuperClass() == null) return false; + if (!(classMember instanceof PsiMethod)) return false; + final PsiMethod method = ((PsiMethod)classMember); + final PsiMethod methodBySignature = (getSuperClass()).findMethodBySignature(method, true); + return methodBySignature != null; + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java index 026ef87353..76bc87caa1 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceDependencyMemberInfoModel.java @@ -8,13 +8,16 @@ */ package com.intellij.refactoring.util.classMembers; -import com.intellij.psi.*; +import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMember; +import com.intellij.refactoring.classMembers.DependencyMemberInfoModel; +import com.intellij.refactoring.classMembers.MemberInfoTooltipManager; -public class InterfaceDependencyMemberInfoModel extends DependencyMemberInfoModel { +public class InterfaceDependencyMemberInfoModel extends DependencyMemberInfoModel { public InterfaceDependencyMemberInfoModel(PsiClass aClass) { super(new InterfaceMemberDependencyGraph(aClass), WARNING); - setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { + setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { public String getTooltip(MemberInfo memberInfo) { return ((InterfaceMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); } diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java index 47b9d01d2c..8402094780 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/InterfaceMemberDependencyGraph.java @@ -2,13 +2,14 @@ package com.intellij.refactoring.util.classMembers; import com.intellij.psi.*; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberDependencyGraph; import com.intellij.util.containers.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Set; -public class InterfaceMemberDependencyGraph implements MemberDependencyGraph { +public class InterfaceMemberDependencyGraph implements MemberDependencyGraph { protected HashSet myInterfaceDependencies = null; protected HashMap> myMembersToInterfacesMap = new HashMap>(); protected HashSet myImplementedInterfaces; diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java deleted file mode 100644 index 6eb4f67489..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberDependenciesStorage.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.psi.*; -import com.intellij.util.containers.HashMap; - -import java.util.HashSet; - - -class MemberDependenciesStorage { - protected final PsiClass myClass; - private final PsiClass mySuperClass; - private final HashMap> myDependencyGraph; - - MemberDependenciesStorage(PsiClass aClass, PsiClass superClass) { - myClass = aClass; - mySuperClass = superClass; - myDependencyGraph = new HashMap>(); - } - - protected HashSet getMemberDependencies(PsiMember member) { - HashSet result = myDependencyGraph.get(member); - if (result == null) { - DependentMembersCollector collector = new DependentMembersCollector(); - member.accept(collector); - result = collector.getCollection(); - myDependencyGraph.put(member, result); - } - return result; - } - - class DependentMembersCollector extends ClassMemberReferencesVisitor { - private final HashSet myCollection = new HashSet(); - - DependentMembersCollector() { - super(myClass); - } - - public HashSet getCollection() { - return myCollection; - } - - protected void visitClassMemberReferenceElement(PsiMember classMember, PsiJavaCodeReferenceElement classMemberReference) { - if (!existsInSuperClass(classMember)) { - myCollection.add(classMember); - } - } - } - - private boolean existsInSuperClass(PsiMember classMember) { - if(mySuperClass == null) return false; - if (!(classMember instanceof PsiMethod)) return false; - final PsiMethod method = ((PsiMethod) classMember); - final PsiMethod methodBySignature = mySuperClass.findMethodBySignature(method, true); - return methodBySignature != null; - } -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfo.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfo.java index 6e091fb78d..03087428be 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfo.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfo.java @@ -8,70 +8,25 @@ */ package com.intellij.refactoring.util.classMembers; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; import com.intellij.refactoring.RefactoringBundle; +import com.intellij.refactoring.classMembers.MemberInfoBase; import com.intellij.util.containers.HashSet; import java.util.ArrayList; import java.util.List; import java.util.Set; -public class MemberInfo { - private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.extractSuperclass.MemberInfo"); - private PsiMember myMember; - final private boolean isStatic; - final private String displayName; - private boolean isChecked = false; - private boolean toAbstract = false; - /** - * TRUE if is overriden, FALSE if implemented, null if not implemented or overriden - */ - final private Boolean overrides; +public class MemberInfo extends MemberInfoBase { private final PsiReferenceList mySourceReferenceList; - public boolean isStatic() { - return isStatic; - } - - public String getDisplayName() { - return displayName; - } - - public boolean isChecked() { - return isChecked; - } - - public void setChecked(boolean checked) { - isChecked = checked; - } - - public boolean isToAbstract() { - return toAbstract; - } - - public void setToAbstract(boolean toAbstract) { - this.toAbstract = toAbstract; - } - - /** - * Returns Boolean.TRUE if getMember() overrides something, Boolean.FALSE if getMember() - * implements something, null if neither is the case. - * If getMember() is a PsiClass, returns Boolean.TRUE if this class comes - * from 'extends', Boolean.FALSE if it comes from 'implements' list, null - * if it is an inner class. - */ - public Boolean getOverrides() { - return overrides; - } - public MemberInfo(PsiMember member) { this(member, false, null); } public MemberInfo(PsiMember member, boolean isSuperClass, PsiReferenceList sourceReferenceList) { + super(member); LOG.assertTrue(member.isValid()); - myMember = member; mySourceReferenceList = sourceReferenceList; if (member instanceof PsiMethod) { PsiMethod method = (PsiMethod) member; @@ -124,34 +79,17 @@ public class MemberInfo { } } - public PsiMember getMember() { - LOG.assertTrue(myMember.isValid()); - return myMember; - } - - /** - * Use this method solely to update element from smart pointer and the likes - * @param element - */ - public void updateMember(PsiMember element) { - myMember = element; - } - public PsiReferenceList getSourceReferenceList() { return mySourceReferenceList; } - public static interface Filter { - boolean includeMember(PsiMember member); - } - - public static MemberInfo[] extractClassMembers(PsiClass subclass, Filter filter, boolean extractInterfacesDeep) { + public static List extractClassMembers(PsiClass subclass, Filter filter, boolean extractInterfacesDeep) { List members = new ArrayList(); extractClassMembers(subclass, members, filter, extractInterfacesDeep); - return members.toArray(new MemberInfo[members.size()]); + return members; } - public static void extractClassMembers(PsiClass subclass, List result, Filter filter, final boolean extractInterfacesDeep) { + public static void extractClassMembers(PsiClass subclass, List result, Filter filter, final boolean extractInterfacesDeep) { if (extractInterfacesDeep) { extractSuperInterfaces(subclass, filter, result, new HashSet()); } @@ -186,7 +124,7 @@ public class MemberInfo { } private static void extractSuperInterfaces(final PsiClass subclass, - final Filter filter, + final Filter filter, final List result, Set processed) { if (!processed.contains(subclass)) { @@ -197,7 +135,7 @@ public class MemberInfo { } private static void extractSuperInterfacesFromReferenceList(final PsiReferenceList referenceList, - final Filter filter, + final Filter filter, final List result, final Set processed) { if (referenceList != null) { diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChange.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChange.java deleted file mode 100644 index 0a5089d316..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChange.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 09.07.2002 - * Time: 15:41:29 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.refactoring.util.classMembers.MemberInfo; - -public class MemberInfoChange { - private final MemberInfo[] myChangedMembers; - - public MemberInfoChange(MemberInfo[] changedMembers) { - myChangedMembers = changedMembers; - } - - public MemberInfo[] getChangedMembers() { - return myChangedMembers; - } -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java deleted file mode 100644 index ea15f17d42..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoChangeListener.java +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 09.07.2002 - * Time: 15:41:09 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ -package com.intellij.refactoring.util.classMembers; - -import java.util.EventListener; - -public interface MemberInfoChangeListener extends EventListener { - void memberInfoChanged(MemberInfoChange event); -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java dissimilarity index 78% index cf1a90b7d0..b53f2e6d0b 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoStorage.java @@ -1,164 +1,62 @@ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.psi.*; -import com.intellij.psi.util.MethodSignatureUtil; -import com.intellij.util.containers.HashMap; - -import java.util.*; - - -public class MemberInfoStorage { - private final PsiClass myClass; - private final HashMap> myClassToMemberInfoMap = new HashMap>(); - private final HashMap> myClassToSubclassesMap = new HashMap>(); - private final HashMap> myTargetClassToExtendingMap = new HashMap>(); - private final HashMap myTargetClassToMemberInfosMap = new HashMap(); - private final HashMap> myTargetClassToMemberInfosListMap = new HashMap>(); - private final HashMap> myTargetClassToDuplicatedMemberInfosMap = new HashMap>(); - private final MemberInfo.Filter myFilter; - - public MemberInfoStorage(PsiClass aClass, MemberInfo.Filter memberInfoFilter) { - myClass = aClass; - buildSubClassesMap(aClass); - myFilter = memberInfoFilter; - } - - private Set getAllClasses() { - return myClassToSubclassesMap.keySet(); - } - - public Set getExtending(PsiClass baseClass) { - Set result = myTargetClassToExtendingMap.get(baseClass); - if(result == null) { - result = new HashSet(); - result.add(baseClass); - final Set allClasses = getAllClasses(); - for (Iterator iterator = allClasses.iterator(); iterator.hasNext();) { - PsiClass aClass = iterator.next(); - if(aClass.isInheritor(baseClass, true)) { - result.add(aClass); - } - } - myTargetClassToExtendingMap.put(baseClass, result); - } - - return result; - } - - public List getClassMemberInfos(PsiClass aClass) { - List result = myClassToMemberInfoMap.get(aClass); - if(result == null) { - ArrayList temp = new ArrayList(); - MemberInfo.extractClassMembers(aClass, temp, myFilter, false); - result = Collections.unmodifiableList(temp); - myClassToMemberInfoMap.put(aClass, result); - } - return result; - } - - public MemberInfo[] getMemberInfosList(PsiClass baseClass) { - MemberInfo[] result = myTargetClassToMemberInfosMap.get(baseClass); - - if (result == null) { - Set list = getIntermediateClassesMemberInfosList(baseClass); - result = list.toArray(new MemberInfo[list.size()]); - myTargetClassToMemberInfosMap.put(baseClass, result); - } - - return result; - } - - public Set getDuplicatedMemberInfos(PsiClass baseClass) { - HashSet result = myTargetClassToDuplicatedMemberInfosMap.get(baseClass); - - if(result == null) { - result = buildDuplicatedMemberInfos(baseClass); - myTargetClassToDuplicatedMemberInfosMap.put(baseClass, result); - } - return result; - } - - private HashSet buildDuplicatedMemberInfos(PsiClass baseClass) { - HashSet result = new HashSet(); - MemberInfo[] memberInfos = getMemberInfosList(baseClass); - - for (int i = 0; i < memberInfos.length; i++) { - final MemberInfo memberInfo = memberInfos[i]; - final PsiElement member = memberInfo.getMember(); - - for(int j = 0; j < i; j++) { - final MemberInfo memberInfo1 = memberInfos[j]; - final PsiElement member1 = memberInfo1.getMember(); - if(memberConflict(member1, member)) { - result.add(memberInfo); -// We let the first one be... -// result.add(memberInfo1); - } - } - } - return result; - } - - private boolean memberConflict(PsiElement member1, PsiElement member) { - if(member instanceof PsiMethod && member1 instanceof PsiMethod) { - return MethodSignatureUtil.areSignaturesEqual((PsiMethod) member, (PsiMethod) member1); - } - else if(member instanceof PsiField && member1 instanceof PsiField - || member instanceof PsiClass && member1 instanceof PsiClass) { - return ((PsiNamedElement) member).getName().equals(((PsiNamedElement) member1).getName()); - } - return false; - } - - - private Set getIntermediateClassesMemberInfosList(PsiClass targetClass) { - LinkedHashSet result = myTargetClassToMemberInfosListMap.get(targetClass); - if(result == null) { - result = new LinkedHashSet(); - Set subclasses = getSubclasses(targetClass); - for (Iterator iterator = subclasses.iterator(); iterator.hasNext();) { - PsiClass subclass = iterator.next(); - List memberInfos = getClassMemberInfos(subclass); - result.addAll(memberInfos); - } - for (Iterator iterator = subclasses.iterator(); iterator.hasNext();) { - PsiClass subclass = iterator.next(); - result.addAll(getIntermediateClassesMemberInfosList(subclass)); - } - myTargetClassToMemberInfosListMap.put(targetClass, result); - } - return result; - } - - private LinkedHashSet getSubclasses(PsiClass aClass) { - LinkedHashSet result = myClassToSubclassesMap.get(aClass); - if(result == null) { - result = new LinkedHashSet(); - myClassToSubclassesMap.put(aClass, result); - } - return result; - } - - private void buildSubClassesMap(PsiClass aClass) { - final PsiReferenceList extendsList = aClass.getExtendsList(); - if (extendsList != null) { - buildSubClassesMapForList(extendsList.getReferencedTypes(), aClass); - } - final PsiReferenceList implementsList = aClass.getImplementsList(); - if (implementsList != null) { - buildSubClassesMapForList(implementsList.getReferencedTypes(), aClass); - } - } - - private void buildSubClassesMapForList(final PsiClassType[] classesList, PsiClass aClass) { - for (int i = 0; i < classesList.length; i++) { - PsiClassType element = classesList[i]; - PsiClass resolved = element.resolve(); - if(resolved != null) { - PsiClass superClass = resolved; - getSubclasses(superClass).add(aClass); - buildSubClassesMap(superClass); - } - } - } -} +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.*; +import com.intellij.psi.util.MethodSignatureUtil; +import com.intellij.refactoring.classMembers.AbstractMemberInfoStorage; + +import java.util.ArrayList; + + +public class MemberInfoStorage extends AbstractMemberInfoStorage { + + public MemberInfoStorage(PsiClass aClass, MemberInfo.Filter memberInfoFilter) { + super(aClass, memberInfoFilter); + } + + @Override + protected boolean isInheritor(PsiClass baseClass, PsiClass aClass) { + return aClass.isInheritor(baseClass, true); + } + + @Override + protected void extractClassMembers(PsiClass aClass, ArrayList temp) { + MemberInfo.extractClassMembers(aClass, temp, myFilter, false); + } + + @Override + protected boolean memberConflict(PsiElement member1, PsiElement member) { + if(member instanceof PsiMethod && member1 instanceof PsiMethod) { + return MethodSignatureUtil.areSignaturesEqual((PsiMethod) member, (PsiMethod) member1); + } + else if(member instanceof PsiField && member1 instanceof PsiField + || member instanceof PsiClass && member1 instanceof PsiClass) { + return ((PsiNamedElement) member).getName().equals(((PsiNamedElement) member1).getName()); + } + return false; + } + + + @Override + protected void buildSubClassesMap(PsiClass aClass) { + final PsiReferenceList extendsList = aClass.getExtendsList(); + if (extendsList != null) { + buildSubClassesMapForList(extendsList.getReferencedTypes(), aClass); + } + final PsiReferenceList implementsList = aClass.getImplementsList(); + if (implementsList != null) { + buildSubClassesMapForList(implementsList.getReferencedTypes(), aClass); + } + } + + private void buildSubClassesMapForList(final PsiClassType[] classesList, PsiClass aClass) { + for (int i = 0; i < classesList.length; i++) { + PsiClassType element = classesList[i]; + PsiClass resolved = element.resolve(); + if(resolved != null) { + PsiClass superClass = resolved; + getSubclasses(superClass).add(aClass); + buildSubClassesMap(superClass); + } + } + } +} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java deleted file mode 100644 index a6d5286c9f..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/MemberInfoTooltipManager.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.intellij.refactoring.util.classMembers; - - - -import com.intellij.util.containers.HashMap; - - - -/** - - * @author dsl - - */ - -public class MemberInfoTooltipManager { - - private final HashMap myTooltips = new HashMap(); - - private final TooltipProvider myProvider; - - - - public interface TooltipProvider { - - String getTooltip(MemberInfo memberInfo); - - } - - - - public MemberInfoTooltipManager(TooltipProvider provider) { - - myProvider = provider; - - } - - - - public void invalidate() { - - myTooltips.clear(); - - } - - - - public String getTooltip(MemberInfo member) { - - if(myTooltips.keySet().contains(member)) { - - return myTooltips.get(member); - - } - - String tooltip = myProvider.getTooltip(member); - - myTooltips.put(member, tooltip); - - return tooltip; - - } - -} - diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java deleted file mode 100644 index c837448a8f..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByDependencyMemberInfoModel.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.psi.*; - -/** - * @author dsl - */ -public class UsedByDependencyMemberInfoModel extends DependencyMemberInfoModel { - - public UsedByDependencyMemberInfoModel(PsiClass aClass) { - super(new UsedByMemberDependencyGraph(aClass), ERROR); - setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { - public String getTooltip(MemberInfo memberInfo) { - return ((UsedByMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); - } - }); - } - - public boolean isCheckedWhenDisabled(MemberInfo member) { - return false; - } - - public Boolean isFixedAbstract(MemberInfo member) { - return null; - } -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java deleted file mode 100644 index a421c968c6..0000000000 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsedByMemberDependencyGraph.java +++ /dev/null @@ -1,96 +0,0 @@ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMember; -import com.intellij.psi.PsiNamedElement; -import com.intellij.refactoring.RefactoringBundle; -import com.intellij.util.containers.HashMap; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - -public class UsedByMemberDependencyGraph implements MemberDependencyGraph { - protected HashSet mySelectedNormal; - protected HashSet mySelectedAbstract; - protected HashSet myMembers; - protected HashSet myDependencies = null; - protected HashMap> myDependenciesToDependent = null; - private final MemberDependenciesStorage myMemberDependenciesStorage; - - UsedByMemberDependencyGraph(PsiClass aClass) { - myMemberDependenciesStorage = new MemberDependenciesStorage(aClass, null); - mySelectedNormal = new HashSet(); - mySelectedAbstract = new HashSet(); - myMembers = new HashSet(); - } - - public void memberChanged(MemberInfo memberInfo) { - if(ClassMembersUtil.isProperMember(memberInfo)) - { - myDependencies = null; - myDependenciesToDependent = null; - PsiMember member = memberInfo.getMember(); - myMembers.add(member); - if (!memberInfo.isChecked()) { - mySelectedNormal.remove(member); - mySelectedAbstract.remove(member); - } - else { - if (memberInfo.isToAbstract()) { - mySelectedNormal.remove(member); - mySelectedAbstract.add(member); - } - else { - mySelectedNormal.add(member); - mySelectedAbstract.remove(member); - } - } - } - } - - public Set getDependent() { - if(myDependencies == null) { - myDependencies = new HashSet(); - myDependenciesToDependent = new HashMap>(); - for (PsiMember member : myMembers) { - Set dependent = myMemberDependenciesStorage.getMemberDependencies(member); - for (final PsiMember aDependent : dependent) { - if (mySelectedNormal.contains(aDependent) && !mySelectedAbstract.contains(aDependent)) { - myDependencies.add(member); - HashSet deps = myDependenciesToDependent.get(member); - if (deps == null) { - deps = new HashSet(); - myDependenciesToDependent.put(member, deps); - } - deps.add(aDependent); - } - } - } - } - - return myDependencies; - } - - public Set getDependenciesOf(PsiMember member) { - final Set dependent = getDependent(); - if(!dependent.contains(member)) return null; - return myDependenciesToDependent.get(member); - } - - public String getElementTooltip(PsiMember element) { - final Set dependencies = getDependenciesOf(element); - if (dependencies == null || dependencies.size() == 0) return null; - - ArrayList strings = new ArrayList(); - for (PsiMember dep : dependencies) { - if (dep instanceof PsiNamedElement) { - strings.add(dep.getName()); - } - } - - if (strings.isEmpty()) return null; - return RefactoringBundle.message("uses.0", StringUtil.join(strings, ", ")); - } -} diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java index 15f5b9462f..ccd96e9dba 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesAndInterfacesDependencyMemberInfoModel.java @@ -9,11 +9,13 @@ package com.intellij.refactoring.util.classMembers; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiMember; +import com.intellij.psi.PsiMethod; +import com.intellij.refactoring.classMembers.ANDCombinedMemberInfoModel; +import com.intellij.refactoring.classMembers.DelegatingMemberInfoModel; import org.jetbrains.annotations.NotNull; -public class UsesAndInterfacesDependencyMemberInfoModel extends DelegatingMemberInfoModel { +public class UsesAndInterfacesDependencyMemberInfoModel extends DelegatingMemberInfoModel { public static final InterfaceContainmentVerifier DEFAULT_CONTAINMENT_VERIFIER = new InterfaceContainmentVerifier() { public boolean checkedInterfacesContain(PsiMethod psiMethod) { return false; @@ -22,8 +24,8 @@ public class UsesAndInterfacesDependencyMemberInfoModel extends DelegatingMember public UsesAndInterfacesDependencyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive, @NotNull final InterfaceContainmentVerifier interfaceContainmentVerifier) { - super(new ANDCombinedMemberInfoModel( - new UsesDependencyMemberInfoModel(aClass, superClass, recursive) { + super(new ANDCombinedMemberInfoModel( + new UsesDependencyMemberInfoModel(aClass, superClass, recursive) { public int checkForProblems(@NotNull MemberInfo memberInfo) { final int problem = super.checkForProblems(memberInfo); if (problem == OK) return OK; diff --git a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java dissimilarity index 64% index 300fe3b558..fe6a978076 100644 --- a/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java +++ b/refactoring/impl/com/intellij/refactoring/util/classMembers/UsesDependencyMemberInfoModel.java @@ -1,49 +1,37 @@ -/* - * Created by IntelliJ IDEA. - * User: dsl - * Date: 08.07.2002 - * Time: 17:55:02 - * To change template for new class use - * Code Style | Class Templates options (Tools | IDE Options). - */ -package com.intellij.refactoring.util.classMembers; - -import com.intellij.psi.*; -import org.jetbrains.annotations.NotNull; - -public class UsesDependencyMemberInfoModel extends DependencyMemberInfoModel { - private final PsiClass myClass; - - public UsesDependencyMemberInfoModel(PsiClass aClass, PsiClass superClass, boolean recursive) { - super(new UsesMemberDependencyGraph(aClass, superClass, recursive), ERROR); - setTooltipProvider(new MemberInfoTooltipManager.TooltipProvider() { - public String getTooltip(MemberInfo memberInfo) { - return ((UsesMemberDependencyGraph) myMemberDependencyGraph).getElementTooltip(memberInfo.getMember()); - } - }); - myClass = aClass; - } - - public int checkForProblems(@NotNull MemberInfo memberInfo) { - final int problem = super.checkForProblems(memberInfo); - final PsiElement member = memberInfo.getMember(); - if(problem == ERROR - && member instanceof PsiModifierListOwner - && ((PsiModifierListOwner) member).hasModifierProperty(PsiModifier.STATIC)) { - return WARNING; - } - return problem; - } - - public void setSuperClass(PsiClass superClass) { - setMemberDependencyGraph(new UsesMemberDependencyGraph(myClass, superClass, false)); - } - - public boolean isCheckedWhenDisabled(MemberInfo member) { - return false; - } - - public Boolean isFixedAbstract(MemberInfo member) { - return null; - } -} +/* + * Created by IntelliJ IDEA. + * User: dsl + * Date: 08.07.2002 + * Time: 17:55:02 + * To change template for new class use + * Code Style | Class Templates options (Tools | IDE Options). + */ +package com.intellij.refactoring.util.classMembers; + +import com.intellij.psi.NavigatablePsiElement; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiModifier; +import com.intellij.psi.PsiModifierListOwner; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.classMembers.AbstractUsesDependencyMemberInfoModel; +import org.jetbrains.annotations.NotNull; + +public class UsesDependencyMemberInfoModel> + extends AbstractUsesDependencyMemberInfoModel { + + public UsesDependencyMemberInfoModel(C aClass, C superClass, boolean recursive) { + super(aClass, superClass, recursive); + } + + @Override + protected int doCheck(@NotNull M memberInfo, int problem) { + final PsiElement member = memberInfo.getMember(); + if(problem == ERROR + && member instanceof PsiModifierListOwner + && ((PsiModifierListOwner) member).hasModifierProperty(PsiModifier.STATIC)) { + return WARNING; + } + return problem; + } + +} diff --git a/refactoring/tests/com/intellij/refactoring/RemoveMiddleManTest.java b/refactoring/tests/com/intellij/refactoring/RemoveMiddleManTest.java index 4cf1b66b4e..5c85cb235c 100644 --- a/refactoring/tests/com/intellij/refactoring/RemoveMiddleManTest.java +++ b/refactoring/tests/com/intellij/refactoring/RemoveMiddleManTest.java @@ -44,7 +44,7 @@ public class RemoveMiddleManTest extends MultiFileTestCase{ info.setToAbstract(delete); infos.add(info); } - RemoveMiddlemanProcessor processor = new RemoveMiddlemanProcessor(field, infos.toArray(new MemberInfo[infos.size()])); + RemoveMiddlemanProcessor processor = new RemoveMiddlemanProcessor(field, infos); processor.run(); LocalFileSystem.getInstance().refresh(false); FileDocumentManager.getInstance().saveAllDocuments(); diff --git a/source/com/intellij/lang/java/JavaClassMembersRefactoringSupport.java b/source/com/intellij/lang/java/JavaClassMembersRefactoringSupport.java new file mode 100644 index 0000000000..c910bd0663 --- /dev/null +++ b/source/com/intellij/lang/java/JavaClassMembersRefactoringSupport.java @@ -0,0 +1,21 @@ +package com.intellij.lang.java; + +import com.intellij.psi.PsiClass; +import com.intellij.refactoring.classMembers.ClassMembersRefactoringSupport; +import com.intellij.refactoring.classMembers.DependentMembersCollectorBase; +import com.intellij.refactoring.classMembers.MemberInfoBase; +import com.intellij.refactoring.util.classMembers.ClassMembersUtil; +import com.intellij.refactoring.util.classMembers.DependentMembersCollector; + +/** + * @author Dennis.Ushakov + */ +public class JavaClassMembersRefactoringSupport implements ClassMembersRefactoringSupport { + public DependentMembersCollectorBase createDependentMembersCollector(Object clazz, Object superClass) { + return new DependentMembersCollector((PsiClass)clazz, (PsiClass)superClass); + } + + public boolean isProperMember(MemberInfoBase member) { + return ClassMembersUtil.isProperMember(member); + } +} diff --git a/source/com/intellij/testIntegration/TestIntegrationUtils.java b/source/com/intellij/testIntegration/TestIntegrationUtils.java index e8e68c0d5c..65381d1473 100644 --- a/source/com/intellij/testIntegration/TestIntegrationUtils.java +++ b/source/com/intellij/testIntegration/TestIntegrationUtils.java @@ -68,7 +68,7 @@ public class TestIntegrationUtils { List result = new ArrayList(); do { - MemberInfo.extractClassMembers(clazz, result, new MemberInfo.Filter() { + MemberInfo.extractClassMembers(clazz, result, new MemberInfo.Filter() { public boolean includeMember(PsiMember member) { if (!(member instanceof PsiMethod)) return false; PsiModifierList list = member.getModifierList(); diff --git a/source/com/intellij/testIntegration/createTest/CreateTestAction.java b/source/com/intellij/testIntegration/createTest/CreateTestAction.java index 7d61be90c7..c34afe4443 100644 --- a/source/com/intellij/testIntegration/createTest/CreateTestAction.java +++ b/source/com/intellij/testIntegration/createTest/CreateTestAction.java @@ -26,6 +26,8 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; + public class CreateTestAction extends PsiElementBaseIntentionAction { @NotNull public String getText() { @@ -163,7 +165,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { private void addTestMethods(Editor editor, PsiClass targetClass, TestFrameworkDescriptor descriptor, - MemberInfo[] methods, + Collection methods, boolean generateBefore, boolean generateAfter) throws IncorrectOperationException { if (generateBefore) { diff --git a/source/com/intellij/testIntegration/createTest/CreateTestDialog.java b/source/com/intellij/testIntegration/createTest/CreateTestDialog.java index 389cdbd900..a57b05af26 100644 --- a/source/com/intellij/testIntegration/createTest/CreateTestDialog.java +++ b/source/com/intellij/testIntegration/createTest/CreateTestDialog.java @@ -181,7 +181,7 @@ public class CreateTestDialog extends DialogWrapper { } }); restoreShowInheritedMembersStatus(); - myMethodsTable = new MemberSelectionTable(new MemberInfo[0], null); + myMethodsTable = new MemberSelectionTable(Collections.emptyList(), null); updateMethodsTable(); } @@ -214,7 +214,7 @@ public class CreateTestDialog extends DialogWrapper { each.setChecked(selectedMethods.contains(each.getMember())); } - myMethodsTable.setMemberInfos(methods.toArray(new MemberInfo[methods.size()])); + myMethodsTable.setMemberInfos(methods); } private void doSelectPackage() { @@ -392,7 +392,7 @@ public class CreateTestDialog extends DialogWrapper { return myTargetDirectory; } - public MemberInfo[] getSelectedMethods() { + public Collection getSelectedMethods() { return myMethodsTable.getSelectedMemberInfos(); } -- 2.11.4.GIT