From 69c44e772824ccc4c2beb4e2f1267e20c9fa1af6 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Tue, 28 Aug 2018 17:16:12 +0300 Subject: [PATCH] replace onDemand static import with single imports (IDEA-175105) --- .../ipp/imports/OnDemandImportPredicate.java | 8 +-- .../ReplaceOnDemandImportIntention.java | 50 +++++++++++++------ .../com/siyeh/ipp/imports/StaticImport.java | 7 +++ .../siyeh/ipp/imports/StaticImport_after.java | 9 ++++ .../ReplaceOnDemandImportIntentionTest.java | 20 ++++++++ 5 files changed, 76 insertions(+), 18 deletions(-) create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport.java create mode 100644 plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport_after.java create mode 100644 plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/imports/ReplaceOnDemandImportIntentionTest.java diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/OnDemandImportPredicate.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/OnDemandImportPredicate.java index 67d121260a22..1bc5f2ba4b05 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/OnDemandImportPredicate.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/OnDemandImportPredicate.java @@ -16,8 +16,8 @@ package com.siyeh.ipp.imports; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiImportStatement; import com.intellij.psi.PsiImportStatementBase; +import com.intellij.psi.PsiImportStaticStatement; import com.intellij.psi.PsiJavaFile; import com.siyeh.ipp.base.PsiElementPredicate; import com.siyeh.ipp.psiutils.ErrorUtil; @@ -27,14 +27,16 @@ class OnDemandImportPredicate implements PsiElementPredicate { @Override public boolean satisfiedBy(@NotNull PsiElement element) { - // doesn't work for import static yet. - if (!(element instanceof PsiImportStatement)) { + if (!(element instanceof PsiImportStatementBase)) { return false; } PsiImportStatementBase importStatement = (PsiImportStatementBase)element; if (!importStatement.isOnDemand() || ErrorUtil.containsError(element)) { return false; } + if (importStatement instanceof PsiImportStaticStatement && ((PsiImportStaticStatement)importStatement).resolveTargetClass() == null) { + return false; + } return importStatement.getContainingFile() instanceof PsiJavaFile; } } \ No newline at end of file diff --git a/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/ReplaceOnDemandImportIntention.java b/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/ReplaceOnDemandImportIntention.java index 060dd570dcae..cbef5ebdd0c0 100644 --- a/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/ReplaceOnDemandImportIntention.java +++ b/plugins/IntentionPowerPak/src/com/siyeh/ipp/imports/ReplaceOnDemandImportIntention.java @@ -17,15 +17,14 @@ package com.siyeh.ipp.imports; import com.intellij.psi.*; import com.intellij.psi.util.ClassUtil; +import com.intellij.psi.util.ImportsUtil; import com.siyeh.ig.psiutils.CommentTracker; import com.siyeh.ipp.base.Intention; import com.siyeh.ipp.base.PsiElementPredicate; import org.jetbrains.annotations.NotNull; -import java.util.Arrays; -import java.util.Comparator; -import java.util.HashSet; -import java.util.Set; +import java.util.*; +import java.util.function.Function; public class ReplaceOnDemandImportIntention extends Intention { @@ -38,9 +37,11 @@ public class ReplaceOnDemandImportIntention extends Intention { @Override protected void processIntention(@NotNull PsiElement element) { final PsiImportStatementBase importStatementBase = (PsiImportStatementBase)element; + final PsiJavaFile javaFile = (PsiJavaFile)importStatementBase.getContainingFile(); + final PsiManager manager = importStatementBase.getManager(); + final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); if (importStatementBase instanceof PsiImportStatement) { final PsiImportStatement importStatement = (PsiImportStatement)importStatementBase; - final PsiJavaFile javaFile = (PsiJavaFile)importStatement.getContainingFile(); final PsiClass[] classes = javaFile.getClasses(); final String qualifiedName = importStatement.getQualifiedName(); final ClassCollector visitor = new ClassCollector(qualifiedName); @@ -49,24 +50,43 @@ public class ReplaceOnDemandImportIntention extends Intention { } final PsiClass[] importedClasses = visitor.getImportedClasses(); Arrays.sort(importedClasses, new PsiClassComparator()); - final PsiManager manager = importStatement.getManager(); - final PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory(); - final PsiElement importList = importStatement.getParent(); - for (PsiClass importedClass : importedClasses) { - final PsiImportStatement newImportStatement = factory.createImportStatement(importedClass); - importList.add(newImportStatement); - } - new CommentTracker().deleteAndRestoreComments(importStatement); + createImportStatements(importStatement, importedClasses, factory::createImportStatement); } else if (importStatementBase instanceof PsiImportStaticStatement) { - // do something else + PsiClass targetClass = ((PsiImportStaticStatement)importStatementBase).resolveTargetClass(); + if (targetClass != null) { + String[] members = ImportsUtil.collectReferencesThrough(javaFile, + importStatementBase.getImportReference(), + (PsiImportStaticStatement)importStatementBase) + .stream() + .map(PsiReference::resolve) + .filter(resolve -> resolve instanceof PsiMember) + .map(member -> ((PsiMember)member).getName()) + .distinct() + .filter(Objects::nonNull) + .toArray(String[]::new); + + createImportStatements(importStatementBase, + members, + member -> factory.createImportStaticStatement(targetClass, member)); + } } } + private static void createImportStatements(PsiImportStatementBase importStatement, + T[] importedMembers, + Function function) { + final PsiElement importList = importStatement.getParent(); + for (T importedMember : importedMembers) { + importList.add(function.apply(importedMember)); + } + new CommentTracker().deleteAndRestoreComments(importStatement); + } + private static class ClassCollector extends JavaRecursiveElementWalkingVisitor { private final String importedPackageName; - private final Set importedClasses = new HashSet(); + private final Set importedClasses = new HashSet<>(); ClassCollector(String importedPackageName) { this.importedPackageName = importedPackageName; diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport.java new file mode 100644 index 000000000000..e5c5bbf002ae --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport.java @@ -0,0 +1,7 @@ +import static java.util.Arrays.*; +class A { + void f(String[] array){ + sort(array); + System.out.println(asList(array)); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport_after.java b/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport_after.java new file mode 100644 index 000000000000..b5eac69dfba8 --- /dev/null +++ b/plugins/IntentionPowerPak/test/com/siyeh/ipp/imports/StaticImport_after.java @@ -0,0 +1,9 @@ +import static java.util.Arrays.asList; +import static java.util.Arrays.sort; + +class A { + void f(String[] array){ + sort(array); + System.out.println(asList(array)); + } +} \ No newline at end of file diff --git a/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/imports/ReplaceOnDemandImportIntentionTest.java b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/imports/ReplaceOnDemandImportIntentionTest.java new file mode 100644 index 000000000000..27e8629e328a --- /dev/null +++ b/plugins/IntentionPowerPak/testSrc/com/siyeh/ipp/imports/ReplaceOnDemandImportIntentionTest.java @@ -0,0 +1,20 @@ +// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ipp.imports; + +import com.siyeh.IntentionPowerPackBundle; +import com.siyeh.ipp.IPPTestCase; + +public class ReplaceOnDemandImportIntentionTest extends IPPTestCase { + + public void testStaticImport() { doTest(); } + + @Override + protected String getIntentionName() { + return IntentionPowerPackBundle.message("replace.on.demand.import.intention.name"); + } + + @Override + protected String getRelativePath() { + return "imports"; + } +}