public void checkTypeParameterNullnessForAssignability()

in nullaway/src/main/java/com/uber/nullaway/generics/GenericsChecks.java [752:795]


  public void checkTypeParameterNullnessForAssignability(Tree tree, VisitorState state) {
    Config config = analysis.getConfig();
    if (!config.isJSpecifyMode()) {
      return;
    }
    Type lhsType = getTreeType(tree, state);
    if (lhsType == null) {
      return;
    }
    ExpressionTree rhsTree;
    boolean assignedToLocal;
    if (tree instanceof VariableTree varTree) {
      rhsTree = varTree.getInitializer();
      assignedToLocal = isAssignmentToLocalVariable(varTree);
    } else if (tree instanceof AssignmentTree assignmentTree) {
      rhsTree = assignmentTree.getExpression();
      assignedToLocal = isAssignmentToLocalVariable(assignmentTree);
    } else {
      throw new RuntimeException("Unexpected tree type: " + tree.getKind());
    }
    // rhsTree can be null for a VariableTree.  Also, we don't need to do a check
    // if rhsTree is the null literal
    if (rhsTree == null || rhsTree.getKind().equals(Tree.Kind.NULL_LITERAL)) {
      return;
    }
    if (!assignedToLocal
        && (rhsTree instanceof LambdaExpressionTree || rhsTree instanceof MemberReferenceTree)
        && isAssignmentToField(tree)) {
      maybeStorePolyExpressionTypeFromTarget(rhsTree, lhsType);
    }
    TreePath pathToRhs = new TreePath(state.getPath(), rhsTree);
    Type rhsType = getTreeType(rhsTree, state.withPath(pathToRhs));
    if (rhsType != null) {
      if (isGenericCallNeedingInference(rhsTree)) {
        rhsType =
            inferGenericMethodCallType(
                state, (MethodInvocationTree) rhsTree, null, lhsType, assignedToLocal, false);
      }
      boolean isAssignmentValid = subtypeParameterNullability(lhsType, rhsType, state);
      if (!isAssignmentValid) {
        reportInvalidAssignmentInstantiationError(tree, lhsType, rhsType, state);
      }
    }
  }