[java-inspections] IDEA-357190 Support JEP477 - Remove unnecessary qualification is not suggested when it can be

- check if class is already imported

GitOrigin-RevId: 11a43bf80302194a4f8b34125de2bb741f1f3bac
This commit is contained in:
Mikhail Pyltsin
2024-08-09 11:00:42 +00:00
committed by intellij-monorepo-bot
parent d3c5f5a6c0
commit 0f5aa949cb
5 changed files with 59 additions and 20 deletions
@@ -130,7 +130,8 @@ public final class ImportUtils {
if (hasExactImportConflict(fqName, file)) {
return false;
}
if (hasOnDemandImportConflict(fqName, file, true)) {
if (hasOnDemandImportConflict(fqName, file, true) && !isAlreadyImported(file, fqName)
) {
return false;
}
if (containsConflictingReference(file, fqName)) {
@@ -142,6 +143,34 @@ public final class ImportUtils {
return !containsConflictingTypeParameter(fqName, context);
}
/**
* Checks if the class with the given fully qualified name is already imported in the specified Java file.
*
* @param file the Java file to check for the import.
* @param fullyQualifiedName the fully qualified name of the class to check.
* @return true if the class is already imported, false otherwise.
*/
public static boolean isAlreadyImported(@NotNull PsiJavaFile file, @NotNull String fullyQualifiedName) {
String className = extractClassName(file, fullyQualifiedName);
Project project = file.getProject();
PsiResolveHelper resolveHelper = PsiResolveHelper.getInstance(project);
PsiClass psiClass = resolveHelper.resolveReferencedClass(className, file);
return psiClass != null && fullyQualifiedName.equals(psiClass.getQualifiedName());
}
private static @NotNull String extractClassName(@NotNull PsiJavaFile file, @NotNull String fullyQualifiedName) {
for (PsiClass aClass : file.getClasses()) {
String outerClassName = aClass.getQualifiedName();
if (outerClassName != null && fullyQualifiedName.startsWith(outerClassName)) {
return fullyQualifiedName.substring(outerClassName.lastIndexOf('.') + 1);
}
}
return ClassUtil.extractClassName(fullyQualifiedName);
}
private static boolean containsConflictingTypeParameter(String fqName, PsiElement context) {
final String shortName = ClassUtil.extractClassName(fqName);
PsiElement parent = context.getParent();
@@ -9,7 +9,6 @@ import com.intellij.jsp.JspSpiUtil;
import com.intellij.lang.ASTNode;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.openapi.util.Predicates;
@@ -42,6 +41,7 @@ import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.NotNullList;
import com.siyeh.ig.psiutils.ImportUtils;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
import one.util.streamex.StreamEx;
@@ -704,25 +704,15 @@ public final class ImportHelper{
});
}
/**
* Checks if the class with the given fully qualified name is already imported in the specified Java file.
*
* @param file the Java file to check for the import.
* @param fullyQualifiedName the fully qualified name of the class to check.
* @return true if the class is already imported, false otherwise.
*/
public static boolean isAlreadyImported(@NotNull PsiJavaFile file, @NotNull String fullyQualifiedName) {
String className = extractClassName(file, fullyQualifiedName);
Project project = file.getProject();
PsiResolveHelper resolveHelper = PsiResolveHelper.getInstance(project);
PsiClass psiClass = resolveHelper.resolveReferencedClass(className, file);
return psiClass != null && fullyQualifiedName.equals(psiClass.getQualifiedName());
}
private static @NotNull String extractClassName(@NotNull PsiJavaFile file, @NotNull String fullyQualifiedName) {
for (PsiClass aClass : file.getClasses()) {
String outerClassName = aClass.getQualifiedName();
if (outerClassName != null && fullyQualifiedName.startsWith(outerClassName)) {
return fullyQualifiedName.substring(outerClassName.lastIndexOf('.') + 1);
}
}
return ClassUtil.extractClassName(fullyQualifiedName);
return ImportUtils.isAlreadyImported(file, fullyQualifiedName);
}
public ASTNode getDefaultAnchor(@NotNull PsiImportList list, @NotNull PsiImportStatementBase statement){
@@ -0,0 +1,6 @@
import p.Date;
public static void main(String[] args) {
Date date;
date = new Date();
}
@@ -0,0 +1,6 @@
import p.Date;
public static void main(String[] args) {
<warning descr="Qualifier 'p' is unnecessary and can be removed">p</warning><caret>.Date date;
date = new Date();
}
@@ -30,6 +30,14 @@ public class UnnecessaryFullyQualifiedNameWithImplicitImportsFixTest extends Lig
checkQuickFix(InspectionGadgetsBundle.message("unnecessary.fully.qualified.name.remove.quickfix"));
}
public void testAlreadyImported() {
myFixture.addClass("""
package p;
public class Date {}""");
doTest();
checkQuickFix(InspectionGadgetsBundle.message("unnecessary.fully.qualified.name.remove.quickfix"));
}
public void testSimpleImportJavaLangWithImplicitClassWithConflict() {
myFixture.addClass("""
package p;