When APT compiles a source code that refers to a non-existent annotation, such as:
@NoSuchAnnotation
class A {}
APT correctly reports an error:
Test.java:1: cannot find symbol
symbol : class NoSuchAnnotation
location: class A
@NoSuchAnnotation
^
but then it nevertheless lets annotation processors a chance to introspect this class A.
When our annotation processor does:
for( AnnotationMirror m : decl.getAnnotationMirrors() ) {
AnnotationType at = m.getAnnotationType();
...
}
It causes a ClassCastException as follows:
java.lang.ClassCastException: com.sun.tools.apt.mirror.type.ClassTypeImpl
at com.sun.tools.apt.mirror.declaration.AnnotationMirrorImpl.getAnnotationType(AnnotationMirrorImpl.java:82)
which is at the following line:
public AnnotationType getAnnotationType() {
return (AnnotationType) env.typeMaker.getType(anno.type);
}
... presumably because typeMaker returns a token that designates an error, which doesn't implement AnnotationType.
A few observations:
1. if a special TypeMirror that represents an error is used (which is a common technique so that the caller can avoid constantly checking against error conditions), then it should implement all TypeMirror subtypes, so that it can be used everywhere.
2. Alternatively, return null from the getAnnotationType(). In a few other parts of the APT API, null is returned for errors, so that seems to be in alignment with the rest. I find it unfortunate that I have to check null all the time in so many places, which makes my annotation processor looks like some C program.
3. For the purpose of my annotation processor, it's acceptable not to process anything at all and abort right away if there's any compilation error in the source code. It would be great if AnnotationProcessorEnvironment can make that information available to me.
@NoSuchAnnotation
class A {}
APT correctly reports an error:
Test.java:1: cannot find symbol
symbol : class NoSuchAnnotation
location: class A
@NoSuchAnnotation
^
but then it nevertheless lets annotation processors a chance to introspect this class A.
When our annotation processor does:
for( AnnotationMirror m : decl.getAnnotationMirrors() ) {
AnnotationType at = m.getAnnotationType();
...
}
It causes a ClassCastException as follows:
java.lang.ClassCastException: com.sun.tools.apt.mirror.type.ClassTypeImpl
at com.sun.tools.apt.mirror.declaration.AnnotationMirrorImpl.getAnnotationType(AnnotationMirrorImpl.java:82)
which is at the following line:
public AnnotationType getAnnotationType() {
return (AnnotationType) env.typeMaker.getType(anno.type);
}
... presumably because typeMaker returns a token that designates an error, which doesn't implement AnnotationType.
A few observations:
1. if a special TypeMirror that represents an error is used (which is a common technique so that the caller can avoid constantly checking against error conditions), then it should implement all TypeMirror subtypes, so that it can be used everywhere.
2. Alternatively, return null from the getAnnotationType(). In a few other parts of the APT API, null is returned for errors, so that seems to be in alignment with the rest. I find it unfortunate that I have to check null all the time in so many places, which makes my annotation processor looks like some C program.
3. For the purpose of my annotation processor, it's acceptable not to process anything at all and abort right away if there's any compilation error in the source code. It would be great if AnnotationProcessorEnvironment can make that information available to me.
- relates to
-
JDK-4991798 need some indications of errors/warnings when running -nocompile
- Closed
-
JDK-6403465 javac should defer diagnostics until it can be determined they are persistent
- Closed
-
JDK-6381698 Warn of decommissioning of apt
- Closed
-
JDK-5052910 need option to turn javac errors into apt errors
- Closed