enclosing instance check: don't check the inheritance for the class with extends/implements itself

This commit is contained in:
Anna.Kozlova
2017-03-08 19:15:20 +01:00
parent 472660a3b0
commit 92d60ede85
3 changed files with 26 additions and 4 deletions
@@ -784,7 +784,7 @@ public class HighlightClassUtil {
if (!PsiUtil.isInnerClass(base)) return;
if (resolve == resolved && baseClass != null && (!PsiTreeUtil.isAncestor(baseClass, extendRef, true) || aClass.hasModifierProperty(PsiModifier.STATIC)) &&
!InheritanceUtil.hasEnclosingInstanceInScope(baseClass, extendRef, PsiUtil.isInnerClass(aClass) && !aClass.hasModifierProperty(PsiModifier.STATIC), true) &&
!InheritanceUtil.hasEnclosingInstanceInScope(baseClass, extendRef, psiClass -> psiClass != aClass, true) &&
!qualifiedNewCalledInConstructors(aClass)) {
String description = JavaErrorMessages.message("no.enclosing.instance.in.scope", HighlightUtil.formatClass(baseClass));
infos[0] = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(extendRef).descriptionAndTooltip(description).create();
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.util;
import com.intellij.openapi.util.Condition;
import com.intellij.psi.*;
import com.intellij.util.Processor;
import gnu.trove.THashSet;
@@ -131,13 +132,20 @@ public class InheritanceUtil {
public static boolean hasEnclosingInstanceInScope(PsiClass aClass,
PsiElement scope,
final boolean isSuperClassAccepted,
boolean isSuperClassAccepted,
boolean isTypeParamsAccepted) {
return hasEnclosingInstanceInScope(aClass, scope, psiClass -> isSuperClassAccepted, isTypeParamsAccepted);
}
public static boolean hasEnclosingInstanceInScope(PsiClass aClass,
PsiElement scope,
Condition<PsiClass> isSuperClassAccepted,
boolean isTypeParamsAccepted) {
PsiManager manager = aClass.getManager();
PsiElement place = scope;
while (place != null && place != aClass && !(place instanceof PsiFile)) {
if (place instanceof PsiClass) {
if (isSuperClassAccepted) {
if (isSuperClassAccepted.value((PsiClass)place)) {
if (isInheritorOrSelf((PsiClass)place, aClass, true)) return true;
}
else {
@@ -2,4 +2,18 @@ class Outer {
class Inner extends Outer {}
}
class Impl extends <error descr="No enclosing instance of type 'Outer' is in scope">Outer.Inner</error> {}
class Impl extends <error descr="No enclosing instance of type 'Outer' is in scope">Outer.Inner</error> {}
class Impl1 {
class InnerImpl extends <error descr="No enclosing instance of type 'Outer' is in scope">Outer.Inner</error> {}
}
class Impl2 extends Outer {
{
class <warning descr="Local class 'L' is never used">L</warning> extends Outer.Inner {}
}
class In extends Outer.Inner {}
static class In1 extends <error descr="No enclosing instance of type 'Outer' is in scope">Outer.Inner</error> {}
}