diff --git a/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties b/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties index be767bd76fe5..8b762f82a22f 100644 --- a/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties +++ b/java/codeserver/highlighting/resources/messages/JavaCompilationErrorBundle.properties @@ -251,6 +251,7 @@ reference.unresolved=Cannot resolve symbol ''{0}'' reference.ambiguous=Reference to ''{0}'' is ambiguous, both ''{1}'' and ''{2}'' match reference.implicit.class=Implicitly declared class ''{0}'' cannot be referenced reference.non.static.from.static.context=Non-static {0} ''{1}'' cannot be referenced from a static context +reference.outer.type.parameter.from.static.context=''{0}'' cannot be referenced from a static context statement.case.outside.switch=Case statement outside switch statement.invalid=Invalid statement diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java index bd0909615c99..63547501385d 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/GenericsChecker.java @@ -505,6 +505,24 @@ final class GenericsChecker { } } + void checkTypeParameterReference(@NotNull PsiJavaCodeReferenceElement ref, @NotNull PsiTypeParameter typeParameter) { + PsiTypeParameterListOwner owner = typeParameter.getOwner(); + if (owner instanceof PsiClass outerClass) { + if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) { + myVisitor.myExpressionChecker.checkIllegalEnclosingUsage(ref, null, outerClass, ref); + } + } + else if (owner instanceof PsiMethod) { + PsiModifierListOwner staticElement = PsiUtil.getEnclosingStaticElement(ref, null); + if (staticElement != null && PsiTreeUtil.isAncestor(owner, staticElement, true)) { + PsiClass ownerContainingClass = owner.getContainingClass(); + if (ownerContainingClass != null) { + myVisitor.report(JavaErrorKinds.REFERENCE_OUTER_TYPE_PARAMETER_FROM_STATIC_CONTEXT.create(ref, typeParameter)); + } + } + } + } + private void checkUnsafeCastInInstanceOf(@NotNull PsiTypeElement checkTypeElement, @NotNull PsiType checkType, @Nullable PsiType expressionType) { if (expressionType != null && JavaGenericsUtil.isUncheckedCast(checkType, expressionType)) { myVisitor.report(JavaErrorKinds.INSTANCEOF_UNSAFE_CAST.create( diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java index 0d4a4d34b06b..baea0864a6c9 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/JavaErrorVisitor.java @@ -760,6 +760,34 @@ final class JavaErrorVisitor extends JavaElementVisitor { if (!hasErrorResults() && (!(parent instanceof PsiNewExpression newExpression) || !newExpression.isArrayCreation())) { myGenericsChecker.checkParameterizedReferenceTypeArguments(resolved, ref, result.getSubstitutor()); } + if (!hasErrorResults() && resolved instanceof PsiClass psiClass) { + PsiClass aClass = psiClass.getContainingClass(); + if (aClass != null) { + PsiElement qualifier = ref.getQualifier(); + PsiElement place; + if (qualifier instanceof PsiJavaCodeReferenceElement element) { + place = element.resolve(); + } + else { + if (parent instanceof PsiNewExpression newExpression) { + PsiExpression newQualifier = newExpression.getQualifier(); + place = newQualifier == null ? ref : PsiUtil.resolveClassInType(newQualifier.getType()); + } + else { + place = ref; + } + } + if (place != null && + PsiTreeUtil.isAncestor(aClass, place, false) && + aClass.hasTypeParameters() && + !PsiUtil.isInsideJavadocComment(place)) { + myExpressionChecker.checkCreateInnerClassFromStaticContext(ref, place, psiClass); + } + } + else if (resolved instanceof PsiTypeParameter typeParameter) { + myGenericsChecker.checkTypeParameterReference(ref, typeParameter); + } + } if (parent instanceof PsiAnonymousClass psiAnonymousClass && ref.equals(psiAnonymousClass.getBaseClassReference())) { if (!hasErrorResults()) myGenericsChecker.checkGenericCannotExtendException(psiAnonymousClass); } diff --git a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java index b474eb0ab9b0..563510ae7062 100644 --- a/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java +++ b/java/codeserver/highlighting/src/com/intellij/java/codeserver/highlighting/errors/JavaErrorKinds.java @@ -906,6 +906,10 @@ public final class JavaErrorKinds { String name = HighlightMessageUtil.getSymbolName(refElement, PsiSubstitutor.EMPTY); return message("reference.non.static.from.static.context", type, name); }); + public static final Parameterized REFERENCE_OUTER_TYPE_PARAMETER_FROM_STATIC_CONTEXT = + parameterized(PsiJavaCodeReferenceElement.class, PsiTypeParameter.class, "reference.outer.type.parameter.from.static.context") + .withHighlightType((ref, refElement) -> JavaErrorHighlightType.WRONG_REF) + .withRawDescription((ref, refElement) -> message("reference.outer.type.parameter.from.static.context", refElement.getName())); public static final Simple STATEMENT_CASE_OUTSIDE_SWITCH = error("statement.case.outside.switch"); public static final Simple STATEMENT_INVALID = error("statement.invalid"); 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 5911e8980ad8..bec0ea0ce09f 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 @@ -43,14 +43,16 @@ import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil import com.intellij.psi.impl.source.tree.java.PsiReferenceExpressionImpl; import com.intellij.psi.infos.MethodCandidateInfo; import com.intellij.psi.tree.IElementType; -import com.intellij.psi.util.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiTypesUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.psi.util.TypeConversionUtil; import com.intellij.ui.ColorUtil; import com.intellij.ui.NewUI; import com.intellij.util.ObjectUtils; import com.intellij.util.ui.JBUI; import com.intellij.util.ui.NamedColorUtil; import com.intellij.util.ui.UIUtil; -import com.siyeh.ig.psiutils.ClassUtils; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; @@ -628,47 +630,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh add(info); } - if (!hasErrorResults() && resolved instanceof PsiClass psiClass) { - PsiClass aClass = psiClass.getContainingClass(); - if (aClass != null) { - PsiElement qualifier = ref.getQualifier(); - PsiElement place; - if (qualifier instanceof PsiJavaCodeReferenceElement element) { - place = element.resolve(); - } - else { - if (parent instanceof PsiNewExpression newExpression) { - PsiExpression newQualifier = newExpression.getQualifier(); - place = newQualifier == null ? ref : PsiUtil.resolveClassInType(newQualifier.getType()); - } - else { - place = ref; - } - } - if (place != null && - PsiTreeUtil.isAncestor(aClass, place, false) && - aClass.hasTypeParameters() && - !PsiUtil.isInsideJavadocComment(place)) { - add(HighlightClassUtil.checkCreateInnerClassFromStaticContext(ref, place, psiClass)); - } - } - else if (resolved instanceof PsiTypeParameter typeParameter) { - PsiTypeParameterListOwner owner = typeParameter.getOwner(); - if (owner instanceof PsiClass outerClass) { - if (!InheritanceUtil.hasEnclosingInstanceInScope(outerClass, ref, false, false)) { - add(HighlightClassUtil.checkIllegalEnclosingUsage(ref, null, outerClass, ref)); - } - } - else if (owner instanceof PsiMethod) { - PsiClass cls = ClassUtils.getContainingStaticClass(ref); - if (cls != null && PsiTreeUtil.isAncestor(owner, cls, true)) { - String description = JavaErrorBundle.message("cannot.be.referenced.from.static.context", ref.getReferenceName()); - add(HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(ref).descriptionAndTooltip(description)); - } - } - } - } - if (!hasErrorResults()) { add(HighlightUtil.checkPackageAndClassConflict(ref, myFile)); }