diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index c561f6b49b67..0e35626a89fd 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -1334,5 +1334,51 @@ public class GenericsHighlightUtil { } return null; } + + public static HighlightInfo areSupersAccessible(@NotNull PsiClass aClass) { + final JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject()); + final GlobalSearchScope resolveScope = aClass.getResolveScope(); + for (PsiClassType superType : aClass.getSuperTypes()) { + final String notAccessibleErrorMessage = isSuperTypeAccessible(superType, new HashSet(), resolveScope, factory); + if (notAccessibleErrorMessage != null) { + return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) + .descriptionAndTooltip(notAccessibleErrorMessage) + .range(HighlightNamesUtil.getClassDeclarationTextRange(aClass)) + .create(); + } + } + return null; + } + + @Nullable + private static String isSuperTypeAccessible(PsiType superType, + HashSet classes, + GlobalSearchScope resolveScope, + JavaPsiFacade factory) { + final PsiClass aClass = PsiUtil.resolveClassInType(superType); + if (aClass != null && classes.add(aClass)) { + final String qualifiedName = aClass.getQualifiedName(); + if (qualifiedName != null && factory.findClass(qualifiedName, resolveScope) == null) { + return "Cannot access " + HighlightUtil.formatClass(aClass); + } + + if (superType instanceof PsiClassType) { + for (PsiType psiType : ((PsiClassType)superType).getParameters()) { + final String notAccessibleMessage = isSuperTypeAccessible(psiType, classes, resolveScope, factory); + if (notAccessibleMessage != null) { + return notAccessibleMessage; + } + } + } + + for (PsiClassType type : aClass.getSuperTypes()) { + final String notAccessibleMessage = isSuperTypeAccessible(type, classes, resolveScope, factory); + if (notAccessibleMessage != null) { + return notAccessibleMessage; + } + } + } + return null; + } } diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java index 7c9c1d9e9f63..383d6292ecdf 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java @@ -381,6 +381,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh super.visitClass(aClass); if (aClass instanceof PsiSyntheticClass) return; if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass)); + if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.areSupersAccessible(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightClassUtil.checkDuplicateTopLevelClass(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkEnumMustNotBeLocal(aClass)); if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion)); diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java7/p/SuperclassImplementsGenericsOfUnknownType.java b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/SuperclassImplementsGenericsOfUnknownType.java index c435a69e8588..1a2d7a699ee3 100644 --- a/java/java-tests/testData/codeInsight/multipleJdks/java7/p/SuperclassImplementsGenericsOfUnknownType.java +++ b/java/java-tests/testData/codeInsight/multipleJdks/java7/p/SuperclassImplementsGenericsOfUnknownType.java @@ -1,2 +1,3 @@ package p; -abstract class B extends A{} \ No newline at end of file +abstract class B extends A{} +abstract class C extends A1{} diff --git a/java/java-tests/testData/codeInsight/multipleJdks/java8/p/SuperclassImplementsGenericsOfUnknownType.java b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/SuperclassImplementsGenericsOfUnknownType.java index a0859d35946b..15bf832b83e4 100644 --- a/java/java-tests/testData/codeInsight/multipleJdks/java8/p/SuperclassImplementsGenericsOfUnknownType.java +++ b/java/java-tests/testData/codeInsight/multipleJdks/java8/p/SuperclassImplementsGenericsOfUnknownType.java @@ -3,4 +3,5 @@ import java.util.stream.Stream; import java.util.List; public abstract class A implements List> { -} \ No newline at end of file +} +abstract class A1 extends A {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java index e535a9522532..4167b01e2bf2 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/MultipleJdksHighlightingTest.java @@ -114,12 +114,10 @@ public class MultipleJdksHighlightingTest extends UsefulTestCase { doTestWithoutLibrary(); } - @Bombed(month = Calendar.FEBRUARY, day = 20) public void testSuperclassImplementsUnknownType() throws Exception { doTestWithoutLibrary(); } - @Bombed(month = Calendar.FEBRUARY, day = 20) public void testSuperclassImplementsGenericsOfUnknownType() throws Exception { doTestWithoutLibrary(); }