mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[java-highlighting] checkInterfaceMultipleInheritance, checkClassSupersAccessibility -> GenericsChecker
Part of IDEA-365344 Create a new Java error highlighter with minimal dependencies (PSI only) GitOrigin-RevId: d8c69e0cc3ce9f2e4525ce432013e3e0d729a36e
This commit is contained in:
committed by
intellij-monorepo-bot
parent
e4d0585b15
commit
60ceb06e60
@@ -86,6 +86,9 @@ class.anonymous.extends.sealed=Anonymous classes must not extend sealed classes
|
||||
class.already.imported=''{0}'' is already defined in this compilation unit
|
||||
class.not.enclosing=''{0}'' is not an enclosing class
|
||||
class.cannot.be.referenced.from.static.context=''{0}'' cannot be referenced from a static context
|
||||
class.inheritance.different.type.arguments=''{0}'' cannot be inherited with different type arguments: ''{1}'' and ''{2}''
|
||||
class.inheritance.raw.and.generic=''{0}'' cannot be inherited as a raw type and with generic type arguments ''{1}''
|
||||
class.not.accessible=Cannot access {0}
|
||||
|
||||
class.implicit.no.main.method=Implicitly declared class contains no 'main' method
|
||||
class.implicit.invalid.file.name=Implicitly declared class's file name is not a valid identifier
|
||||
|
||||
+122
-3
@@ -4,14 +4,18 @@ package com.intellij.java.codeserver.highlighting;
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaErrorKinds;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaIncompatibleTypeErrorContext;
|
||||
import com.intellij.openapi.roots.FileIndexFacade;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.IncompleteModelUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.psi.impl.PsiClassImplUtil;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
|
||||
final class GenericsChecker {
|
||||
private final @NotNull JavaErrorVisitor myVisitor;
|
||||
@@ -119,4 +123,119 @@ final class GenericsChecker {
|
||||
myVisitor.report(JavaErrorKinds.REFERENCE_TYPE_NEEDS_TYPE_ARGUMENTS.create(parent));
|
||||
}
|
||||
}
|
||||
|
||||
void checkInterfaceMultipleInheritance(@NotNull PsiClass aClass) {
|
||||
PsiClassType[] types = aClass.getSuperTypes();
|
||||
if (types.length < 2) return;
|
||||
checkInterfaceMultipleInheritance(aClass,
|
||||
aClass,
|
||||
PsiSubstitutor.EMPTY, new HashMap<>(),
|
||||
new HashSet<>());
|
||||
}
|
||||
|
||||
private void checkInterfaceMultipleInheritance(@NotNull PsiClass aClass,
|
||||
@NotNull PsiClass place,
|
||||
@NotNull PsiSubstitutor derivedSubstitutor,
|
||||
@NotNull Map<PsiClass, PsiSubstitutor> inheritedClasses,
|
||||
@NotNull Set<? super PsiClass> visited) {
|
||||
List<PsiClassType.ClassResolveResult> superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, place.getResolveScope());
|
||||
for (PsiClassType.ClassResolveResult result : superTypes) {
|
||||
PsiClass superClass = result.getElement();
|
||||
if (superClass == null || visited.contains(superClass)) continue;
|
||||
PsiSubstitutor superTypeSubstitutor = result.getSubstitutor();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(aClass.getProject());
|
||||
//JLS 4.8 The superclasses (respectively, superinterfaces) of a raw type are the erasures
|
||||
// of the superclasses (superinterfaces) of any of the parameterizations of the generic type.
|
||||
superTypeSubstitutor = PsiUtil.isRawSubstitutor(aClass, derivedSubstitutor)
|
||||
? elementFactory.createRawSubstitutor(superClass)
|
||||
: MethodSignatureUtil.combineSubstitutors(superTypeSubstitutor, derivedSubstitutor);
|
||||
|
||||
PsiSubstitutor inheritedSubstitutor = inheritedClasses.get(superClass);
|
||||
if (inheritedSubstitutor != null) {
|
||||
PsiTypeParameter[] typeParameters = superClass.getTypeParameters();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
PsiType type1 = inheritedSubstitutor.substitute(typeParameter);
|
||||
PsiType type2 = superTypeSubstitutor.substitute(typeParameter);
|
||||
|
||||
if (!Comparing.equal(type1, type2)) {
|
||||
var context = new JavaErrorKinds.InheritTypeClashContext(superClass, type1, type2);
|
||||
if (type1 != null && type2 != null) {
|
||||
myVisitor.report(JavaErrorKinds.CLASS_INHERITANCE_DIFFERENT_TYPE_ARGUMENTS.create(place, context));
|
||||
}
|
||||
else {
|
||||
myVisitor.report(JavaErrorKinds.CLASS_INHERITANCE_RAW_AND_GENERIC.create(place, context));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
inheritedClasses.put(superClass, superTypeSubstitutor);
|
||||
visited.add(superClass);
|
||||
checkInterfaceMultipleInheritance(superClass, place, superTypeSubstitutor, inheritedClasses, visited);
|
||||
visited.remove(superClass);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
}
|
||||
}
|
||||
|
||||
void checkClassSupersAccessibility(@NotNull PsiClass aClass) {
|
||||
checkClassSupersAccessibility(aClass, aClass, aClass.getResolveScope(), true);
|
||||
}
|
||||
|
||||
void checkClassSupersAccessibility(@NotNull PsiClass aClass, @NotNull PsiElement ref, @NotNull GlobalSearchScope scope) {
|
||||
checkClassSupersAccessibility(ref, aClass, scope, false);
|
||||
}
|
||||
|
||||
private void checkClassSupersAccessibility(@NotNull PsiElement anchor,
|
||||
@NotNull PsiClass aClass,
|
||||
@NotNull GlobalSearchScope resolveScope,
|
||||
boolean checkParameters) {
|
||||
JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject());
|
||||
for (PsiClassType superType : aClass.getSuperTypes()) {
|
||||
HashSet<PsiClass> checked = new HashSet<>();
|
||||
checked.add(aClass);
|
||||
checkTypeAccessible(anchor, superType, checked, checkParameters, true, resolveScope, factory);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkTypeAccessible(@NotNull PsiElement anchor,
|
||||
@Nullable PsiType type,
|
||||
@NotNull Set<? super PsiClass> classes,
|
||||
boolean checkParameters,
|
||||
boolean checkSuperTypes,
|
||||
@NotNull GlobalSearchScope resolveScope,
|
||||
@NotNull JavaPsiFacade factory) {
|
||||
type = PsiClassImplUtil.correctType(type, resolveScope);
|
||||
|
||||
PsiClass aClass = PsiUtil.resolveClassInType(type);
|
||||
if (aClass != null && classes.add(aClass)) {
|
||||
VirtualFile vFile = PsiUtilCore.getVirtualFile(aClass);
|
||||
if (vFile == null) return;
|
||||
FileIndexFacade index = FileIndexFacade.getInstance(aClass.getProject());
|
||||
if (!index.isInSource(vFile) && !index.isInLibraryClasses(vFile)) return;
|
||||
|
||||
PsiImplicitClass parentImplicitClass = PsiTreeUtil.getParentOfType(aClass, PsiImplicitClass.class);
|
||||
String qualifiedName = aClass.getQualifiedName();
|
||||
if (parentImplicitClass == null && qualifiedName != null && factory.findClass(qualifiedName, resolveScope) == null) {
|
||||
myVisitor.report(JavaErrorKinds.CLASS_NOT_ACCESSIBLE.create(anchor, aClass));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checkParameters) return;
|
||||
|
||||
if (type instanceof PsiClassType classType) {
|
||||
for (PsiType parameterType : classType.getParameters()) {
|
||||
checkTypeAccessible(anchor, parameterType, classes, true, false, resolveScope, factory);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checkSuperTypes) return;
|
||||
|
||||
boolean isInLibrary = !index.isInContent(vFile);
|
||||
for (PsiClassType superType : aClass.getSuperTypes()) {
|
||||
checkTypeAccessible(anchor, superType, classes, !isInLibrary, true, resolveScope, factory);
|
||||
if (myVisitor.hasErrorResults()) return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-2
@@ -4,6 +4,7 @@ package com.intellij.java.codeserver.highlighting;
|
||||
import com.intellij.java.codeserver.highlighting.errors.JavaCompilationError;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiJavaModule;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -22,8 +23,13 @@ public final class JavaErrorCollector {
|
||||
* @param file Java file to process
|
||||
* @param consumer a consumer to get errors
|
||||
*/
|
||||
public JavaErrorCollector(@NotNull PsiFile file, @NotNull Consumer<@NotNull JavaCompilationError<?, ?>> consumer) {
|
||||
myVisitor = new JavaErrorVisitor(file, consumer);
|
||||
public JavaErrorCollector(@NotNull PsiFile file, @NotNull Consumer<@NotNull JavaCompilationError<?, ?>> consumer) {
|
||||
this(file, null, consumer);
|
||||
}
|
||||
|
||||
public JavaErrorCollector(@NotNull PsiFile file, @Nullable PsiJavaModule module,
|
||||
@NotNull Consumer<@NotNull JavaCompilationError<?, ?>> consumer) {
|
||||
myVisitor = new JavaErrorVisitor(file, module, consumer);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+31
-1
@@ -18,6 +18,7 @@ import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
|
||||
import com.intellij.psi.util.PsiTypesUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -43,13 +44,15 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
final @NotNull ExpressionChecker myExpressionChecker = new ExpressionChecker(this);
|
||||
private final @NotNull StatementChecker myStatementChecker = new StatementChecker(this);
|
||||
private final @NotNull LiteralChecker myLiteralChecker = new LiteralChecker(this);
|
||||
private final @Nullable PsiJavaModule myJavaModule;
|
||||
private boolean myHasError; // true if myHolder.add() was called with HighlightInfo of >=ERROR severity. On each .visit(PsiElement) call this flag is reset. Useful to determine whether the error was already reported while visiting this PsiElement.
|
||||
|
||||
JavaErrorVisitor(@NotNull PsiFile file, @NotNull Consumer<JavaCompilationError<?, ?>> consumer) {
|
||||
JavaErrorVisitor(@NotNull PsiFile file, @Nullable PsiJavaModule module, @NotNull Consumer<JavaCompilationError<?, ?>> consumer) {
|
||||
myFile = file;
|
||||
myProject = file.getProject();
|
||||
myLanguageLevel = PsiUtil.getLanguageLevel(file);
|
||||
myErrorConsumer = consumer;
|
||||
myJavaModule = module;
|
||||
}
|
||||
|
||||
void report(@NotNull JavaCompilationError<?, ?> error) {
|
||||
@@ -335,6 +338,21 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myClassChecker.checkStaticDeclarationInInnerClass(keyword);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitImportStaticStatement(@NotNull PsiImportStaticStatement statement) {
|
||||
checkFeature(statement, JavaFeature.STATIC_IMPORTS);
|
||||
if (!hasErrorResults()) {
|
||||
PsiJavaCodeReferenceElement importReference = statement.getImportReference();
|
||||
PsiClass targetClass = statement.resolveTargetClass();
|
||||
if (importReference != null) {
|
||||
PsiElement referenceNameElement = importReference.getReferenceNameElement();
|
||||
if (referenceNameElement != null && targetClass != null) {
|
||||
myGenericsChecker.checkClassSupersAccessibility(targetClass, referenceNameElement, myFile.getResolveScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClass(@NotNull PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
@@ -345,6 +363,8 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
if (!hasErrorResults()) myClassChecker.checkPublicClassInRightFile(aClass);
|
||||
if (!hasErrorResults()) myClassChecker.checkSealedClassInheritors(aClass);
|
||||
if (!hasErrorResults()) myClassChecker.checkSealedSuper(aClass);
|
||||
if (!hasErrorResults()) myGenericsChecker.checkInterfaceMultipleInheritance(aClass);
|
||||
if (!hasErrorResults()) myGenericsChecker.checkClassSupersAccessibility(aClass);
|
||||
if (!hasErrorResults()) myRecordChecker.checkRecordHeader(aClass);
|
||||
}
|
||||
|
||||
@@ -355,6 +375,16 @@ final class JavaErrorVisitor extends JavaElementVisitor {
|
||||
visitExpression(expression);
|
||||
if (hasErrorResults()) return;
|
||||
}
|
||||
PsiElement parent = expression.getParent();
|
||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
if (!hasErrorResults() && myJavaModule == null && qualifierExpression != null) {
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
PsiClass psiClass = RefactoringChangeUtil.getQualifierClass(expression);
|
||||
if (psiClass != null) {
|
||||
myGenericsChecker.checkClassSupersAccessibility(psiClass, expression, myFile.getResolveScope());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+20
-1
@@ -188,6 +188,7 @@ public final class JavaErrorKinds {
|
||||
.withAnchor(parameter -> requireNonNullElse(parameter.getTypeElement(), parameter)).parameterized();
|
||||
public static final Parameterized<PsiReceiverParameter, @Nullable String> RECEIVER_NAME_MISMATCH =
|
||||
error(PsiReceiverParameter.class, "receiver.name.mismatch").withAnchor(PsiReceiverParameter::getIdentifier).parameterized();
|
||||
|
||||
// PsiMember = PsiClass | PsiEnumConstant
|
||||
public static final Parameterized<PsiMember, PsiMethod> CLASS_NO_ABSTRACT_METHOD =
|
||||
error(PsiMember.class, "class.must.implement.method")
|
||||
@@ -293,7 +294,23 @@ public final class JavaErrorKinds {
|
||||
.withRawDescription((psi, ctx) -> message(
|
||||
"class.cannot.be.referenced.from.static.context",
|
||||
formatClass(ctx.outerClass()) + "." + (psi instanceof PsiSuperExpression ? PsiKeyword.SUPER : PsiKeyword.THIS)));
|
||||
|
||||
public static final Parameterized<PsiClass, InheritTypeClashContext> CLASS_INHERITANCE_DIFFERENT_TYPE_ARGUMENTS =
|
||||
parameterized(PsiClass.class, InheritTypeClashContext.class, "class.inheritance.different.type.arguments")
|
||||
.withRange((cls, ctx) -> getClassDeclarationTextRange(cls))
|
||||
.withRawDescription((cls, ctx) -> message("class.inheritance.different.type.arguments",
|
||||
formatClass(ctx.superClass()),
|
||||
formatType(ctx.type1()),
|
||||
formatType(ctx.type2())));
|
||||
public static final Parameterized<PsiClass, InheritTypeClashContext> CLASS_INHERITANCE_RAW_AND_GENERIC =
|
||||
parameterized(PsiClass.class, InheritTypeClashContext.class, "class.inheritance.raw.and.generic")
|
||||
.withRange((cls, ctx) -> getClassDeclarationTextRange(cls))
|
||||
.withRawDescription((cls, ctx) -> message("class.inheritance.raw.and.generic",
|
||||
formatClass(ctx.superClass()),
|
||||
formatType(ctx.type1() != null ? ctx.type1() : ctx.type2())));
|
||||
public static final Parameterized<PsiElement, PsiClass> CLASS_NOT_ACCESSIBLE =
|
||||
parameterized(PsiElement.class, PsiClass.class, "class.not.accessible")
|
||||
.withRange((psi, cls) -> psi instanceof PsiMember member ? getMemberDeclarationTextRange(member) : null)
|
||||
.withRawDescription((psi, cls) -> message("class.not.accessible", formatClass(cls)));
|
||||
|
||||
public static final Simple<PsiJavaCodeReferenceElement> VALUE_CLASS_EXTENDS_NON_ABSTRACT = error("value.class.extends.non.abstract");
|
||||
|
||||
@@ -625,6 +642,8 @@ public final class JavaErrorKinds {
|
||||
|
||||
public record OverrideClashContext(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
|
||||
}
|
||||
|
||||
public record InheritTypeClashContext(@NotNull PsiClass superClass, @Nullable PsiType type1, @Nullable PsiType type2) {}
|
||||
|
||||
public record IncompatibleOverrideReturnTypeContext(@NotNull PsiMethod method,
|
||||
@NotNull PsiType methodReturnType,
|
||||
|
||||
-86
@@ -315,66 +315,6 @@ public final class GenericsHighlightUtil {
|
||||
}
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkInterfaceMultipleInheritance(@NotNull PsiClass aClass) {
|
||||
PsiClassType[] types = aClass.getSuperTypes();
|
||||
if (types.length < 2) return null;
|
||||
TextRange textRange = HighlightNamesUtil.getClassDeclarationTextRange(aClass);
|
||||
return checkInterfaceMultipleInheritance(aClass,
|
||||
aClass,
|
||||
PsiSubstitutor.EMPTY, new HashMap<>(),
|
||||
new HashSet<>(), textRange);
|
||||
}
|
||||
|
||||
private static HighlightInfo.Builder checkInterfaceMultipleInheritance(@NotNull PsiClass aClass,
|
||||
@NotNull PsiElement place,
|
||||
@NotNull PsiSubstitutor derivedSubstitutor,
|
||||
@NotNull Map<PsiClass, PsiSubstitutor> inheritedClasses,
|
||||
@NotNull Set<? super PsiClass> visited,
|
||||
@NotNull TextRange textRange) {
|
||||
List<PsiClassType.ClassResolveResult> superTypes = PsiClassImplUtil.getScopeCorrectedSuperTypes(aClass, place.getResolveScope());
|
||||
for (PsiClassType.ClassResolveResult result : superTypes) {
|
||||
PsiClass superClass = result.getElement();
|
||||
if (superClass == null || visited.contains(superClass)) continue;
|
||||
PsiSubstitutor superTypeSubstitutor = result.getSubstitutor();
|
||||
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(aClass.getProject());
|
||||
//JLS 4.8 The superclasses (respectively, superinterfaces) of a raw type are the erasures of the superclasses (superinterfaces) of any of the parameterizations of the generic type.
|
||||
superTypeSubstitutor = PsiUtil.isRawSubstitutor(aClass, derivedSubstitutor) ? elementFactory.createRawSubstitutor(superClass)
|
||||
: MethodSignatureUtil.combineSubstitutors(superTypeSubstitutor, derivedSubstitutor);
|
||||
|
||||
PsiSubstitutor inheritedSubstitutor = inheritedClasses.get(superClass);
|
||||
if (inheritedSubstitutor != null) {
|
||||
PsiTypeParameter[] typeParameters = superClass.getTypeParameters();
|
||||
for (PsiTypeParameter typeParameter : typeParameters) {
|
||||
PsiType type1 = inheritedSubstitutor.substitute(typeParameter);
|
||||
PsiType type2 = superTypeSubstitutor.substitute(typeParameter);
|
||||
|
||||
if (!Comparing.equal(type1, type2)) {
|
||||
String description;
|
||||
if (type1 != null && type2 != null) {
|
||||
description = JavaErrorBundle.message("generics.cannot.be.inherited.with.different.type.arguments",
|
||||
HighlightUtil.formatClass(superClass),
|
||||
JavaHighlightUtil.formatType(type1),
|
||||
JavaHighlightUtil.formatType(type2));
|
||||
}
|
||||
else {
|
||||
description = JavaErrorBundle.message("generics.cannot.be.inherited.as.raw.and.generic",
|
||||
HighlightUtil.formatClass(superClass),
|
||||
JavaHighlightUtil.formatType(type1 != null ? type1 : type2));
|
||||
}
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
inheritedClasses.put(superClass, superTypeSubstitutor);
|
||||
visited.add(superClass);
|
||||
HighlightInfo.Builder builder = checkInterfaceMultipleInheritance(superClass, place, superTypeSubstitutor, inheritedClasses, visited, textRange);
|
||||
visited.remove(superClass);
|
||||
|
||||
if (builder != null) return builder;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static void computeOverrideEquivalentMethodErrors(@NotNull PsiClass aClass,
|
||||
@NotNull Set<? super PsiClass> overrideEquivalentMethodsVisitedClasses,
|
||||
@NotNull Map<PsiMember, HighlightInfo.Builder> overrideEquivalentMethodsErrors) {
|
||||
@@ -1189,32 +1129,6 @@ public final class GenericsHighlightUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkClassSupersAccessibility(@NotNull PsiClass aClass) {
|
||||
HighlightInfo.Builder builder = checkClassSupersAccessibility(aClass, aClass.getResolveScope(), true);
|
||||
return builder == null ? null : builder.range(HighlightNamesUtil.getClassDeclarationTextRange(aClass));
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkClassSupersAccessibility(@NotNull PsiClass aClass, @NotNull PsiElement ref, @NotNull GlobalSearchScope scope) {
|
||||
HighlightInfo.Builder builder = checkClassSupersAccessibility(aClass, scope, false);
|
||||
return builder == null ? null : builder.range(ref.getTextRange());
|
||||
}
|
||||
|
||||
private static HighlightInfo.Builder checkClassSupersAccessibility(@NotNull PsiClass aClass,
|
||||
@NotNull GlobalSearchScope resolveScope,
|
||||
boolean checkParameters) {
|
||||
JavaPsiFacade factory = JavaPsiFacade.getInstance(aClass.getProject());
|
||||
for (PsiClassType superType : aClass.getSuperTypes()) {
|
||||
HashSet<PsiClass> checked = new HashSet<>();
|
||||
checked.add(aClass);
|
||||
String notAccessibleErrorMessage = isTypeAccessible(superType, checked, checkParameters, true, resolveScope, factory);
|
||||
if (notAccessibleErrorMessage != null) {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.descriptionAndTooltip(notAccessibleErrorMessage);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static HighlightInfo.Builder checkMemberSignatureTypesAccessibility(@NotNull PsiReferenceExpression ref) {
|
||||
String message = null;
|
||||
|
||||
|
||||
+4
-27
@@ -44,7 +44,6 @@ 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.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.ui.NewUI;
|
||||
import com.intellij.util.JavaPsiConstructorUtil;
|
||||
@@ -221,7 +220,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
myJavaModule = JavaFeature.MODULES.isSufficient(myLanguageLevel) ? JavaModuleGraphUtil.findDescriptorByElement(file) : null;
|
||||
myPreviewFeatureVisitor = myLanguageLevel.isPreview() ? null : new PreviewFeatureUtil.PreviewFeatureVisitor(myLanguageLevel, myErrorSink);
|
||||
JavaErrorFixProvider errorFixProvider = JavaErrorFixProvider.getInstance();
|
||||
myCollector = new JavaErrorCollector(myFile, error -> reportError(error, errorFixProvider));
|
||||
myCollector = new JavaErrorCollector(myFile, myJavaModule, error -> reportError(error, errorFixProvider));
|
||||
}
|
||||
|
||||
private void reportError(JavaCompilationError<?, ?> error, JavaErrorFixProvider errorFixProvider) {
|
||||
@@ -458,8 +457,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
public void visitClass(@NotNull PsiClass aClass) {
|
||||
super.visitClass(aClass);
|
||||
if (aClass instanceof PsiSyntheticClass) return;
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkInterfaceMultipleInheritance(aClass));
|
||||
if (!hasErrorResults()) add(GenericsHighlightUtil.checkClassSupersAccessibility(aClass));
|
||||
if (!hasErrorResults()) add(HighlightUtil.checkImplicitThisReferenceBeforeSuper(aClass, myJavaSdkVersion));
|
||||
if (!hasErrorResults()) GenericsHighlightUtil.checkTypeParameterOverrideEquivalentMethods(aClass, myLanguageLevel, myErrorSink, myOverrideEquivalentMethodsVisitedClasses, myOverrideEquivalentMethodsErrors);
|
||||
}
|
||||
@@ -619,21 +616,9 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
|
||||
@Override
|
||||
public void visitImportStaticStatement(@NotNull PsiImportStaticStatement statement) {
|
||||
add(checkFeature(statement, JavaFeature.STATIC_IMPORTS));
|
||||
visitElement(statement);
|
||||
if (!hasErrorResults()) add(ImportsHighlightUtil.checkStaticOnDemandImportResolvesToClass(statement));
|
||||
if (!hasErrorResults()) {
|
||||
PsiJavaCodeReferenceElement importReference = statement.getImportReference();
|
||||
PsiClass targetClass = statement.resolveTargetClass();
|
||||
if (importReference != null) {
|
||||
PsiElement referenceNameElement = importReference.getReferenceNameElement();
|
||||
if (referenceNameElement != null && targetClass != null) {
|
||||
add(GenericsHighlightUtil.checkClassSupersAccessibility(targetClass, referenceNameElement, myFile.getResolveScope()));
|
||||
}
|
||||
}
|
||||
if (!hasErrorResults()) {
|
||||
PreviewFeatureUtil.checkPreviewFeature(statement, myPreviewFeatureVisitor);
|
||||
}
|
||||
}
|
||||
if (!hasErrorResults()) PreviewFeatureUtil.checkPreviewFeature(statement, myPreviewFeatureVisitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1172,15 +1157,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
PsiExpression qualifierExpression = expression.getQualifierExpression();
|
||||
add(HighlightUtil.checkUnqualifiedSuperInDefaultMethod(myLanguageLevel, expression, qualifierExpression));
|
||||
if (!hasErrorResults() && myJavaModule == null && qualifierExpression != null) {
|
||||
if (parent instanceof PsiMethodCallExpression) {
|
||||
PsiClass psiClass = RefactoringChangeUtil.getQualifierClass(expression);
|
||||
if (psiClass != null) {
|
||||
add(GenericsHighlightUtil.checkClassSupersAccessibility(psiClass, expression, myFile.getResolveScope()));
|
||||
}
|
||||
}
|
||||
if (!hasErrorResults()) {
|
||||
add(GenericsHighlightUtil.checkMemberSignatureTypesAccessibility(expression));
|
||||
}
|
||||
add(GenericsHighlightUtil.checkMemberSignatureTypesAccessibility(expression));
|
||||
}
|
||||
if (!hasErrorResults() && resolved instanceof PsiModifierListOwner) {
|
||||
PreviewFeatureUtil.checkPreviewFeature(expression, myPreviewFeatureVisitor);
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import static p.<error descr="Cannot access p.BaseClass">ChildClass</error>.*;
|
||||
|
||||
class Sample {
|
||||
public static void main(String[] args) {
|
||||
ChildClass.<error descr="Cannot resolve method 'foo' in 'ChildClass'">foo</error>();
|
||||
<error descr="Cannot access p.BaseClass">ChildClass.foo</error>();
|
||||
foo();
|
||||
ChildClass cc = ChildClass2.childClass();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user