mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
accessibility check for annotation parameters: treat parameters as they are outside the class (IDEA-165904)
This commit is contained in:
-49
@@ -445,55 +445,6 @@ public class AnnotationsHighlightUtil {
|
||||
return ref;
|
||||
}
|
||||
|
||||
static HighlightInfo checkForeignInnerClassesUsed(final PsiAnnotation annotation) {
|
||||
final HighlightInfo[] infos = new HighlightInfo[1];
|
||||
final PsiAnnotationOwner owner = annotation.getOwner();
|
||||
if (owner instanceof PsiModifierList) {
|
||||
final PsiElement parent = ((PsiModifierList)owner).getParent();
|
||||
if (parent instanceof PsiClass) {
|
||||
annotation.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
if (infos[0] != null) return;
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) {
|
||||
super.visitClassObjectAccessExpression(expression);
|
||||
final PsiTypeElement operand = expression.getOperand();
|
||||
final PsiClass classType = PsiUtil.resolveClassInType(operand.getType());
|
||||
if (classType != null) {
|
||||
checkAccessibility(operand.getInnermostComponentReferenceElement(), classType, HighlightUtil.formatClass(classType));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitReferenceExpression(PsiReferenceExpression expression) {
|
||||
super.visitReferenceExpression(expression);
|
||||
final PsiElement resolve = expression.resolve();
|
||||
if (resolve instanceof PsiField) {
|
||||
checkAccessibility(expression, (PsiMember)resolve, HighlightUtil.formatField((PsiField)resolve));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAccessibility(PsiJavaCodeReferenceElement expression, PsiMember resolve, String memberString) {
|
||||
if (resolve.hasModifierProperty(PsiModifier.PRIVATE) &&
|
||||
PsiTreeUtil.isAncestor(parent, resolve, true)) {
|
||||
String description = JavaErrorMessages.message("private.symbol",
|
||||
memberString,
|
||||
HighlightUtil.formatClass((PsiClass)parent));
|
||||
infos[0] =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
|
||||
HighlightUtil.registerAccessQuickFixAction(resolve, expression, infos[0], null);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return infos[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkAnnotationType(PsiAnnotation annotation) {
|
||||
PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
|
||||
|
||||
-1
@@ -241,7 +241,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkMissingAttributes(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkTargetAnnotationDuplicates(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkDuplicateAnnotations(annotation, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkForeignInnerClassesUsed(annotation));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkFunctionalInterface(annotation, myLanguageLevel));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(AnnotationsHighlightUtil.checkRepeatableAnnotation(annotation));
|
||||
if (CommonClassNames.JAVA_LANG_OVERRIDE.equals(annotation.getQualifiedName())) {
|
||||
|
||||
@@ -122,9 +122,15 @@ public class JavaResolveUtil {
|
||||
if (memberClass == null) {
|
||||
return false;
|
||||
}
|
||||
// if resolving supertype reference, skip its containing class with getContextClass
|
||||
PsiClass contextClass = member instanceof PsiClass ? getContextClass(place)
|
||||
: PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
|
||||
PsiClass contextClass;
|
||||
if (member instanceof PsiClass) {
|
||||
// if resolving supertype reference, skip its containing class with getContextClass
|
||||
contextClass = getContextClass(place);
|
||||
}
|
||||
else {
|
||||
contextClass = PsiTreeUtil.getContextOfType(place, PsiClass.class, false);
|
||||
if (isInClassAnnotationParameterList(place, contextClass)) return false;
|
||||
}
|
||||
while (contextClass != null) {
|
||||
if (InheritanceUtil.isInheritorOrSelf(contextClass, memberClass, true)) {
|
||||
if (member instanceof PsiClass ||
|
||||
@@ -156,7 +162,8 @@ public class JavaResolveUtil {
|
||||
if (fileResolveScope == null) {
|
||||
PsiClass placeTopLevelClass = getTopLevelClass(place, null);
|
||||
PsiClass memberTopLevelClass = getTopLevelClass(memberClass, null);
|
||||
return manager.areElementsEquivalent(placeTopLevelClass, memberTopLevelClass);
|
||||
return manager.areElementsEquivalent(placeTopLevelClass, memberTopLevelClass) &&
|
||||
!isInClassAnnotationParameterList(place, PsiTreeUtil.getContextOfType(place, PsiClass.class, false));
|
||||
}
|
||||
else {
|
||||
return fileResolveScope instanceof PsiClass &&
|
||||
@@ -186,6 +193,16 @@ public class JavaResolveUtil {
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean isInClassAnnotationParameterList(@NotNull PsiElement place, @Nullable PsiClass contextClass) {
|
||||
if (contextClass != null) {
|
||||
PsiAnnotation annotation = PsiTreeUtil.getContextOfType(place, PsiAnnotation.class, true);
|
||||
if (annotation != null && contextClass.getModifierList() == annotation.getOwner()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean ignoreReferencedElementAccessibility(PsiFile placeFile) {
|
||||
return placeFile instanceof FileResolveScopeProvider &&
|
||||
((FileResolveScopeProvider) placeFile).ignoreReferencedElementAccessibility() &&
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
import a.A;
|
||||
|
||||
@SuppressWarnings(A.<error descr="'A_FOO' has protected access in 'a.A'">A_FOO</error>)
|
||||
class B extends A {}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@SomeAnnotation(<error descr="'Foo.Bar' has private access in 'Foo'">Foo.Bar</error>.class)
|
||||
@SomeAnnotation(Foo.<error descr="'Foo.Bar' has private access in 'Foo'">Bar</error>.class)
|
||||
public class Foo{
|
||||
private static class Bar {
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@SuppressWarnings(<error descr="'ThisClass.FOO' has private access in 'ThisClass'">ThisClass.FOO</error>)
|
||||
@SuppressWarnings(ThisClass.<error descr="'FOO' has private access in 'ThisClass'">FOO</error>)
|
||||
public class ThisClass {
|
||||
private static final String FOO = "foo";
|
||||
}
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
@FooAnnotation(<error descr="'Foo.BAR' has private access in 'Foo'">Foo.BAR</error>)
|
||||
@FooAnnotation(Foo.<error descr="'BAR' has private access in 'Foo'">BAR</error>)
|
||||
class Foo {
|
||||
private static final String BAR = "bar";
|
||||
}
|
||||
|
||||
+6
@@ -99,6 +99,12 @@ public class LightAdvHighlightingFixtureTest extends LightCodeInsightFixtureTest
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
public void testProtectedFieldUsedInAnnotationParameterOfInheritor() throws Exception {
|
||||
myFixture.addClass("package a; public class A {protected final static String A_FOO = \"A\";}");
|
||||
myFixture.configureByFile(getTestName(false) + ".java");
|
||||
myFixture.checkHighlighting();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/advFixture";
|
||||
|
||||
Reference in New Issue
Block a user