mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
pull up/push down: type parameters substitution should modify member copy (IDEA-53496)
This commit is contained in:
@@ -106,9 +106,6 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
final HashSet<PsiMember> movedMembers = new HashSet<PsiMember>();
|
||||
myMembersAfterMove = new HashSet<PsiMember>();
|
||||
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(myMembersToMove, PsiUtil.typeParametersIterable(mySourceClass),
|
||||
upDownSuperClassSubstitutor(),
|
||||
JavaPsiFacade.getElementFactory(myProject));
|
||||
// build aux sets
|
||||
for (MemberInfo info : myMembersToMove) {
|
||||
movedMembers.add(info.getMember());
|
||||
@@ -129,6 +126,9 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
ChangeContextUtil.encodeContextInfo(info.getMember(), true);
|
||||
}
|
||||
|
||||
final PsiSubstitutor substitutor = upDownSuperClassSubstitutor();
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
|
||||
|
||||
// do actual move
|
||||
for (MemberInfo info : myMembersToMove) {
|
||||
if (info.getMember() instanceof PsiMethod) {
|
||||
@@ -138,7 +138,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
PsiMethod methodCopy = (PsiMethod)method.copy();
|
||||
ChangeContextUtil.clearContextInfo(method);
|
||||
RefactoringUtil.abstractizeMethod(myTargetSuperClass, methodCopy);
|
||||
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
if (method.findDeepestSuperMethods().length == 0 || (myTargetSuperClass.isInterface() && !PsiUtil.isLanguageLevel6OrHigher(mySourceClass))) {
|
||||
deleteOverrideAnnotationIfFound(methodCopy);
|
||||
}
|
||||
@@ -169,6 +169,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
if (isOriginalMethodAbstract) {
|
||||
PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true);
|
||||
}
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(method, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
fixReferencesToStatic(method, movedMembers);
|
||||
final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(method, false);
|
||||
if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
|
||||
@@ -184,6 +185,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
else if (info.getMember() instanceof PsiField) {
|
||||
PsiField field = (PsiField)info.getMember();
|
||||
field.normalizeDeclaration();
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(field, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
fixReferencesToStatic(field, movedMembers);
|
||||
if (myIsTargetInterface) {
|
||||
PsiUtil.setModifierProperty(field, PsiModifier.PUBLIC, true);
|
||||
@@ -201,6 +203,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) :
|
||||
RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass);
|
||||
if (ref != null) {
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
final PsiReferenceList referenceList =
|
||||
myTargetSuperClass.isInterface() ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList();
|
||||
assert referenceList != null;
|
||||
@@ -208,6 +211,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
|
||||
}
|
||||
}
|
||||
else {
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory);
|
||||
fixReferencesToStatic(aClass, movedMembers);
|
||||
final PsiMember movedElement = (PsiMember)myTargetSuperClass.add(aClass);
|
||||
myMembersAfterMove.add(movedElement);
|
||||
|
||||
@@ -327,9 +327,8 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
private void pushDownToClass(PsiClass targetClass) throws IncorrectOperationException {
|
||||
final PsiElementFactory factory = JavaPsiFacade.getInstance(myClass.getProject()).getElementFactory();
|
||||
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(myClass, targetClass, PsiSubstitutor.EMPTY);
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(myMemberInfos, PsiUtil.typeParametersIterable(myClass), substitutor, factory);
|
||||
for (MemberInfo memberInfo : myMemberInfos) {
|
||||
final PsiMember member = memberInfo.getMember();
|
||||
PsiMember member = memberInfo.getMember();
|
||||
final List<PsiReference> refsToRebind = new ArrayList<PsiReference>();
|
||||
final PsiModifierList list = member.getModifierList();
|
||||
LOG.assertTrue(list != null);
|
||||
@@ -345,7 +344,8 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
refsToRebind.add(reference);
|
||||
}
|
||||
}
|
||||
|
||||
member = (PsiMember)member.copy();
|
||||
RefactoringUtil.replaceMovedMemberTypeParameters(member, PsiUtil.typeParametersIterable(myClass), substitutor, factory);
|
||||
PsiMember newMember = null;
|
||||
if (member instanceof PsiField) {
|
||||
((PsiField)member).normalizeDeclaration();
|
||||
|
||||
@@ -52,7 +52,6 @@ import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.refactoring.PackageWrapper;
|
||||
import com.intellij.refactoring.introduceField.ElementToWorkOn;
|
||||
import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
import com.intellij.usageView.UsageInfo;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashMap;
|
||||
@@ -857,23 +856,18 @@ public class RefactoringUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void replaceMovedMemberTypeParameters(final MemberInfo[] memberInfos,
|
||||
public static void replaceMovedMemberTypeParameters(final PsiElement member,
|
||||
final Iterable<PsiTypeParameter> parametersIterable,
|
||||
final PsiSubstitutor substitutor,
|
||||
final PsiElementFactory factory) {
|
||||
for (PsiTypeParameter parameter : parametersIterable) {
|
||||
for (PsiReference reference : ReferencesSearch.search(parameter)) {
|
||||
for (PsiReference reference : ReferencesSearch.search(parameter, new LocalSearchScope(member))) {
|
||||
final PsiElement element = reference.getElement();
|
||||
for (MemberInfo memberInfo : memberInfos) {
|
||||
if (PsiTreeUtil.isAncestor(memberInfo.getMember(), element, false)) {
|
||||
PsiType substitutedType = substitutor.substitute(parameter);
|
||||
if (substitutedType == null) {
|
||||
substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
|
||||
}
|
||||
element.getParent().replace(factory.createTypeElement(substitutedType));
|
||||
break;
|
||||
}
|
||||
PsiType substitutedType = substitutor.substitute(parameter);
|
||||
if (substitutedType == null) {
|
||||
substitutedType = TypeConversionUtil.erasure(factory.createType(parameter));
|
||||
}
|
||||
element.getParent().replace(factory.createTypeElement(substitutedType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Test {
|
||||
Integer t;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Test1 {
|
||||
String t;
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
class Super<T> {
|
||||
T t;
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class Test extends Super<Integer>{
|
||||
}
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
class Test1 extends Super<String>{
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
public abstract class Parent<S> {}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
void <caret>method(T t){}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
public abstract class Parent<S> {
|
||||
abstract void method(S t);
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
@Override
|
||||
void method(T t){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Parent<S> {}
|
||||
|
||||
interface I<IT> {
|
||||
void method(IT t);
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> implements I<T>{
|
||||
<caret>
|
||||
public void method(T t){}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
public class Parent<S> implements I<S> {}
|
||||
|
||||
interface I<IT> {
|
||||
void method(IT t);
|
||||
}
|
||||
|
||||
class Child<T> extends Parent<T> {
|
||||
|
||||
public void method(T t){}
|
||||
}
|
||||
@@ -161,6 +161,14 @@ public class InlineSuperClassTest extends MultiFileTestCase {
|
||||
}
|
||||
|
||||
public void testMultipleSubclasses() throws Exception {
|
||||
doTestMultipleSubclasses();
|
||||
}
|
||||
|
||||
public void testMultipleSubstitutions() throws Exception {
|
||||
doTestMultipleSubclasses();
|
||||
}
|
||||
|
||||
private void doTestMultipleSubclasses() throws Exception {
|
||||
doTest(new PerformAction() {
|
||||
public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
|
||||
PsiClass superClass = myJavaFacade.findClass("Super", GlobalSearchScope.allScope(myProject));
|
||||
|
||||
@@ -79,7 +79,19 @@ public class PullUpTest extends LightCodeInsightTestCase {
|
||||
doTest(new MemberDescriptor("f", PsiField.class));
|
||||
}
|
||||
|
||||
public void testGenericsInAbstractMethod() throws Exception {
|
||||
doTest(new MemberDescriptor("method", PsiMethod.class, true));
|
||||
}
|
||||
|
||||
public void testGenericsInImplements() throws Exception {
|
||||
doTest(false, new MemberDescriptor("I", PsiClass.class));
|
||||
}
|
||||
|
||||
private void doTest(MemberDescriptor... membersToFind) throws Exception {
|
||||
doTest(true, membersToFind);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkMemebersMovedCount, MemberDescriptor... membersToFind) throws Exception {
|
||||
configureByFile(BASE_PATH + getTestName(false) + ".java");
|
||||
PsiElement elementAt = getFile().findElementAt(getEditor().getCaretModel().getOffset());
|
||||
final PsiClass sourceClass = PsiTreeUtil.getParentOfType(elementAt, PsiClass.class);
|
||||
@@ -105,7 +117,9 @@ public class PullUpTest extends LightCodeInsightTestCase {
|
||||
final PullUpHelper helper = new PullUpHelper(sourceClass, targetClass, infos, new DocCommentPolicy(DocCommentPolicy.ASIS));
|
||||
helper.run();
|
||||
JavaRefactoringListenerManager.getInstance(getProject()).removeMoveMembersListener(listener);
|
||||
assertEquals(countMoved[0], membersToFind.length);
|
||||
if (checkMemebersMovedCount) {
|
||||
assertEquals(countMoved[0], membersToFind.length);
|
||||
}
|
||||
checkResultByFile(BASE_PATH + getTestName(false) + "_after.java");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user