You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(resolver): suppress weak short-name matches for TS/JS method calls
A member call `x.foo()` reaches the registry's weak textual cascade only when
the TS-LSP could not resolve the receiver type — type-resolved calls win via
lsp_* strategies before the registry runs. Binding such a call to a project
symbol by a weak short-name strategy fabricates a CALLS edge (`re.test()` ->
SalesforceRestClient.test, `date.toISOString()` -> any project toISOString).
On a 6k-file monorepo this produced ~21.6k false edges (~12.6% of CALLS).
Add cbm_tsjs_suppress_weak_method_match: for a TS/JS/TSX member call flagged
is_method, the weak strategies (suffix_match, unique_name, field_type_hint,
fuzzy) are noise. It uses an EXPLICIT drop-list, not keep-list + default-drop,
because the resolver runs lsp_* through the same code path — a default-drop
would silently kill lsp_ts_method. Gated on the file language so no other
language is affected.
The suppression is applied at the PLAIN-CALLS emission point, not before it:
emit_classified_edge (sequential) and emit_service_edge (parallel) take a
suppress_plain_calls flag and skip ONLY the final plain CALLS fall-through
(and emit_http_async_edge's no-URL fall-through). Every service classification
that runs first — the #523 callee-name HTTP/ASYNC bypass, route registration,
gRPC/GraphQL/tRPC/CONFIG, and emit_service_edge's unconditional
detect_url_in_args — is therefore byte-identical to main by construction. This
replaces an earlier attempt that dropped the call at a language guard and tried
to re-derive "is this a service edge?" with a predicate: that predicate drifted
from the emit path's classification and lost ~399 HTTP_CALLS (verb-suffix
clients like api.patch / page.goto / request(app).get, whose HTTP signal is not
a library name in the callee) plus ~63 CONFIGURES on the monorepo. Suppressing
at the emit point cannot drift.
Tests: unit tests pin the keep/drop split (including lsp_* -> keep). A
reproduce-first sequential E2E fixture asserts the regex-receiver false edge is
gone while a typed-receiver call (lsp_ts_method) and a bare local call survive.
A >=50-file parallel fixture (CBM_WORKERS forces the parallel resolver) asserts
that axios.get and dev.load('/api/data') keep their HTTP_CALLS (the latter via
detect_url_in_args — the class the old predicate lost), that api.patch,
request(app).get and router.get keep their Route registrations, and that the
regex and dev.load weak plain-CALLS edges stay suppressed. The ts/S6
inherited-method probe, which used to pass via a fragile unique_name fallback,
now asserts exactly zero CALLS with a store-opened guard (the INHERITS edge IS
extracted; the gap is ts_lsp_cross's cross-file resolution, which the guard
keeps once wired).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Hitoshi Okazaki <okazaki.hitoshi@tecnos.co.jp>
0 commit comments