[java-inspections] IDEA-288910 avoid warning if two classes with the same simple name are used

GitOrigin-RevId: f2048ea5840ae36ee92c40826a078e7eb3e8243a
This commit is contained in:
Mikhail Pyltsin
2022-12-14 13:24:56 +00:00
committed by intellij-monorepo-bot
parent 40e7346234
commit 9f00b76c0c
6 changed files with 77 additions and 17 deletions
@@ -4,6 +4,6 @@ import java.util.Date;
class FullyQualifiedName {
void m(Object value) {
value = new java.sql.Date(((Date) value).getTime());
value = ((Date) value).getTime();
}
}
@@ -2,6 +2,6 @@
class FullyQualifiedName {
void m(Object value) {
value = new java.sql.Date(((java.<caret>util.Date) value).getTime());
value = ((java.<caret>util.Date) value).getTime();
}
}
@@ -20,7 +20,6 @@ import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ProblemHighlightType;
import com.intellij.codeInspection.options.OptPane;
import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.openapi.wm.WindowManager;
@@ -30,6 +29,9 @@ import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.JavaCodeStyleSettings;
import com.intellij.psi.impl.source.codeStyle.ImportHelper;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.psi.util.PsiModificationTracker;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.SmartList;
import com.siyeh.InspectionGadgetsBundle;
@@ -40,15 +42,11 @@ import com.siyeh.ig.psiutils.CommentTracker;
import com.siyeh.ig.psiutils.HighlightUtils;
import com.siyeh.ig.psiutils.ImportUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import static com.intellij.codeInspection.options.OptPane.*;
import static com.intellij.codeInspection.options.OptPane.checkbox;
import static com.intellij.codeInspection.options.OptPane.pane;
public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection implements CleanupLocalInspectionTool {
@@ -220,8 +218,7 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
if (element != null && !(element instanceof PsiAnnotation)) {
return;
}
final PsiFile containingFile = reference.getContainingFile();
if (!(containingFile instanceof PsiJavaFile)) {
if (!(reference.getContainingFile() instanceof PsiJavaFile containingFile)) {
return;
}
final PsiElement target = reference.resolve();
@@ -232,12 +229,12 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
final PsiDocComment containingComment = PsiTreeUtil.getParentOfType(reference, PsiDocComment.class);
boolean reportAsInformationInsideJavadoc = false;
if (containingComment != null) {
if (acceptFqnInJavadoc((PsiJavaFile)containingFile, styleSettings)) {
if (acceptFqnInJavadoc(containingFile, styleSettings)) {
return;
}
JavaCodeStyleSettings javaSettings = styleSettings.getCustomSettings(JavaCodeStyleSettings.class);
if (javaSettings.CLASS_NAMES_IN_JAVADOC == JavaCodeStyleSettings.FULLY_QUALIFY_NAMES_IF_NOT_IMPORTED) {
reportAsInformationInsideJavadoc = !ImportHelper.isAlreadyImported((PsiJavaFile)containingFile, reference.getQualifiedName());
reportAsInformationInsideJavadoc = !ImportHelper.isAlreadyImported(containingFile, reference.getQualifiedName());
}
}
final PsiJavaCodeReferenceElement qualifierReference = (PsiJavaCodeReferenceElement)qualifier;
@@ -270,6 +267,12 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
}
final PsiElement qualifier1 = aReference.getQualifier();
if (qualifier1 != null) {
Map<String, Set<String>> allReferencesByName = getReferencesFromCache(containingFile);
Collection<String> classesWithReferenceName = allReferencesByName.get(aReference.getReferenceName());
if (classesWithReferenceName.size() > 1) {
continue;
}
PsiElement elementToHighlight = qualifier1;
final ProblemHighlightType highlightType;
if (reportAsInformationInsideJavadoc ||
@@ -284,14 +287,14 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
}
final boolean inSameFile = aClass.getContainingFile() == containingFile ||
ImportHelper.isAlreadyImported((PsiJavaFile)containingFile, qualifiedName);
ImportHelper.isAlreadyImported(containingFile, qualifiedName);
registerError(elementToHighlight, highlightType, inSameFile);
}
break;
}
}
private void collectInnerClassNames(PsiJavaCodeReferenceElement reference, List<? super PsiJavaCodeReferenceElement> references) {
private static void collectInnerClassNames(PsiJavaCodeReferenceElement reference, List<? super PsiJavaCodeReferenceElement> references) {
PsiElement rParent = reference.getParent();
while (rParent instanceof PsiJavaCodeReferenceElement) {
final PsiJavaCodeReferenceElement parentReference = (PsiJavaCodeReferenceElement)rParent;
@@ -303,11 +306,55 @@ public class UnnecessaryFullyQualifiedNameInspection extends BaseInspection impl
}
}
private boolean acceptFqnInJavadoc(PsiJavaFile javaFile, CodeStyleSettings styleSettings) {
private static boolean acceptFqnInJavadoc(PsiJavaFile javaFile, CodeStyleSettings styleSettings) {
if ("package-info.java".equals(javaFile.getName())) {
return true;
}
return styleSettings.getCustomSettings(JavaCodeStyleSettings.class).useFqNamesInJavadocAlways();
}
}
private static Map<String, Set<String>> getReferencesFromCache(PsiJavaFile file) {
return CachedValuesManager.getCachedValue(file, () -> {
ReferenceCollector referenceCollector = new ReferenceCollector();
file.accept(referenceCollector);
return CachedValueProvider.Result.create(referenceCollector.getReferences(), PsiModificationTracker.MODIFICATION_COUNT);
});
}
private static class ReferenceCollector extends JavaRecursiveElementWalkingVisitor {
private final Map<String, Set<String>> referencesByName = new HashMap<>();
@Override
public void visitImportList(@NotNull PsiImportList list) { }
@Override
public void visitReferenceElement(@NotNull PsiJavaCodeReferenceElement reference) {
super.visitReferenceElement(reference);
if (!reference.isQualified()) {
return;
}
final PsiElement target = reference.resolve();
if (!(target instanceof final PsiClass aClass)) {
return;
}
referencesByName.compute(reference.getReferenceName(), (k, elements) -> {
if (elements == null) {
elements = new HashSet<>();
}
elements.add(aClass.getQualifiedName());
return elements;
});
}
@Override
public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) {
visitReferenceElement(expression);
}
public Map<String, Set<String>> getReferences() {
return referencesByName;
}
}
}
@@ -0,0 +1,6 @@
class Test {
void m(Object value) {
value = new java.sql.Date(((java.<caret>util.Date) value).getTime());
}
}
@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<problems>
</problems>
@@ -31,6 +31,10 @@ public class UnnecessaryFullyQualifiedNameInspectionTest extends IGInspectionTes
doTest(BASE_DIR + "unnecessary_fqn_type_parameter_conflict", new UnnecessaryFullyQualifiedNameInspection());
}
public void testSkipWarningIfThereIsSameNames() {
doTest(BASE_DIR + "unnecessary_fqn_skip_warn_if_confusing", new UnnecessaryFullyQualifiedNameInspection());
}
private void doTestWithFqnInJavadocSetting(String dirPath, int classNamesInJavadoc) {
JavaCodeStyleSettings javaSettings = JavaCodeStyleSettings.getInstance(getProject());