mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix Pull Up refactoring after removal of MethodElement#copyElement override
In some scenarios Pull Up worked correctly only by chance, thanks to incorrect resolve on copied method. However there are more scenarios, presented in new tests ReferencedStaticGenericClassFromOuterClass and ReferencedStaticMethodFromOuterClass, which did not work correctly even before. The fix addresses these cases. GitOrigin-RevId: bd56ed851dd8bbf546dba2847535a98de1eea295
This commit is contained in:
committed by
intellij-monorepo-bot
parent
f3f3e9eecb
commit
77517a3a3a
@@ -100,16 +100,23 @@ public class JavaPullUpHelper implements PullUpHelper<MemberInfo> {
|
||||
|
||||
member.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
final PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
|
||||
final PsiElement qualifierExpression = reference.getQualifier();
|
||||
if (qualifierExpression != null) {
|
||||
final Boolean preserveQualifier = qualifierExpression.getCopyableUserData(PRESERVE_QUALIFIER);
|
||||
if (preserveQualifier != null && !preserveQualifier) {
|
||||
qualifierExpression.delete();
|
||||
return;
|
||||
PsiElement target = reference.resolve();
|
||||
if (target != null) {
|
||||
PsiJavaCodeReferenceElement copy = (PsiJavaCodeReferenceElement)reference.copy();
|
||||
Objects.requireNonNull(copy.getQualifier()).delete();
|
||||
if (copy.resolve() == target) {
|
||||
qualifierExpression.delete();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
super.visitReferenceExpression(expression);
|
||||
super.visitReferenceElement(reference);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -686,15 +693,16 @@ public class JavaPullUpHelper implements PullUpHelper<MemberInfo> {
|
||||
PsiClass aClass = classes.get(i);
|
||||
|
||||
if (namedElement instanceof PsiNamedElement) {
|
||||
PsiReferenceExpression newRef =
|
||||
(PsiReferenceExpression) factory.createExpressionFromText
|
||||
("a." + ((PsiNamedElement) namedElement).getName(),
|
||||
null);
|
||||
PsiExpression qualifierExpression = newRef.getQualifierExpression();
|
||||
assert qualifierExpression != null;
|
||||
qualifierExpression = (PsiExpression)qualifierExpression.replace(factory.createReferenceExpression(aClass));
|
||||
qualifierExpression.putCopyableUserData(PRESERVE_QUALIFIER, ref.isQualified());
|
||||
ref.replace(newRef);
|
||||
PsiElement oldQualifier = ref.getQualifier();
|
||||
if (oldQualifier != null) {
|
||||
oldQualifier.delete();
|
||||
}
|
||||
String template = aClass.getQualifiedName() + "." + ref.getText();
|
||||
PsiJavaCodeReferenceElement newRef = ref instanceof PsiReferenceExpression ?
|
||||
(PsiReferenceExpression)factory.createExpressionFromText(template, null) :
|
||||
factory.createReferenceFromText(template, null);
|
||||
ref = (PsiJavaCodeReferenceElement)ref.replace(newRef);
|
||||
Objects.requireNonNull(ref.getQualifier()).putCopyableUserData(PRESERVE_QUALIFIER, oldQualifier != null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
|
||||
class A extends C {
|
||||
void <caret>foo() {
|
||||
A.D<String> d = new A.D<>();
|
||||
}
|
||||
|
||||
static class D<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class C {
|
||||
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
|
||||
class A extends C {
|
||||
|
||||
}
|
||||
|
||||
class C {
|
||||
|
||||
void foo() {
|
||||
C.D<String> d = new C.D<>();
|
||||
}
|
||||
|
||||
static class D<T> {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
static class B extends C {
|
||||
void <caret>foo() {
|
||||
bar();
|
||||
}
|
||||
}
|
||||
|
||||
static void bar() {}
|
||||
}
|
||||
|
||||
class C {
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
class A {
|
||||
static class B extends C {
|
||||
}
|
||||
|
||||
static void bar() {}
|
||||
}
|
||||
|
||||
class C {
|
||||
|
||||
void foo() {
|
||||
A.bar();
|
||||
}
|
||||
}
|
||||
@@ -160,6 +160,15 @@ public class PullUpTest extends LightRefactoringTestCase {
|
||||
public void testTypeParamsConflictingNames() {
|
||||
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class, true));
|
||||
}
|
||||
|
||||
public void testReferencedStaticMethodFromOuterClass() {
|
||||
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class, false));
|
||||
}
|
||||
|
||||
public void testReferencedStaticGenericClassFromOuterClass() {
|
||||
doTest(false, new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class),
|
||||
new RefactoringTestUtil.MemberDescriptor("D", PsiClass.class));
|
||||
}
|
||||
|
||||
public void testConflictOnNewAbstractMethod() {
|
||||
doTest(false, "Concrete 'class <b><code>C</code></b>' would inherit a new abstract method", new RefactoringTestUtil.MemberDescriptor("foo", PsiMethod.class));
|
||||
|
||||
Reference in New Issue
Block a user