Skip to content

fix(resolution): a receiver-less JS/TS call never binds to a method - #1759

Merged
colbymchenry merged 1 commit into
mainfrom
forge/fix-1714-bare-call-no-method
Sep 8, 2026
Merged

colbymchenry merged 1 commit into
mainfrom
forge/fix-1714-bare-call-no-method

Conversation

@colbymchenry

Copy link
Copy Markdown
Owner

Fixes #1714.

Lands/rebases #1735 onto current main (was CONFLICTING).

Receiver-less JS/TS calls never bind to methods; local bindings shadow cross-file names. Keeps main visibility guards.

Verified fail->pass on Linux; bare-call-no-method 5/5; resolution 198/198; tsc clean.

Credit: @danusha2345 (#1735).

`serialize(this.raw)` inside `Record.serialize`, with a module-scope
`function serialize` in the same file, resolved onto the method itself:
both were exact-name candidates, both same-file, and findBestMatch's
line-proximity term always prefers the enclosing method (#1714). In JS/TS a
call written without a receiver cannot reach a method at all — methods
need `this.`, an object, or a bound reference.

The extractor emits `this.m()` and `super.m()` under the bare method name,
so the receiver is read back from the call site's own line: when the text
there begins with the name itself and nothing but whitespace, an operator
or an opener precedes it, the call is bare, and `method` nodes leave the
candidate set before ranking. matchFuzzy declines a lone `method` survivor
for the same ref. A name the file binds itself also has no cross-file
candidate for a bare call. `this.serialize()` and `other.serialize()` are
unchanged.

Rebased #1735 onto current main (resolved conflicts with sealed-module /
cross-file visibility guards from #1719/#1730/#1731).

Fixes #1714

Co-authored-by: danusha2345 <ewidusoc498@gmail.com>
@danusha2345

Copy link
Copy Markdown
Contributor

Thanks for landing it — but the head you rebased (fd26889) carries a regression I had found and fixed on the branch an hour before this merged, and it is on main now: at cd4e65b, object-literal-methods.test.ts (resolves callers of store actions across files) and ui-steps-api.test.ts (2 tests) fail. Rule 2 reads const { fetchUser } = useStore.getState() and const setZipUri = useStore((s) => s.setZipUri) as local definitions and drops the store-action edges. Fix as a follow-up: #1760 (a same-name re-binding is not a local definition; one new fixture, the three tests pass again, vite numbers in the description).

bompus added a commit to bompus/codegraph that referenced this pull request Sep 8, 2026
Replaces the fork-local carve-out with the version in upstream PR colbymchenry#1760,
which fixes the same colbymchenry#1759 regression. Adopting it now means the merge is
clean when colbymchenry#1760 lands instead of conflicting in name-matcher.ts.

The two differ in approach. The carve-out kept destructuring in declRe and
excluded `.getState()` / `get()` initialisers by name; colbymchenry#1760 drops the
destructuring alternation from declRe entirely, so a destructured binding is
never a candidate, and matches a selector by backreference — the arrow's body
must read the member off its OWN parameter. That also reclassifies
`const now = opts.now || (() => Date.now())`, which the carve-out kept
shadowing.

bare-call-no-method, object-literal-methods and ui-steps-api: 25 passed,
including colbymchenry#1760's new store-selector test, carried over with it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

A bare call resolves onto the enclosing method when a same-file function shares its name

2 participants