in nullaway/src/main/java/com/uber/nullaway/NullAway.java [1606:1650]
private void checkNullableAnnotationPositionInType(
List<? extends AnnotationTree> annotations, Tree type, VisitorState state) {
// Early return if the type is not a nested or inner class reference.
if (!(type instanceof MemberSelectTree)) {
return;
}
// Get the end position of the outer type expression. Any nullable annotation before this
// position is considered to be on the outer type, which is incorrect.
int endOfOuterType = state.getEndPosition(((MemberSelectTree) type).getExpression());
int startOfType = ((JCTree) type).getStartPosition();
for (AnnotationTree annotation : annotations) {
Symbol sym = ASTHelpers.getSymbol(annotation);
if (sym == null) {
continue;
}
String qualifiedName = sym.getQualifiedName().toString();
if (!isNullableAnnotation(qualifiedName, config)) {
continue;
}
if (!isTypeUseAnnotation(sym)) {
continue;
}
// If an annotation is declaration ALSO, we check if it is at the correct location. If it is,
// we treat it as declaration and skip the checks.
if (isDeclarationAnnotation(sym) && state.getEndPosition(annotation) <= startOfType) {
continue;
}
if (state.getEndPosition(annotation) < endOfOuterType) {
// annotation is not on the inner-most type
ErrorMessage errorMessage =
new ErrorMessage(
MessageTypes.NULLABLE_ON_WRONG_NESTED_CLASS_LEVEL,
"Type-use nullability annotations should be applied on inner class");
state.reportMatch(
errorBuilder.createErrorDescription(errorMessage, buildDescription(type), state, null));
}
}
}