Lookup the method that a method_invocation node resolves to. Returns * NULL if the receiver type is unknown. Used by bind_lambda_args / * bind_method_ref_args before re-walking arguments — we need the resolved * method to know the SAM-typed parameter slot. */
| 2736 | * bind_method_ref_args before re-walking arguments — we need the resolved |
| 2737 | * method to know the SAM-typed parameter slot. */ |
| 2738 | static const CBMRegisteredFunc *lookup_method_for_call(JavaLSPContext *ctx, TSNode call, |
| 2739 | const CBMType **out_recv_type) { |
| 2740 | if (out_recv_type) |
| 2741 | *out_recv_type = NULL; |
| 2742 | TSNode obj = ts_node_child_by_field_name(call, "object", 6); |
| 2743 | TSNode name_node = ts_node_child_by_field_name(call, "name", 4); |
| 2744 | if (ts_node_is_null(name_node)) |
| 2745 | return NULL; |
| 2746 | char *mname = java_node_text(ctx, name_node); |
| 2747 | if (!mname) |
| 2748 | return NULL; |
| 2749 | int arity = count_call_args(call); |
| 2750 | |
| 2751 | if (ts_node_is_null(obj)) { |
| 2752 | if (ctx->enclosing_class_qn) { |
| 2753 | return java_lookup_method(ctx, ctx->enclosing_class_qn, mname, arity); |
| 2754 | } |
| 2755 | return NULL; |
| 2756 | } |
| 2757 | if (strcmp(ts_node_type(obj), "super") == 0) { |
| 2758 | const char *sq = ctx->enclosing_super_qn ? ctx->enclosing_super_qn : "java.lang.Object"; |
| 2759 | return java_lookup_method(ctx, sq, mname, arity); |
| 2760 | } |
| 2761 | if (strcmp(ts_node_type(obj), "this") == 0) { |
| 2762 | if (ctx->enclosing_class_qn) { |
| 2763 | return java_lookup_method(ctx, ctx->enclosing_class_qn, mname, arity); |
| 2764 | } |
| 2765 | return NULL; |
| 2766 | } |
| 2767 | /* Static call via class name. */ |
| 2768 | if (strcmp(ts_node_type(obj), "identifier") == 0) { |
| 2769 | char *oname = java_node_text(ctx, obj); |
| 2770 | if (oname && cbm_type_is_unknown(cbm_scope_lookup(ctx->current_scope, oname))) { |
| 2771 | const char *cls_qn = java_resolve_type_name(ctx, oname); |
| 2772 | if (cls_qn) { |
| 2773 | const CBMRegisteredFunc *f = java_lookup_method(ctx, cls_qn, mname, arity); |
| 2774 | if (f) |
| 2775 | return f; |
| 2776 | } |
| 2777 | } |
| 2778 | } |
| 2779 | /* Instance dispatch. */ |
| 2780 | const CBMType *recv = java_eval_expr_type(ctx, obj); |
| 2781 | if (out_recv_type) |
| 2782 | *out_recv_type = recv; |
| 2783 | const char *recv_qn = NULL; |
| 2784 | if (recv && recv->kind == CBM_TYPE_NAMED) |
| 2785 | recv_qn = recv->data.named.qualified_name; |
| 2786 | else if (recv && recv->kind == CBM_TYPE_TEMPLATE) |
| 2787 | recv_qn = recv->data.template_type.template_name; |
| 2788 | if (recv_qn) |
| 2789 | return java_lookup_method(ctx, recv_qn, mname, arity); |
| 2790 | return NULL; |
| 2791 | } |
| 2792 | |
| 2793 | /* Walk every node beneath `node`, calling resolve_method_call on each |
| 2794 | * method_invocation / object_creation_expression and recursing into block |
no test coverage detected