diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LocalRefUseInfo.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LocalRefUseInfo.java index c9d9594e30f7..1fd3a14eda9b 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LocalRefUseInfo.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/LocalRefUseInfo.java @@ -376,6 +376,11 @@ public final class LocalRefUseInfo { if (resolveResult.getCurrentFileResolveScope() instanceof PsiImportStatementBase importStatement) { registerImportStatement(importStatement); + } else if (ref instanceof PsiJavaCodeReferenceElement javaRef && + isMethodCallResolvedToLocalVariable(refElement, javaRef)) { + for (PsiImportStatementBase potentialImport : IncompleteModelUtil.getPotentialImports(javaRef, false)) { + registerImportStatement(potentialImport); + } } else if (refElement == null && ref instanceof PsiJavaReference javaReference) { JavaResolveResult[] results = javaReference.multiResolve(true); @@ -464,6 +469,11 @@ public final class LocalRefUseInfo { registerConstructorCall(enumConstant); } + private static boolean isMethodCallResolvedToLocalVariable(@Nullable PsiElement refElement, @NotNull PsiJavaCodeReferenceElement javaRef) { + return javaRef.getParent() instanceof PsiMethodCallExpression && + refElement instanceof PsiLocalVariable; + } + private void registerConstructorCall(@NotNull PsiConstructorCall constructorCall) { if (constructorCall.resolveMethodGenerics().getElement() instanceof PsiNamedElement namedElement) { registerLocallyReferenced(namedElement); diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/UnusedImportsVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/UnusedImportsVisitor.java index 416205198e69..d2b329ded6c2 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/UnusedImportsVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/UnusedImportsVisitor.java @@ -206,7 +206,6 @@ public class UnusedImportsVisitor extends JavaElementVisitor { if (isRedundantImport(javaFile, importStatement, state.refCountHolder)) { redundantImports.add(importStatement); } - else { int entryIndex = JavaCodeStyleManager.getInstance(javaFile.getProject()).findEntryIndex(importStatement); if (entryIndex < state.currentEntryIndex && !state.requiresFix) { @@ -272,7 +271,7 @@ public class UnusedImportsVisitor extends JavaElementVisitor { myState.builderList.add(builder); - if (!predefinedImport && !myState.requiresFix) { + if (!predefinedImport && !myState.requiresFix/* && importStatement.resolve() != null*/) { myState.requiresFix = true; } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/IncompleteModelUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/IncompleteModelUtil.java index 5cddc7720d29..4c4a43d1d991 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/IncompleteModelUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/IncompleteModelUtil.java @@ -213,11 +213,19 @@ public final class IncompleteModelUtil { PsiTypes.nullType().equals(initializerType) && mayHaveNullTypeDueToPendingReference(initializer); } + /** + * @see #getPotentialImports(PsiJavaCodeReferenceElement, boolean) + */ + public static @NotNull List getPotentialImports(@NotNull PsiJavaCodeReferenceElement ref) { + return getPotentialImports(ref, true); + } + /** * @param ref unresolved reference to find potential imports for + * @param ignoreResolvableStaticImports if true, static imports that resolved to a class are filtered out. * @return list of import statements that potentially import the given unresolved reference */ - public static List getPotentialImports(@NotNull PsiJavaCodeReferenceElement ref) { + public static @NotNull List getPotentialImports(@NotNull PsiJavaCodeReferenceElement ref, boolean ignoreResolvableStaticImports) { PsiElement parent = ref.getParent(); if (parent instanceof PsiImportStatementBase || ref.isQualified()) return Collections.emptyList(); boolean maybeClass = canBeClassReference(ref); @@ -226,7 +234,7 @@ public final class IncompleteModelUtil { List imports = new ArrayList<>(); if (list != null) { for (PsiImportStatementBase statement : list.getAllImportStatements()) { - if (statement instanceof PsiImportStaticStatement && ((PsiImportStaticStatement)statement).resolveTargetClass() != null) continue; + if (statement instanceof PsiImportStaticStatement && ((PsiImportStaticStatement)statement).resolveTargetClass() != null && ignoreResolvableStaticImports) continue; if (!statement.isOnDemand()) { PsiJavaCodeReferenceElement reference = statement.getImportReference(); if (reference == null) continue; diff --git a/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportClassNoIntention.java b/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportClassNoIntention.java new file mode 100644 index 000000000000..8e3372adef66 --- /dev/null +++ b/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportClassNoIntention.java @@ -0,0 +1,8 @@ +import static foo.Util.baz; + +class Test { + void test() { + Object baz = null; + baz(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportPackageNoIntention.java b/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportPackageNoIntention.java new file mode 100644 index 000000000000..7902089f521d --- /dev/null +++ b/java/java-tests/testData/psi/optimizeImports/OptimizeImportNotOnTheFlyInvalidStaticImportPackageNoIntention.java @@ -0,0 +1,8 @@ +import static foo.bar.baz; + +class Test { + void test() { + Object baz = null; + baz(); + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/psi/OptimizeImportsTest.java b/java/java-tests/testSrc/com/intellij/java/psi/OptimizeImportsTest.java index 4996c1d57c7c..3cf08344f896 100644 --- a/java/java-tests/testSrc/com/intellij/java/psi/OptimizeImportsTest.java +++ b/java/java-tests/testSrc/com/intellij/java/psi/OptimizeImportsTest.java @@ -44,7 +44,6 @@ import com.intellij.util.concurrency.AppExecutorUtil; import org.jetbrains.annotations.NotNull; import java.util.Set; -import java.util.concurrent.ExecutionException; public class OptimizeImportsTest extends OptimizeImportsTestCase { static final String BASE_PATH = PathManagerEx.getTestDataPath() + "/psi/optimizeImports"; @@ -493,6 +492,22 @@ public class OptimizeImportsTest extends OptimizeImportsTestCase { checkOptimizeImportNoIntention(); } + public void testOptimizeImportNotOnTheFlyInvalidStaticImportPackageNoIntention() { + checkOptimizeImportNoIntention(); + } + + public void testOptimizeImportNotOnTheFlyInvalidStaticImportClassNoIntention() { + myFixture.addFileToProject( + "foo/Util.java", + """ + package foo; + + public class Util {} + """ + ); + checkOptimizeImportNoIntention(); + } + public void testOptimizeImportNotOnTheFlyInvalidImportOnDemand() { checkOptimizeImport(); }