diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
index 2860c23f0fda..4b886a80666d 100644
--- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
+++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/META-INF/InspectionGadgets.xml
@@ -2764,7 +2764,7 @@
implementationClass="com.siyeh.ig.visibility.AnonymousClassVariableHidesContainingMethodVariableInspection"/>
checkers = new ArrayList<>(2);
- PsiFile file = holder.getFile();
- if (file instanceof PsiJavaFile) {
- PsiJavaFile javaFile = (PsiJavaFile)file;
- if (javaFile.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_9)) {
- PsiJavaModule psiModule = JavaModuleGraphUtil.findDescriptorByElement(file);
- if (psiModule != null) {
- VirtualFile vFile = file.getVirtualFile();
- if (vFile != null) {
- Module module = ProjectFileIndex.SERVICE.getInstance(holder.getProject()).getModuleForFile(vFile);
- if (module != null) {
- Set exportedPackageNames =
- new THashSet<>(ContainerUtil.mapNotNull(psiModule.getExports(), PsiExportsStatement::getPackageName));
- if (exportedPackageNames.contains(javaFile.getPackageName())) {
- checkers.add(new Java9NonAccessibleTypeExposedVisitor(holder, module, exportedPackageNames));
+ if (checkModuleApi) {
+ PsiFile file = holder.getFile();
+ if (file instanceof PsiJavaFile) {
+ PsiJavaFile javaFile = (PsiJavaFile)file;
+ if (javaFile.getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_9)) {
+ PsiJavaModule psiModule = JavaModuleGraphUtil.findDescriptorByElement(file);
+ if (psiModule != null) {
+ VirtualFile vFile = file.getVirtualFile();
+ if (vFile != null) {
+ Module module = ProjectFileIndex.SERVICE.getInstance(holder.getProject()).getModuleForFile(vFile);
+ if (module != null) {
+ Set exportedPackageNames =
+ new THashSet<>(ContainerUtil.mapNotNull(psiModule.getExports(), PsiExportsStatement::getPackageName));
+ if (exportedPackageNames.contains(javaFile.getPackageName())) {
+ checkers.add(new Java9NonAccessibleTypeExposedVisitor(holder, module, exportedPackageNames));
+ }
}
}
}
}
}
}
- if (!onlyJava9Modules) {
+ if (checkPublicApi || checkPackageLocal) {
checkers.add(new ClassEscapesItsScopeVisitor(holder));
}
- return new VisibilityVisitor(checkers.toArray(VisibilityChecker.EMPTY_ARRAY));
+ return !checkers.isEmpty() ? new VisibilityVisitor(checkers.toArray(VisibilityChecker.EMPTY_ARRAY)) : PsiElementVisitor.EMPTY_VISITOR;
}
private static class VisibilityVisitor extends JavaElementVisitor {
@@ -153,21 +157,26 @@ public class ClassEscapesItsScopeInspection extends BaseJavaBatchLocalInspection
abstract boolean checkVisibilityIssue(PsiMember member, PsiClass psiClass, PsiJavaCodeReferenceElement reference);
}
- private static class ClassEscapesItsScopeVisitor extends VisibilityChecker {
+ private class ClassEscapesItsScopeVisitor extends VisibilityChecker {
public ClassEscapesItsScopeVisitor(ProblemsHolder holder) {
super(holder);
}
@Override
boolean checkVisibilityIssue(PsiMember member, PsiClass psiClass, PsiJavaCodeReferenceElement reference) {
- if (isLessRestrictiveScope(member, psiClass)) {
+ if (needToCheck(member) && isLessRestrictiveScope(member, psiClass)) {
myHolder.registerProblem(reference, InspectionGadgetsBundle.message("class.escapes.defined.scope.problem.descriptor"));
return true;
}
return false;
}
- private static boolean isLessRestrictiveScope(@NotNull PsiMember member, @NotNull PsiClass aClass) {
+ private boolean needToCheck(PsiMember member) {
+ return checkPublicApi && (member.hasModifierProperty(PsiModifier.PUBLIC) || member.hasModifierProperty(PsiModifier.PROTECTED)) ||
+ checkPackageLocal && member.hasModifierProperty(PsiModifier.PACKAGE_LOCAL);
+ }
+
+ private boolean isLessRestrictiveScope(@NotNull PsiMember member, @NotNull PsiClass aClass) {
final int methodScopeOrder = getScopeOrder(member);
final int classScopeOrder = getScopeOrder(aClass);
final PsiClass containingClass = member.getContainingClass();
@@ -179,7 +188,7 @@ public class ClassEscapesItsScopeInspection extends BaseJavaBatchLocalInspection
return methodScopeOrder > classScopeOrder && containingClassScopeOrder > classScopeOrder;
}
- private static int getScopeOrder(@NotNull PsiModifierListOwner element) {
+ private int getScopeOrder(@NotNull PsiModifierListOwner element) {
if (element.hasModifierProperty(PsiModifier.PUBLIC)) {
return 4;
}
@@ -187,10 +196,10 @@ public class ClassEscapesItsScopeInspection extends BaseJavaBatchLocalInspection
return 1;
}
else if (element.hasModifierProperty(PsiModifier.PROTECTED)) {
- return 2;
+ return 3;
}
else {
- return 3;
+ return 2;
}
}
}
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPackageLocal.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPackageLocal.java
new file mode 100644
index 000000000000..d3b81cb7ad47
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPackageLocal.java
@@ -0,0 +1,44 @@
+import java.util.List;
+
+public class ExposedByPackageLocal {
+ public static class NestedPublic { }
+ protected static class NestedProtected { }
+ static class NestedPackageLocal { }
+ private static class NestedPrivate { }
+
+ public NestedPublic withPublic1(
+ List list) { return list.get(0);}
+ protected NestedPublic withPublic2(
+ List list) { return list.get(0);}
+ NestedPublic withPublic3(
+ List list) { return list.get(0);}
+ private NestedPublic withPublic4(
+ List list) { return list.get(0);}
+
+ public NestedProtected withProtected1(
+ List list) { return list.get(0);}
+ protected NestedProtected withProtected2(
+ List list) { return list.get(0);}
+ NestedProtected withProtected3(
+ List list) { return list.get(0);}
+ private NestedProtected withProtected4(
+ List list) { return list.get(0);}
+
+ public NestedPackageLocal withPackageLocal1(
+ List list) { return list.get(0);}
+ protected NestedPackageLocal withPackageLocal2(
+ List list) { return list.get(0);}
+ NestedPackageLocal withPackageLocal3(
+ List list) { return list.get(0);}
+ private NestedPackageLocal withPackageLocal4(
+ List list) { return list.get(0);}
+
+ public NestedPrivate withPrivate1(
+ List list) { return list.get(0);}
+ protected NestedPrivate withPrivate2(
+ List list) { return list.get(0);}
+ NestedPrivate withPrivate3(
+ List<NestedPrivate> list) { return list.get(0);}
+ private NestedPrivate withPrivate4(
+ List list) { return list.get(0);}
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPublic.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPublic.java
new file mode 100644
index 000000000000..1fb22d2f17a7
--- /dev/null
+++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/visibility/class_escapes_its_scope/ExposedByPublic.java
@@ -0,0 +1,44 @@
+import java.util.List;
+
+public class ExposedByPublic {
+ public static class NestedPublic { }
+ protected static class NestedProtected { }
+ static class NestedPackageLocal { }
+ private static class NestedPrivate { }
+
+ public NestedPublic withPublic1(
+ List list) { return list.get(0);}
+ protected NestedPublic withPublic2(
+ List list) { return list.get(0);}
+ NestedPublic withPublic3(
+ List list) { return list.get(0);}
+ private NestedPublic withPublic4(
+ List list) { return list.get(0);}
+
+ public NestedProtected withProtected1(
+ List<NestedProtected> list) { return list.get(0);}
+ protected NestedProtected withProtected2(
+ List list) { return list.get(0);}
+ NestedProtected withProtected3(
+ List list) { return list.get(0);}
+ private NestedProtected withProtected4(
+ List list) { return list.get(0);}
+
+ public NestedPackageLocal withPackageLocal1(
+ List<NestedPackageLocal> list) { return list.get(0);}
+ protected NestedPackageLocal withPackageLocal2(
+ List<NestedPackageLocal> list) { return list.get(0);}
+ NestedPackageLocal withPackageLocal3(
+ List list) { return list.get(0);}
+ private NestedPackageLocal withPackageLocal4(
+ List list) { return list.get(0);}
+
+ public NestedPrivate withPrivate1(
+ List<NestedPrivate> list) { return list.get(0);}
+ protected NestedPrivate withPrivate2(
+ List<NestedPrivate> list) { return list.get(0);}
+ NestedPrivate withPrivate3(
+ List list) { return list.get(0);}
+ private NestedPrivate withPrivate4(
+ List list) { return list.get(0);}
+}
\ No newline at end of file
diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/ClassEscapesItsScopeInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/ClassEscapesItsScopeInspectionTest.java
index 56551611ccd9..c193575bfd93 100644
--- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/ClassEscapesItsScopeInspectionTest.java
+++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/visibility/ClassEscapesItsScopeInspectionTest.java
@@ -23,16 +23,34 @@ import org.jetbrains.annotations.Nullable;
* @author Bas Leijdekkers
*/
public class ClassEscapesItsScopeInspectionTest extends LightInspectionTestCase {
+ private ClassEscapesItsScopeInspection myInspection = new ClassEscapesItsScopeInspection();
- public void testClassEscapesItsScope() { doTest(); }
+ public void testClassEscapesItsScope() { doTest(true, true); }
- public void testGenericParameterEscapesItsScope() { doTest(); }
+ public void testGenericParameterEscapesItsScope() { doTest(true, true); }
+
+ public void testExposedByPublic() {
+ doTest(true, false);
+ }
+
+ public void testExposedByPackageLocal() {
+ doTest(false, true);
+ }
+
+ private void doTest(boolean checkPublicApi, boolean checkPackageLocal) {
+ myInspection.checkPublicApi = checkPublicApi;
+ myInspection.checkPackageLocal = checkPackageLocal;
+ try {
+ doTest();
+ }
+ finally {
+ myInspection.checkPublicApi = myInspection.checkPackageLocal = false;
+ }
+ }
@Nullable
@Override
protected InspectionProfileEntry getInspection() {
- ClassEscapesItsScopeInspection inspection = new ClassEscapesItsScopeInspection();
- inspection.onlyJava9Modules = false;
- return inspection;
+ return myInspection;
}
}
\ No newline at end of file