mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-153358 Inspection Declaration access can be weaker: false positive for lambda usage
This commit is contained in:
+46
-26
@@ -26,6 +26,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.searches.FunctionalExpressionSearch;
|
||||
import com.intellij.psi.util.ClassUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -145,34 +146,23 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
PsiDirectory memberDirectory = memberFile.getContainingDirectory();
|
||||
final PsiPackage memberPackage = memberDirectory == null ? null : JavaDirectoryService.getInstance().getPackage(memberDirectory);
|
||||
log(member.getName()+ ": checking effective level for "+member);
|
||||
boolean result =
|
||||
UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> {
|
||||
foundUsage.set(true);
|
||||
PsiFile psiFile = info.getFile();
|
||||
if (psiFile == null) return true;
|
||||
if (!(psiFile instanceof PsiJavaFile)) {
|
||||
log(" refd from " + psiFile.getName() + "; set to public");
|
||||
maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
|
||||
if (memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
return false; // referenced from XML, has to be public
|
||||
}
|
||||
//int offset = info.getNavigationOffset();
|
||||
//if (offset == -1) return true;
|
||||
PsiElement element = info.getElement();
|
||||
if (element == null) return true;
|
||||
@PsiUtil.AccessLevel
|
||||
int level = getEffectiveLevel(element, psiFile, member, memberFile, memberClass, memberPackage);
|
||||
log(" ref in file " + psiFile.getName() + "; level = " + PsiUtil.getAccessModifier(level) + "; (" + element + ")");
|
||||
maxLevel.getAndAccumulate(level, Math::max);
|
||||
if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
|
||||
return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
|
||||
UnusedSymbolUtil.processUsages(project, memberFile, member, new EmptyProgressIndicator(), null, info -> {
|
||||
PsiElement element = info.getElement();
|
||||
if (element == null) return true;
|
||||
PsiFile psiFile = info.getFile();
|
||||
if (psiFile == null) return true;
|
||||
|
||||
return handleUsage(member, memberClass, memberFile, maxLevel, memberPackage, element, psiFile, foundUsage);
|
||||
});
|
||||
|
||||
if (member instanceof PsiClass && ((PsiClass)member).isInterface()) {
|
||||
// there can be lambda implementing this interface implicitly
|
||||
FunctionalExpressionSearch.search((PsiClass)member).forEach(functionalExpression -> {
|
||||
PsiFile psiFile = functionalExpression.getContainingFile();
|
||||
return handleUsage(member, memberClass, memberFile, maxLevel, memberPackage, functionalExpression, psiFile, foundUsage);
|
||||
});
|
||||
|
||||
}
|
||||
if (!foundUsage.get()) {
|
||||
log(member.getName() + " unused; ignore");
|
||||
return; // do not propose private for unused method
|
||||
@@ -199,6 +189,36 @@ class AccessCanBeTightenedInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
|
||||
private boolean handleUsage(@NotNull PsiMember member,
|
||||
@Nullable PsiClass memberClass,
|
||||
@NotNull PsiFile memberFile,
|
||||
@NotNull AtomicInteger maxLevel,
|
||||
@Nullable PsiPackage memberPackage,
|
||||
@NotNull PsiElement element,
|
||||
@NotNull PsiFile psiFile,
|
||||
@NotNull AtomicBoolean foundUsage) {
|
||||
foundUsage.set(true);
|
||||
if (!(psiFile instanceof PsiJavaFile)) {
|
||||
log(" refd from " + psiFile.getName() + "; set to public");
|
||||
maxLevel.set(PsiUtil.ACCESS_LEVEL_PUBLIC);
|
||||
if (memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
return false; // referenced from XML, has to be public
|
||||
}
|
||||
//int offset = info.getNavigationOffset();
|
||||
//if (offset == -1) return true;
|
||||
@PsiUtil.AccessLevel
|
||||
int level = getEffectiveLevel(element, psiFile, member, memberFile, memberClass, memberPackage);
|
||||
log(" ref in file " + psiFile.getName() + "; level = " + PsiUtil.getAccessModifier(level) + "; (" + element + ")");
|
||||
maxLevel.getAndAccumulate(level, Math::max);
|
||||
if (level == PsiUtil.ACCESS_LEVEL_PUBLIC && memberClass != null) {
|
||||
childMembersAreUsedOutsideMyPackage.add(memberClass);
|
||||
}
|
||||
|
||||
return level != PsiUtil.ACCESS_LEVEL_PUBLIC;
|
||||
}
|
||||
|
||||
@PsiUtil.AccessLevel
|
||||
private int getEffectiveLevel(@NotNull PsiElement element,
|
||||
@NotNull PsiFile file,
|
||||
|
||||
+31
@@ -144,6 +144,37 @@ public class AccessCanBeTightenedInspectionTest extends LightInspectionTestCase
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
public void testInterfaceIsImplementedByLambda() {
|
||||
myFixture.allowTreeAccessForAllFiles();
|
||||
myFixture.addFileToProject("x/MyInterface.java",
|
||||
"package x;\n" +
|
||||
"public interface MyInterface {\n" +
|
||||
" void doStuff();\n" +
|
||||
"}\n" +
|
||||
"");
|
||||
myFixture.addFileToProject("x/MyConsumer.java",
|
||||
"package x;\n" +
|
||||
"public class MyConsumer {\n" +
|
||||
" public void doIt(MyInterface i) {\n" +
|
||||
" i.doStuff();\n" +
|
||||
" }\n" +
|
||||
"}" +
|
||||
"");
|
||||
myFixture.addFileToProject("y/Test.java",
|
||||
"package y;\n" +
|
||||
"\n" +
|
||||
"import x.MyConsumer;\n" +
|
||||
"\n" +
|
||||
"public class Test {\n" +
|
||||
" void ddd(MyConsumer consumer) {\n" +
|
||||
" consumer.doIt(() -> {});\n" +
|
||||
" }\n" +
|
||||
"}" +
|
||||
"");
|
||||
myFixture.configureByFiles("x/MyInterface.java", "y/Test.java", "x/MyConsumer.java");
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LocalInspectionTool getInspection() {
|
||||
VisibilityInspection inspection = new VisibilityInspection();
|
||||
|
||||
Reference in New Issue
Block a user