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. */
| 2811 | * bind_method_ref_args before re-walking arguments — we need the resolved |
| 2812 | * method to know the SAM-typed parameter slot. */ |
| 2813 | static const CBMRegisteredFunc *lookup_method_for_call(JavaLSPContext *ctx, TSNode call, |
| 2814 | const CBMType **out_recv_type) { |
| 2815 | if (out_recv_type) |
| 2816 | *out_recv_type = NULL; |
| 2817 | TSNode obj = ts_node_child_by_field_name(call, "object", 6); |
| 2818 | TSNode name_node = ts_node_child_by_field_name(call, "name", 4); |
| 2819 | if (ts_node_is_null(name_node)) |
| 2820 | return NULL; |
| 2821 | char *mname = java_node_text(ctx, name_node); |
| 2822 | if (!mname) |
| 2823 | return NULL; |
| 2824 | int arity = count_call_args(call); |
| 2825 | |
| 2826 | if (ts_node_is_null(obj)) { |
| 2827 | if (ctx->enclosing_class_qn) { |
| 2828 | return java_lookup_method(ctx, ctx->enclosing_class_qn, mname, arity); |
| 2829 | } |
| 2830 | return NULL; |
| 2831 | } |
| 2832 | if (strcmp(ts_node_type(obj), "super") == 0) { |
| 2833 | const char *sq = ctx->enclosing_super_qn ? ctx->enclosing_super_qn : "java.lang.Object"; |
| 2834 | return java_lookup_method(ctx, sq, mname, arity); |
| 2835 | } |
| 2836 | if (strcmp(ts_node_type(obj), "this") == 0) { |
| 2837 | if (ctx->enclosing_class_qn) { |
| 2838 | return java_lookup_method(ctx, ctx->enclosing_class_qn, mname, arity); |
| 2839 | } |
| 2840 | return NULL; |
| 2841 | } |
| 2842 | /* Static call via class name. */ |
| 2843 | if (strcmp(ts_node_type(obj), "identifier") == 0) { |
| 2844 | char *oname = java_node_text(ctx, obj); |
| 2845 | if (oname && cbm_type_is_unknown(cbm_scope_lookup(ctx->current_scope, oname))) { |
| 2846 | const char *cls_qn = java_resolve_type_name(ctx, oname); |
| 2847 | if (cls_qn) { |
| 2848 | const CBMRegisteredFunc *f = java_lookup_method(ctx, cls_qn, mname, arity); |
| 2849 | if (f) |
| 2850 | return f; |
| 2851 | } |
| 2852 | } |
| 2853 | } |
| 2854 | /* Instance dispatch. */ |
| 2855 | const CBMType *recv = java_eval_expr_type(ctx, obj); |
| 2856 | if (out_recv_type) |
| 2857 | *out_recv_type = recv; |
| 2858 | const char *recv_qn = NULL; |
| 2859 | if (recv && recv->kind == CBM_TYPE_NAMED) |
| 2860 | recv_qn = recv->data.named.qualified_name; |
| 2861 | else if (recv && recv->kind == CBM_TYPE_TEMPLATE) |
| 2862 | recv_qn = recv->data.template_type.template_name; |
| 2863 | if (recv_qn) |
| 2864 | return java_lookup_method(ctx, recv_qn, mname, arity); |
| 2865 | return NULL; |
| 2866 | } |
| 2867 | |
| 2868 | /* Walk every node beneath `node`, calling resolve_method_call on each |
| 2869 | * method_invocation / object_creation_expression and recursing into block |
no test coverage detected