private void checkNullableAnnotationPositionInType()

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));
      }
    }
  }