private static MapKey argumentToMapKeySpecifier()

in nullaway/src/main/java/com/uber/nullaway/dataflow/AccessPath.java [273:303]


  private static MapKey argumentToMapKeySpecifier(
      Node argument, VisitorState state, AccessPathContext apContext) {
    // Required to have Node type match Tree type in some instances.
    if (argument instanceof WideningConversionNode) {
      argument = ((WideningConversionNode) argument).getOperand();
    }
    // A switch at the Tree level should be faster than multiple if checks at the Node level.
    switch (castToNonNull(argument.getTree()).getKind()) {
      case STRING_LITERAL:
        return new StringMapKey(((StringLiteralNode) argument).getValue());
      case INT_LITERAL:
        return new NumericMapKey(((IntegerLiteralNode) argument).getValue());
      case LONG_LITERAL:
        return new NumericMapKey(((LongLiteralNode) argument).getValue());
      case METHOD_INVOCATION:
        MethodAccessNode target = ((MethodInvocationNode) argument).getTarget();
        Node receiver = stripCasts(target.getReceiver());
        List<Node> arguments = ((MethodInvocationNode) argument).getArguments();
        // Check for int/long boxing.
        if (target.getMethod().getSimpleName().toString().equals("valueOf")
            && arguments.size() == 1
            && castToNonNull(receiver.getTree()).getKind().equals(Tree.Kind.IDENTIFIER)
            && (receiver.toString().equals("Integer") || receiver.toString().equals("Long"))) {
          return argumentToMapKeySpecifier(arguments.get(0), state, apContext);
        }
        // Fine to fallthrough:
      default:
        // Every other type of expression, including variables, field accesses, new A(...), etc.
        return getAccessPathForNode(argument, state, apContext); // Every AP is a MapKey too
    }
  }