| 1916 | } |
| 1917 | |
| 1918 | static void resolve_method_call(JavaLSPContext *ctx, TSNode call) { |
| 1919 | TSNode obj = ts_node_child_by_field_name(call, "object", 6); |
| 1920 | TSNode name_node = ts_node_child_by_field_name(call, "name", 4); |
| 1921 | if (ts_node_is_null(name_node)) |
| 1922 | return; |
| 1923 | char *mname = java_node_text(ctx, name_node); |
| 1924 | if (!mname) |
| 1925 | return; |
| 1926 | int arity = count_call_args(call); |
| 1927 | |
| 1928 | /* Bare call: `foo()`. */ |
| 1929 | if (ts_node_is_null(obj)) { |
| 1930 | if (ctx->enclosing_class_qn) { |
| 1931 | const CBMRegisteredFunc *f = |
| 1932 | java_lookup_method(ctx, ctx->enclosing_class_qn, mname, arity); |
| 1933 | if (f) { |
| 1934 | const char *strategy = "lsp_type_dispatch"; |
| 1935 | if (f->receiver_type && strcmp(f->receiver_type, ctx->enclosing_class_qn) != 0) { |
| 1936 | strategy = "lsp_inherited_dispatch"; |
| 1937 | } |
| 1938 | java_emit_resolved(ctx, f->qualified_name, strategy, 0.95f); |
| 1939 | return; |
| 1940 | } |
| 1941 | } |
| 1942 | /* JLS §15.12.1: a bare call inside an inner class also looks up the |
| 1943 | * call against each enclosing-class scope. Walk outer classes. */ |
| 1944 | for (int i = ctx->enclosing_class_depth - 2; i >= 0; i--) { |
| 1945 | const char *outer = ctx->enclosing_class_stack[i]; |
| 1946 | if (!outer) |
| 1947 | continue; |
| 1948 | const CBMRegisteredFunc *f = java_lookup_method(ctx, outer, mname, arity); |
| 1949 | if (f) { |
| 1950 | java_emit_resolved(ctx, f->qualified_name, "lsp_outer_dispatch", 0.92f); |
| 1951 | return; |
| 1952 | } |
| 1953 | } |
| 1954 | /* Static import. */ |
| 1955 | for (int i = 0; i < ctx->import_count; i++) { |
| 1956 | if (ctx->import_kinds[i] != CBM_JAVA_IMPORT_STATIC) |
| 1957 | continue; |
| 1958 | if (strcmp(ctx->import_local_names[i], mname) != 0) |
| 1959 | continue; |
| 1960 | const char *target = ctx->import_target_qns[i]; |
| 1961 | const char *last_dot = strrchr(target, '.'); |
| 1962 | if (!last_dot) |
| 1963 | continue; |
| 1964 | char *cls = cbm_arena_strndup(ctx->arena, target, (size_t)(last_dot - target)); |
| 1965 | const CBMRegisteredFunc *f = java_lookup_method(ctx, cls, mname, arity); |
| 1966 | if (!f && ctx->registry) { |
| 1967 | /* The import is written package-qualified ("demo.Util"), but the |
| 1968 | * class is registered under the project/directory QN |
| 1969 | * ("<proj>.Util") when the `package` declaration and the file's |
| 1970 | * directory differ. Resolve the import's class by its short name |
| 1971 | * against the registry and retry — preferring an in-module match. |
| 1972 | * Mirrors the C++ short-name type fallback. */ |
| 1973 | const char *cls_dot = strrchr(cls, '.'); |
| 1974 | const char *cls_short = cls_dot ? cls_dot + 1 : cls; |
| 1975 | size_t sl = strlen(cls_short); |
no test coverage detected