From 6100f5a69065f97f02f6f12d0e2cd5964b588464 Mon Sep 17 00:00:00 2001 From: anna Date: Tue, 23 Apr 2013 16:51:35 +0200 Subject: [PATCH] extract class: do not warn about usages of statics in class initializers, preserve static imports (IDEA-106017) --- .../extractclass/ExtractClassProcessor.java | 14 +++++++++++--- .../usageInfo/RetargetStaticMethodCall.java | 3 +++ .../staticImports/after/foo/Extracted.java | 7 +++++++ .../staticImports/after/foo/Test.java | 3 +++ .../staticImports/after/foo/Usage.java | 8 ++++++++ .../staticImports/before/foo/Test.java | 4 ++++ .../staticImports/before/foo/Usage.java | 8 ++++++++ .../intellij/refactoring/ExtractClassTest.java | 16 ++++++++++++++-- 8 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Extracted.java create mode 100644 java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Test.java create mode 100644 java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Usage.java create mode 100644 java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Test.java create mode 100644 java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Usage.java diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java index 354d935486fa..8aaf9412074c 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java @@ -212,8 +212,8 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor { public void visitReferenceExpression(final PsiReferenceExpression expression) { super.visitReferenceExpression(expression); final PsiElement resolved = expression.resolve(); - if (resolved != null) { - dependsOnMoved[0] |= isInMovedElement(resolved); + if (resolved instanceof PsiMember) { + dependsOnMoved[0] |= !((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC) && isInMovedElement(resolved); } } }); @@ -550,6 +550,7 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor { final Project project = psiManager.getProject(); final GlobalSearchScope scope = GlobalSearchScope.allScope(project); final Iterable calls = ReferencesSearch.search(method, scope); + final String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); for (PsiReference reference : calls) { final PsiElement referenceElement = reference.getElement(); @@ -557,9 +558,16 @@ public class ExtractClassProcessor extends FixableUsagesRefactoringProcessor { if (parent instanceof PsiMethodCallExpression) { final PsiMethodCallExpression call = (PsiMethodCallExpression)parent; if (!isInMovedElement(call)) { - final String fullyQualifiedName = StringUtil.getQualifiedName(newPackageName, newClassName); usages.add(new RetargetStaticMethodCall(call, fullyQualifiedName)); } + } else if (parent instanceof PsiImportStaticStatement) { + final PsiJavaCodeReferenceElement importReference = ((PsiImportStaticStatement)parent).getImportReference(); + if (importReference != null) { + final PsiElement qualifier = importReference.getQualifier(); + if (qualifier instanceof PsiJavaCodeReferenceElement) { + usages.add(new ReplaceClassReference((PsiJavaCodeReferenceElement)qualifier, fullyQualifiedName)); + } + } } } usages.add(new RemoveMethod(method)); diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RetargetStaticMethodCall.java b/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RetargetStaticMethodCall.java index 6aaacc6fafc1..3d3ab2033b0c 100644 --- a/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RetargetStaticMethodCall.java +++ b/java/java-impl/src/com/intellij/refactoring/extractclass/usageInfo/RetargetStaticMethodCall.java @@ -34,7 +34,10 @@ public class RetargetStaticMethodCall extends FixableUsageInfo { final PsiReferenceExpression methodExpression = call.getMethodExpression(); final PsiExpression qualifier = (PsiExpression) methodExpression.getQualifier(); if (qualifier == null) { + final PsiElement resolveScope = call.resolveMethodGenerics().getCurrentFileResolveScope(); + if (!(resolveScope instanceof PsiImportStaticStatement)) { MutationUtils.replaceExpression(delegateClassName + '.' + call.getText(), call); + } } else { MutationUtils.replaceExpression(delegateClassName , qualifier); } diff --git a/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Extracted.java b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Extracted.java new file mode 100644 index 000000000000..c2ef3ae5dcb0 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Extracted.java @@ -0,0 +1,7 @@ +package foo; + +public class Extracted { + public static T foo() { + return null; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Test.java b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Test.java new file mode 100644 index 000000000000..4d2368c72fde --- /dev/null +++ b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Test.java @@ -0,0 +1,3 @@ +package foo; +class Test { +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Usage.java b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Usage.java new file mode 100644 index 000000000000..4a102ee72d85 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractClass/staticImports/after/foo/Usage.java @@ -0,0 +1,8 @@ +package foo; +import static foo.Extracted.foo; + +class Usage { + { + foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Test.java b/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Test.java new file mode 100644 index 000000000000..7a2b3a3de827 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Test.java @@ -0,0 +1,4 @@ +package foo; +class Test { + public static T foo() { return null; } +} \ No newline at end of file diff --git a/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Usage.java b/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Usage.java new file mode 100644 index 000000000000..4d6c4f23b7d0 --- /dev/null +++ b/java/java-tests/testData/refactoring/extractClass/staticImports/before/foo/Usage.java @@ -0,0 +1,8 @@ +package foo; +import static foo.Test.foo; + +class Usage { + { + foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractClassTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractClassTest.java index 67b9b83a345f..1e287b22f90c 100644 --- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractClassTest.java +++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractClassTest.java @@ -6,6 +6,7 @@ package com.intellij.refactoring; import com.intellij.JavaTestUtil; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; @@ -42,10 +43,16 @@ public class ExtractClassTest extends MultiFileTestCase{ } private void doTestMethod(final String methodName, final String conflicts) throws Exception { + doTestMethod(methodName, conflicts, "Test"); + } + + private void doTestMethod(final String methodName, + final String conflicts, + final String qualifiedName) throws Exception { doTest(new PerformAction() { @Override public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception { - PsiClass aClass = myJavaFacade.findClass("Test", GlobalSearchScope.projectScope(myProject)); + PsiClass aClass = myJavaFacade.findClass(qualifiedName, GlobalSearchScope.projectScope(myProject)); assertNotNull("Class Test not found", aClass); @@ -105,6 +112,10 @@ public class ExtractClassTest extends MultiFileTestCase{ doTestMethod(); } + public void testStaticImports() throws Exception { + doTestMethod("foo", null, "foo.Test"); + } + public void testNoConstructorParams() throws Exception { doTestFieldAndMethod(); } @@ -165,7 +176,8 @@ public class ExtractClassTest extends MultiFileTestCase{ private static void doTest(final PsiClass aClass, final ArrayList methods, final ArrayList fields, final String conflicts, boolean generateGettersSetters) { try { - ExtractClassProcessor processor = new ExtractClassProcessor(aClass, fields, methods, new ArrayList(), "", null, "Extracted", null, generateGettersSetters, Collections.emptyList()); + ExtractClassProcessor processor = new ExtractClassProcessor(aClass, fields, methods, new ArrayList(), StringUtil.getPackageName(aClass.getQualifiedName()), null, + "Extracted", null, generateGettersSetters, Collections.emptyList()); processor.run(); LocalFileSystem.getInstance().refresh(false); FileDocumentManager.getInstance().saveAllDocuments();