mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
[java-highlighting] Do not mark potential imports for unresolved references as unused
Improves IDEA-353117 Error highlighting in incomplete project model GitOrigin-RevId: d6419b900fc817c28b7d1b942b28857a14b44141
This commit is contained in:
committed by
intellij-monorepo-bot
parent
4ebe1c86dd
commit
c26fabffef
@@ -187,6 +187,35 @@ final class IncompleteModelUtil {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ref unresolved reference to find potential imports for
|
||||
* @return list of import statements that potentially import the given unresolved reference
|
||||
*/
|
||||
static List<PsiImportStatementBase> getPotentialImports(@NotNull PsiJavaCodeReferenceElement ref) {
|
||||
if (ref.getParent() instanceof PsiImportStatementBase) return List.of();
|
||||
boolean call = ref.getParent() instanceof PsiMethodCallExpression;
|
||||
if (!(ref.getContainingFile() instanceof PsiJavaFile file)) return List.of();
|
||||
PsiImportList list = file.getImportList();
|
||||
List<PsiImportStatementBase> imports = new ArrayList<>();
|
||||
if (list != null) {
|
||||
for (PsiImportStatementBase statement : list.getAllImportStatements()) {
|
||||
if (statement instanceof PsiImportStaticStatement staticImport && staticImport.resolveTargetClass() != null) continue;
|
||||
if (!statement.isOnDemand()) {
|
||||
PsiJavaCodeReferenceElement reference = statement.getImportReference();
|
||||
if (reference == null) continue;
|
||||
String name = reference.getReferenceName();
|
||||
if (name == null || !name.equals(ref.getReferenceName())) continue;
|
||||
if (reference.resolve() != null) continue;
|
||||
}
|
||||
// Unqualified method call cannot be imported using non-static import
|
||||
if (statement instanceof PsiImportStaticStatement || !call) {
|
||||
imports.add(statement);
|
||||
}
|
||||
}
|
||||
}
|
||||
return imports;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ref reference to check
|
||||
* @return true if the reference can be pending. A pending reference is an unresolved reference that can be potentially resolved
|
||||
@@ -202,24 +231,7 @@ final class IncompleteModelUtil {
|
||||
if (!isHierarchyResolved(psiClass)) return true;
|
||||
psiClass = ClassUtils.getContainingClass(psiClass);
|
||||
}
|
||||
boolean call = ref.getParent() instanceof PsiMethodCallExpression;
|
||||
PsiImportList list = ((PsiJavaFile)ref.getContainingFile()).getImportList();
|
||||
if (list != null) {
|
||||
for (PsiImportStatementBase statement : list.getAllImportStatements()) {
|
||||
if (statement instanceof PsiImportStaticStatement staticImport && staticImport.resolveTargetClass() != null) continue;
|
||||
if (!statement.isOnDemand()) {
|
||||
PsiJavaCodeReferenceElement reference = statement.getImportReference();
|
||||
if (reference == null) continue;
|
||||
String name = reference.getReferenceName();
|
||||
if (name == null || !name.equals(ref.getReferenceName())) continue;
|
||||
}
|
||||
// Unqualified method call cannot be imported using non-static import
|
||||
if (statement instanceof PsiImportStaticStatement || !call) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return !getPotentialImports(ref).isEmpty();
|
||||
}
|
||||
if (qualifier instanceof PsiReferenceExpression qualifierRef) {
|
||||
PsiElement qualifierTarget = qualifierRef.resolve();
|
||||
|
||||
@@ -360,10 +360,17 @@ public final class LocalRefUseInfo {
|
||||
registerImportStatement(ref, importStatement);
|
||||
}
|
||||
else if (refElement == null && ref instanceof PsiJavaReference javaReference) {
|
||||
for (JavaResolveResult result : javaReference.multiResolve(true)) {
|
||||
if (result.getCurrentFileResolveScope() instanceof PsiImportStatementBase importStatement) {
|
||||
registerImportStatement(ref, importStatement);
|
||||
break;
|
||||
JavaResolveResult[] results = javaReference.multiResolve(true);
|
||||
if (results.length > 0) {
|
||||
for (JavaResolveResult result : results) {
|
||||
if (result.getCurrentFileResolveScope() instanceof PsiImportStatementBase importStatement) {
|
||||
registerImportStatement(ref, importStatement);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (ref instanceof PsiJavaCodeReferenceElement javaRef) {
|
||||
for (PsiImportStatementBase potentialImport : IncompleteModelUtil.getPotentialImports(javaRef)) {
|
||||
registerImportStatement(ref, potentialImport);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import <info descr="Not resolved until the project is fully loaded">com</info>.<
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
<warning descr="Unused import statement">import java.util.TreeMap;</warning>
|
||||
|
||||
public class DefaultLoaderFactory implements <info descr="Not resolved until the project is fully loaded">ReportLoaderFactory</info> {
|
||||
public static final String GROOVY_DATA_LOADER = "groovy";
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
import <info descr="Not resolved until the project is fully loaded">my</info>.<info descr="Not resolved until the project is fully loaded">unknown</info>.<info descr="Not resolved until the project is fully loaded">pkg</info>.<info descr="Not resolved until the project is fully loaded">Anno</info>;
|
||||
import <info descr="Not resolved until the project is fully loaded">my</info>.<info descr="Not resolved until the project is fully loaded">unknown</info>.<info descr="Not resolved until the project is fully loaded">pkg</info>.<info descr="Not resolved until the project is fully loaded">MyInterface</info>;
|
||||
import <info descr="Not resolved until the project is fully loaded">my</info>.<info descr="Not resolved until the project is fully loaded">unknown</info>.<info descr="Not resolved until the project is fully loaded">pkg</info>.<info descr="Not resolved until the project is fully loaded">Cls</info>;
|
||||
@@ -37,6 +38,10 @@ public class Simple {
|
||||
|
||||
void method(String s, Object obj) {}
|
||||
|
||||
private void methodThrows() throws <warning descr="Exception 'java.io.IOException' is never thrown in the method">IOException</warning> {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
void methodCall(<info descr="Not resolved until the project is fully loaded">Unknown</info> u) {
|
||||
method("Hello", u);
|
||||
method(<error descr="'method(java.lang.String, java.lang.Object)' in 'Simple' cannot be applied to '(Unknown, java.lang.String)'">u</error>, "Hello");
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
package com.intellij.java.codeInsight.daemon.incomplete;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.codeInspection.unneededThrows.RedundantThrowsDeclarationLocalInspection;
|
||||
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
|
||||
import com.intellij.openapi.application.WriteAction;
|
||||
import com.intellij.openapi.project.IncompleteDependenciesService;
|
||||
|
||||
@@ -15,6 +17,7 @@ public final class IncompleteModelHighlightingTest extends LightDaemonAnalyzerTe
|
||||
}
|
||||
|
||||
private void doTest(String fileName) {
|
||||
enableInspectionTools(new UnusedImportInspection(), new RedundantThrowsDeclarationLocalInspection());
|
||||
IncompleteDependenciesService service = getProject().getService(IncompleteDependenciesService.class);
|
||||
try (var ignored = asAutoCloseable(WriteAction.compute(() -> service.enterIncompleteState()))) {
|
||||
doTest(BASE_PATH + "/" + fileName, true, true);
|
||||
|
||||
Reference in New Issue
Block a user