instance inner class accessed from static context in declaration: error if containing class contains type params, good code otherwise

This commit is contained in:
anna
2012-11-16 21:05:06 +01:00
parent 53ef2bccfb
commit 67ac8cc039
4 changed files with 76 additions and 6 deletions
@@ -735,7 +735,7 @@ public class HighlightClassUtil {
// must be inner class
if (!PsiUtil.isInnerClass(base)) return;
if (resolve == resolved && baseClass != null &&
if (resolve == resolved && baseClass != null && !PsiTreeUtil.isAncestor(baseClass, extendRef, true) &&
!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);
@@ -811,11 +811,9 @@ public class HighlightClassUtil {
}
@Nullable
public static HighlightInfo checkCreateInnerClassFromStaticContext(PsiElement element, @Nullable PsiExpression qualifier, PsiClass aClass) {
if (!PsiUtil.isInnerClass(aClass)) return null;
PsiClass outerClass = aClass.getContainingClass();
if (outerClass == null) return null;
public static HighlightInfo checkCreateInnerClassFromStaticContext(PsiElement element,
@Nullable PsiExpression qualifier,
PsiClass aClass) {
PsiElement placeToSearchEnclosingFrom;
if (qualifier != null) {
PsiType qType = qualifier.getType();
@@ -824,6 +822,16 @@ public class HighlightClassUtil {
else {
placeToSearchEnclosingFrom = element;
}
return checkCreateInnerClassFromStaticContext(element, placeToSearchEnclosingFrom, aClass);
}
@Nullable
public static HighlightInfo checkCreateInnerClassFromStaticContext(PsiElement element,
PsiElement placeToSearchEnclosingFrom,
PsiClass aClass) {
if (aClass == null || !PsiUtil.isInnerClass(aClass)) return null;
PsiClass outerClass = aClass.getContainingClass();
if (outerClass == null) return null;
if (outerClass instanceof JspClass || hasEnclosingInstanceInScope(outerClass, placeToSearchEnclosingFrom, true)) return null;
return reportIllegalEnclosingUsage(placeToSearchEnclosingFrom, aClass, outerClass, element);
@@ -901,6 +901,17 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
highlightReferencedMethodOrClassName(ref, resolved);
}
if (!myHolder.hasErrorResults() && resolved instanceof PsiClass) {
final PsiClass aClass = ((PsiClass)resolved).getContainingClass();
if (aClass != null) {
final PsiElement qualifier = ref.getQualifier();
final PsiElement place = qualifier instanceof PsiJavaCodeReferenceElement ? ((PsiJavaCodeReferenceElement)qualifier).resolve() : ref;
if (PsiTreeUtil.isAncestor(aClass, place, false) && aClass.hasTypeParameters()) {
myHolder.add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(ref, place, (PsiClass)resolved));
}
}
}
return result;
}
@@ -0,0 +1,50 @@
class MyTest<K> {
class A<T> {
}
//not an error in java 8?!
static class C<T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> {
}
static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
}
static class B {
{
B.<<error descr="'MyTest.this' cannot be referenced from a static context">A</error>>bar();
<error descr="'MyTest.this' cannot be referenced from a static context">A</error> a;
}
static <T extends <error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> void bar() {
}
void v(C<<error descr="'MyTest.this' cannot be referenced from a static context">A<String></error>> c) {
}
}
}
class MyTest1 {
class A<T> {
}
static class C<T extends A<String>> {
}
static <T extends A<String>> void bar() {
}
static class B {
{
B.<A>bar();
A a = <error descr="'MyTest1.this' cannot be referenced from a static context">new A()</error>;
}
static <T extends A<String>> void bar() {
}
void v(C<A<String>> c) {
}
}
}
@@ -201,6 +201,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testInferenceWithBoxingCovariant() throws Exception { doTest17Incompatibility(false); }
public void testSuperWildcardIsNotWithinItsBound() throws Exception { doTest17Incompatibility(false); }
public void testSpecificReturnType() throws Exception { doTest17Incompatibility(false); }
public void testInstanceClassInStaticContextAccess() throws Exception { doTest17Incompatibility(false); }
public void testJavaUtilCollections_NoVerify() throws Exception {
PsiClass collectionsClass = getJavaFacade().findClass("java.util.Collections", GlobalSearchScope.moduleWithLibrariesScope(getModule()));