mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
push down: static import preserve (IDEADEV-33557)
This commit is contained in:
@@ -282,11 +282,12 @@ public class JavaChangeUtilSupport implements TreeGenerator, TreeCopyHandler {
|
||||
else {
|
||||
final PsiMember refMember = element.getCopyableUserData(REFERENCED_MEMBER_KEY);
|
||||
if (refMember != null) {
|
||||
LOG.assertTrue(ref instanceof PsiReferenceExpression);
|
||||
element.putCopyableUserData(REFERENCED_MEMBER_KEY, null);
|
||||
PsiElement refElement1 = ref.resolve();
|
||||
if (refMember != refElement1 && !refMember.getManager().areElementsEquivalent(refMember, refElement1)) {
|
||||
try {
|
||||
ref = (PsiJavaCodeReferenceElement) ref.bindToElement(refMember);
|
||||
ref = (PsiJavaCodeReferenceElement) ((PsiReferenceExpression)ref).bindToElementViaStaticImport(refMember.getContainingClass());
|
||||
}
|
||||
catch (IncorrectOperationException e) {
|
||||
// TODO[yole] ignore?
|
||||
|
||||
+4
@@ -84,6 +84,10 @@ public class PsiReferenceExpressionImpl extends ExpressionPsiElement implements
|
||||
if (getQualifierExpression() != null) {
|
||||
throw new IncorrectOperationException("Reference is qualified: "+getText());
|
||||
}
|
||||
if (!isPhysical()) {
|
||||
// don't qualify reference: the isReferenceTo() check fails anyway, whether we have a static import for this member or not
|
||||
return this;
|
||||
}
|
||||
String staticName = getReferenceName();
|
||||
PsiFile containingFile = getContainingFile();
|
||||
PsiImportList importList = null;
|
||||
|
||||
@@ -71,7 +71,7 @@ public class PushDownConflicts {
|
||||
}
|
||||
}
|
||||
|
||||
public void checkTargetClassConflicts(PsiClass targetClass) {
|
||||
public void checkTargetClassConflicts(PsiClass targetClass, boolean checkStatic) {
|
||||
for (final PsiMember movedMember : myMovedMembers) {
|
||||
checkMemberPlacementInTargetClassConflict(targetClass, movedMember);
|
||||
}
|
||||
@@ -84,13 +84,24 @@ public class PushDownConflicts {
|
||||
final PsiExpression qualifier = referenceExpression.getQualifierExpression();
|
||||
if (qualifier != null) {
|
||||
final PsiType qualifierType = qualifier.getType();
|
||||
PsiClass aClass = null;
|
||||
if (qualifierType instanceof PsiClassType) {
|
||||
final PsiClass aClass = ((PsiClassType)qualifierType).resolve();
|
||||
if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) {
|
||||
myConflicts.putValue(aClass, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites"));
|
||||
break Members;
|
||||
aClass = ((PsiClassType)qualifierType).resolve();
|
||||
}
|
||||
else {
|
||||
if (!checkStatic) continue;
|
||||
if (qualifier instanceof PsiReferenceExpression) {
|
||||
final PsiElement resolved = ((PsiReferenceExpression)qualifier).resolve();
|
||||
if (resolved instanceof PsiClass) {
|
||||
aClass = (PsiClass)resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!InheritanceUtil.isInheritorOrSelf(aClass, targetClass, true)) {
|
||||
myConflicts.putValue(aClass, RefactoringBundle.message("pushed.members.will.not.be.visible.from.certain.call.sites"));
|
||||
break Members;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.codeStyle.JavaCodeStyleManagerImpl;
|
||||
import com.intellij.psi.search.searches.ClassInheritorsSearch;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
@@ -41,6 +42,8 @@ import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.HashSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
@@ -93,7 +96,7 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
for (UsageInfo usage : usagesIn) {
|
||||
final PsiElement element = usage.getElement();
|
||||
if (element instanceof PsiClass) {
|
||||
pushDownConflicts.checkTargetClassConflicts((PsiClass)element);
|
||||
pushDownConflicts.checkTargetClassConflicts((PsiClass)element, usagesIn.length > 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,6 +321,22 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
}
|
||||
for (MemberInfo memberInfo : myMemberInfos) {
|
||||
final PsiMember member = memberInfo.getMember();
|
||||
final List<PsiReference> refsToRebind = new ArrayList<PsiReference>();
|
||||
final PsiModifierList list = member.getModifierList();
|
||||
LOG.assertTrue(list != null);
|
||||
if (list.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
for (final PsiReference reference : ReferencesSearch.search(member)) {
|
||||
final PsiElement element = reference.getElement();
|
||||
if (element instanceof PsiReferenceExpression) {
|
||||
final PsiExpression qualifierExpression = ((PsiReferenceExpression)element).getQualifierExpression();
|
||||
if (qualifierExpression instanceof PsiReferenceExpression && !(((PsiReferenceExpression)qualifierExpression).resolve() instanceof PsiClass)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
refsToRebind.add(reference);
|
||||
}
|
||||
}
|
||||
|
||||
PsiMember newMember = null;
|
||||
if (member instanceof PsiField) {
|
||||
((PsiField)member).normalizeDeclaration();
|
||||
@@ -357,6 +376,9 @@ public class PushDownProcessor extends BaseRefactoringProcessor {
|
||||
|
||||
if (newMember != null) {
|
||||
decodeRefs(newMember, targetClass);
|
||||
for (PsiReference psiReference : refsToRebind) {
|
||||
JavaCodeStyleManagerImpl.getInstance(myProject).shortenClassReferences(psiReference.bindToElement(newMember));
|
||||
}
|
||||
final JavaRefactoringListenerManager listenerManager = JavaRefactoringListenerManager.getInstance(newMember.getProject());
|
||||
((JavaRefactoringListenerManagerImpl)listenerManager).fireMemberMoved(myClass, newMember);
|
||||
}
|
||||
|
||||
+1
-1
@@ -140,7 +140,7 @@ public class MoveJavaMemberHandler implements MoveMemberHandler {
|
||||
if (RefactoringUtil.hasOnDemandStaticImport(refExpr, aClass)) {
|
||||
refExpr.setQualifierExpression(null);
|
||||
}
|
||||
else if (!RefactoringUtil.hasStaticImportOn(refExpr, member.getContainingClass(), member)){
|
||||
else if (!RefactoringUtil.hasStaticImportOn(refExpr, member)){
|
||||
PsiElementFactory factory = JavaPsiFacade.getInstance(refExpr.getProject()).getElementFactory();
|
||||
refExpr.setQualifierExpression(factory.createReferenceExpression(aClass));
|
||||
}
|
||||
|
||||
@@ -224,13 +224,13 @@ public class RefactoringUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean hasStaticImportOn(final PsiReferenceExpression expr, final PsiClass aClass, final PsiMember member) {
|
||||
public static boolean hasStaticImportOn(final PsiElement expr, final PsiMember member) {
|
||||
if (expr.getContainingFile() instanceof PsiJavaFile) {
|
||||
final PsiImportList importList = ((PsiJavaFile)expr.getContainingFile()).getImportList();
|
||||
if (importList != null) {
|
||||
final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements();
|
||||
for(PsiImportStaticStatement stmt: importStaticStatements) {
|
||||
if (!stmt.isOnDemand() && stmt.resolveTargetClass() == aClass && Comparing.strEqual(stmt.getReferenceName(), member.getName())) {
|
||||
if (!stmt.isOnDemand() && stmt.resolveTargetClass() == member.getContainingClass() && Comparing.strEqual(stmt.getReferenceName(), member.getName())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
class Test {
|
||||
public void contextChild() {
|
||||
Test.StInner inner1 = new Test.StInner();
|
||||
StInner inner1 = new StInner();
|
||||
Test.InstInner inner2 = this.new InstInner();
|
||||
}
|
||||
|
||||
void foo() {
|
||||
Test.StInner inner1 = new Test.StInner();
|
||||
StInner inner1 = new StInner();
|
||||
Test.InstInner inner2 = this.new InstInner();
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -1,11 +1,11 @@
|
||||
package p1;
|
||||
|
||||
import p2.Statics;
|
||||
import static p2.Statics.PUB_CONST;
|
||||
|
||||
public class Usage {
|
||||
public void test() {
|
||||
Object i = new Object() {
|
||||
public int myInt = Statics.PUB_CONST;
|
||||
public int myInt = PUB_CONST;
|
||||
};
|
||||
}
|
||||
}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
package a;
|
||||
public class A {
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package b;
|
||||
import a.*;
|
||||
|
||||
public class B extends A {
|
||||
public static void foo(){
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package u;
|
||||
import static b.B.foo;
|
||||
public class U {
|
||||
public static void main(String[] args) {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package a;
|
||||
public class A {
|
||||
public static void foo(){
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package b;
|
||||
import a.*;
|
||||
|
||||
public class B extends A {}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package u;
|
||||
import static a.A.foo;
|
||||
public class U {
|
||||
public static void main(String[] args) {
|
||||
foo();
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package a;
|
||||
import static u.U.C;
|
||||
public class A {
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package b;
|
||||
import a.*;
|
||||
import static u.U.C;
|
||||
|
||||
public class B extends A {
|
||||
public static void foo(){
|
||||
System.out.println(C);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package u;
|
||||
public class U {
|
||||
public static final String C = "CONSTANT";
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package a;
|
||||
import static u.U.C;
|
||||
public class A {
|
||||
public static void foo(){
|
||||
System.out.println(C);
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package b;
|
||||
import a.*;
|
||||
|
||||
public class B extends A {}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package u;
|
||||
public class U {
|
||||
public static final String C = "CONSTANT";
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* User: anna
|
||||
* Date: 20-Aug-2008
|
||||
*/
|
||||
package com.intellij.refactoring;
|
||||
|
||||
import com.intellij.JavaTestUtil;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiMethod;
|
||||
import com.intellij.refactoring.memberPushDown.PushDownProcessor;
|
||||
import com.intellij.refactoring.util.DocCommentPolicy;
|
||||
import com.intellij.refactoring.util.classMembers.MemberInfo;
|
||||
|
||||
//push first method from class a.A to class b.B
|
||||
public class PushDownImportsTest extends MultiFileTestCase {
|
||||
protected String getTestRoot() {
|
||||
return "/refactoring/pushDown/";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return JavaTestUtil.getJavaTestDataPath();
|
||||
}
|
||||
|
||||
protected Sdk getTestProjectJdk() {
|
||||
return JavaSdkImpl.getMockJdk15("java 1.5");
|
||||
}
|
||||
|
||||
private void doTest() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(final boolean fail) throws Exception {
|
||||
try {
|
||||
doTest(new PerformAction() {
|
||||
public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
|
||||
final PsiClass srcClass = myJavaFacade.findClass("a.A");
|
||||
assertTrue("Source class not found", srcClass != null);
|
||||
|
||||
final PsiClass targetClass = myJavaFacade.findClass("b.B");
|
||||
assertTrue("Target class not found", targetClass != null);
|
||||
|
||||
final PsiMethod[] methods = srcClass.getMethods();
|
||||
assertTrue("No methods found", methods.length > 0);
|
||||
final MemberInfo[] membersToMove = new MemberInfo[1];
|
||||
final MemberInfo memberInfo = new MemberInfo(methods[0]);
|
||||
memberInfo.setChecked(true);
|
||||
membersToMove[0] = memberInfo;
|
||||
|
||||
new PushDownProcessor(getProject(), membersToMove, srcClass, new DocCommentPolicy(DocCommentPolicy.ASIS)).run();
|
||||
|
||||
|
||||
//LocalFileSystem.getInstance().refresh(false);
|
||||
//FileDocumentManager.getInstance().saveAllDocuments();
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (RuntimeException e) {
|
||||
if (fail) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (fail) {
|
||||
fail("Conflict was not detected");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void testStaticImportsInsidePushedMethod() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testStaticImportOfPushedMethod() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user