diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
index cd09b455ece4..cad1c585f3ab 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
@@ -654,7 +654,7 @@ public class HighlightClassUtil {
* @param extendRef points to the class in the extends list
* @param resolved extendRef resolved
*/
- public static HighlightInfo checkClassExtendsForeignInnerClass(PsiJavaCodeReferenceElement extendRef, PsiElement resolved) {
+ public static HighlightInfo checkClassExtendsForeignInnerClass(final PsiJavaCodeReferenceElement extendRef, PsiElement resolved) {
PsiElement parent = extendRef.getParent();
if (!(parent instanceof PsiReferenceList)) {
return null;
@@ -663,7 +663,7 @@ public class HighlightClassUtil {
if (!(grand instanceof PsiClass)) {
return null;
}
- PsiClass aClass = (PsiClass)grand;
+ final PsiClass aClass = (PsiClass)grand;
if (aClass instanceof PsiTypeParameter) {
return null;
}
@@ -673,17 +673,41 @@ public class HighlightClassUtil {
if (!(resolved instanceof PsiClass)) {
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, extendRef, JavaErrorMessages.message("class.name.expected"));
}
- PsiClass base = (PsiClass)resolved;
- // must be inner class
- if (!PsiUtil.isInnerClass(base)) return null;
- PsiClass baseClass = base.getContainingClass();
+ final HighlightInfo[] infos = new HighlightInfo[1];
+ extendRef.accept(new JavaRecursiveElementWalkingVisitor() {
+ @Override
+ public void visitElement(PsiElement element) {
+ if (infos[0] != null) return;
+ super.visitElement(element);
+ }
- if (!hasEnclosingInstanceInScope(baseClass, extendRef, true) && !qualifiedNewCalledInConstructors(aClass, baseClass)) {
- String description = JavaErrorMessages.message("no.enclosing.instance.in.scope", HighlightUtil.formatClass(baseClass));
- return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, extendRef, description);
- }
+ @Override
+ public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
+ super.visitReferenceElement(reference);
+ final PsiElement resolve = reference.resolve();
+ if (resolve instanceof PsiClass) {
+ final PsiClass base = (PsiClass)resolve;
+ final PsiClass baseClass = base.getContainingClass();
+ if (baseClass != null && base.hasModifierProperty(PsiModifier.PRIVATE) && !PsiTreeUtil.isAncestor(baseClass, aClass, true)) {
+ String description = JavaErrorMessages.message("private.symbol",
+ HighlightUtil.formatClass(base),
+ HighlightUtil.formatClass(baseClass));
+ infos[0] = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, extendRef, description);
+ return;
+ }
- return null;
+ // must be inner class
+ if (!PsiUtil.isInnerClass(base)) return;
+
+ if (!hasEnclosingInstanceInScope(baseClass, extendRef, true) && !qualifiedNewCalledInConstructors(aClass, baseClass)) {
+ String description = JavaErrorMessages.message("no.enclosing.instance.in.scope", HighlightUtil.formatClass(baseClass));
+ infos[0] = HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, extendRef, description);
+ }
+ }
+ }
+ });
+
+ return infos[0];
}
private static boolean qualifiedNewCalledInConstructors(final PsiClass aClass, final PsiClass baseClass) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/PrivateInnerClassRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/PrivateInnerClassRef.java
new file mode 100644
index 000000000000..53c5b5660dce
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/PrivateInnerClassRef.java
@@ -0,0 +1,14 @@
+import java.util.Comparator;
+
+public abstract class A implements Comparator {
+
+ private static class B {
+ }
+
+ private interface I extends Comparator{}
+ private interface I1 extends Comparator{}
+}
+
+//abstract class C implements error descr="'C.D' has private access in 'C'">C.D error {
+// private static class D {}
+//}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index 0a352a05bab3..452ece2addbb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -102,6 +102,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testTypeWithinItsWildcardBound() throws Exception { doTest(false); }
public void testMethodSignatureEquality() throws Exception { doTest(false); }
public void testInnerClassRef() throws Exception { doTest(false); }
+ public void testPrivateInnerClassRef() throws Exception { doTest(false); }
public void testJavaUtilCollections() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));