mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IDEA-58158 (check when annotation parameter value must be .class)
This commit is contained in:
+20
-12
@@ -70,6 +70,7 @@ public class AnnotationsHighlightUtil {
|
||||
}
|
||||
else {
|
||||
PsiType returnType = method.getReturnType();
|
||||
assert returnType != null : method;
|
||||
PsiAnnotationMemberValue value = pair.getValue();
|
||||
HighlightInfo info = checkMemberValueType(value, returnType);
|
||||
if (info != null) return info;
|
||||
@@ -84,11 +85,10 @@ public class AnnotationsHighlightUtil {
|
||||
PsiNameValuePair[] attributes = annotation.getAttributes();
|
||||
for (PsiNameValuePair attribute : attributes) {
|
||||
if (attribute == pair) break;
|
||||
if (Comparing.equal(attribute.getName(), pair.getName())) {
|
||||
String name = pair.getName();
|
||||
if (Comparing.equal(attribute.getName(), name)) {
|
||||
String description = JavaErrorMessages.message("annotation.duplicate.attribute",
|
||||
pair.getName() == null
|
||||
? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME
|
||||
: pair.getName());
|
||||
name == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : name);
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, pair, description);
|
||||
}
|
||||
}
|
||||
@@ -101,28 +101,35 @@ public class AnnotationsHighlightUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static HighlightInfo checkMemberValueType(PsiAnnotationMemberValue value, PsiType expectedType) {
|
||||
public static HighlightInfo checkMemberValueType(@Nullable PsiAnnotationMemberValue value, PsiType expectedType) {
|
||||
if (value == null) return null;
|
||||
|
||||
if (expectedType instanceof PsiClassType && expectedType.equalsToText(CommonClassNames.JAVA_LANG_CLASS)) {
|
||||
if (!(value instanceof PsiClassObjectAccessExpression)) {
|
||||
String description = JavaErrorMessages.message("annotation.non.class.literal.attribute.value");
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, value, description);
|
||||
}
|
||||
}
|
||||
|
||||
if (value instanceof PsiAnnotation) {
|
||||
PsiJavaCodeReferenceElement nameRef = ((PsiAnnotation)value).getNameReferenceElement();
|
||||
if (nameRef == null) return null;
|
||||
|
||||
if (expectedType instanceof PsiClassType) {
|
||||
PsiClass aClass = ((PsiClassType)expectedType).resolve();
|
||||
if (nameRef.isReferenceTo(aClass)) return null;
|
||||
if (aClass != null && nameRef.isReferenceTo(aClass)) return null;
|
||||
}
|
||||
|
||||
if (expectedType instanceof PsiArrayType) {
|
||||
PsiType componentType = ((PsiArrayType)expectedType).getComponentType();
|
||||
if (componentType instanceof PsiClassType) {
|
||||
PsiClass aClass = ((PsiClassType)componentType).resolve();
|
||||
if (nameRef.isReferenceTo(aClass)) return null;
|
||||
if (aClass != null && nameRef.isReferenceTo(aClass)) return null;
|
||||
}
|
||||
}
|
||||
|
||||
String description = JavaErrorMessages.message("annotation.incompatible.types",
|
||||
formatReference(nameRef),
|
||||
HighlightUtil.formatType(expectedType));
|
||||
|
||||
formatReference(nameRef), HighlightUtil.formatType(expectedType));
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, value, description);
|
||||
}
|
||||
else if (value instanceof PsiArrayInitializerMemberValue) {
|
||||
@@ -134,7 +141,8 @@ public class AnnotationsHighlightUtil {
|
||||
PsiExpression expr = (PsiExpression)value;
|
||||
PsiType type = expr.getType();
|
||||
if (type != null && TypeConversionUtil.areTypesAssignmentCompatible(expectedType, expr) ||
|
||||
expectedType instanceof PsiArrayType && TypeConversionUtil.areTypesAssignmentCompatible(((PsiArrayType)expectedType).getComponentType(), expr)) {
|
||||
expectedType instanceof PsiArrayType &&
|
||||
TypeConversionUtil.areTypesAssignmentCompatible(((PsiArrayType)expectedType).getComponentType(), expr)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -143,7 +151,7 @@ public class AnnotationsHighlightUtil {
|
||||
return HighlightInfo.createHighlightInfo(HighlightInfoType.ERROR, value, description);
|
||||
}
|
||||
|
||||
LOG.error("Unknown annotation member value: "+value);
|
||||
LOG.error("Unknown annotation member value: " + value);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ annotation.duplicate.attribute=Duplicate attribute ''{0}''
|
||||
annotation.missing.attribute={0} missing though required
|
||||
annotation.not.applicable=''@{0}'' not applicable to {1}
|
||||
annotation.non.constant.attribute.value=Attribute value must be constant
|
||||
annotation.non.class.literal.attribute.value=Attribute value must be a class literal
|
||||
annotation.invalid.annotation.member.type=Invalid type for annotation member
|
||||
annotation.cyclic.element.type=Cyclic annotation element type
|
||||
annotation.annotation.type.expected=Annotation type expected
|
||||
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
@interface Ann {
|
||||
Class type();
|
||||
}
|
||||
|
||||
class C {
|
||||
private static final Class<C> THIS_TYPE = C.class;
|
||||
|
||||
@Ann(type = <error descr="Attribute value must be a class literal">THIS_TYPE</error>)
|
||||
void bad() { }
|
||||
|
||||
@Ann(type = C.class)
|
||||
void good() { }
|
||||
}
|
||||
+1
@@ -35,6 +35,7 @@ public class AnnotationsHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testIncompatibleType2() { doTest(false); }
|
||||
public void testIncompatibleType3() { doTest(false); }
|
||||
public void testIncompatibleType4() { doTest(false); }
|
||||
public void testIncompatibleType5() { doTest(false); }
|
||||
public void testMissingAttribute() { doTest(false); }
|
||||
public void testDuplicateAnnotation() { doTest(false); }
|
||||
public void testNonConstantInitializer() { doTest(false); }
|
||||
|
||||
Reference in New Issue
Block a user