Repository navigation
fix(resolution): resolve TS/JS calls on a new C() receiver through C - #1945
Open
danusha2345 wants to merge 2 commits into
Open
danusha2345 wants to merge 2 commits into
danusha2345 wants to merge 2 commits into
Conversation
danusha2345
force-pushed
the
fix/new-expression-receiver
branch
3 times, most recently
from
October 3, 2026 09:01
f3a3f7d to
ef92763
Compare
danusha2345
force-pushed
the
fix/new-expression-receiver
branch
3 times, most recently
from
October 7, 2026 16:05
81bb7a0 to
98273a5
Compare
`new RegExp(p).exec(s)`, `new Array(n).fill(x)`, `new TextDecoder().decode(b)` reached the resolver as the bare method name and exact-matched any project method of that name (in codegraph's own index `new RegExp().exec` onto `SqliteDatabase::exec`, `new Array().fill` onto `TextOptions::fill`). Extraction (mirrored in the kernel) now keeps the constructed class: `new C(args).m()` is encoded `new C().m` (a member-chain constructor keeps its path, `new ns.C().m`); a constructor that is not a plain name or member chain emits nothing. The resolver resolves that shape only on C — through a named import alias to the declared name, and on a supertype in the conformance pass when C is a project class — so a built-in or external class yields no edge. A JS built-in name counts as a project class only when the file imports or declares it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ototype method With the constructed class kept in the ref, `new Params().render()` resolved only on a class `Params`; an ES5 constructor function has none, so the call lost the edge main's colbymchenry#2162 keeps to `prototype.render = function render()` in the constructor's file. When no class method matches and the constructed name is one project function, a same-named function assigned onto a prototype in that function's file is the target. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
danusha2345
force-pushed
the
fix/new-expression-receiver
branch
from
October 10, 2026 11:22
98273a5 to
852c074
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A TS/JS call on a constructor receiver,
new X(args).m(), reaches the resolver as the bare namem, in both the TS extractor and the kernel. Exact-match then binds it to any project method calledm:new RegExp(p).exec(s)→SqliteDatabase::execnew Array(n).fill(0)→TextOptions::fillnew TreeSitterExtractor(..).extract()→RazorExtractor::extractnew Runner().run()reachedRunner::runonly when no other project method was calledrun.Fix
new C().m. This form can't be mistaken for a static call (C.m) or a factory call (C().m).new ns.C()keeps its path, and a receiver that isn't a plain name or member chain emits nothing.monCthroughresolveMethodOnType, which checks that the method exists there.extendsedges exist.import { Runner as R }) maps back toRunner.C(RegExp,URL,Map,Date,TextDecoder…) gets no edge.Mapdoesn't take everynew Map().get()in the repo.new Params().render()on a constructor function has no class to look the method up on. When no class method matches andParamsis one project function, a same-named function assigned onto a prototype in that function's file (prototype.render = function render() {…}) is the target, so the edge main already draws for that shape is kept.No
EXTRACTION_VERSIONbump: main already raised it to 28 for this release.Rebased onto current main. #2363 (functions of a named object literal as
Owner::member), #2357 (top-level destructuring) and #2362 (per-file caches in JS resolution) changed the same files, but none of them changes how anew C()receiver is extracted or resolved: on current mainnew RegExp(p).exec(s)still reaches the resolver as the bareexec.Measured
Every changed edge was read at its call site. Node counts are unchanged.
new RegExp(..).exec(..)→SqliteDatabase::exec×49,new Array(..).fill(..)→TextOptions::fill×10,new TreeSitterExtractor(..).extract()→RazorExtractor::extract/CfmlExtractor::extract×2new ToolHandler(cg).execute(..)→ToolHandler::execute×38 (no edge on main),new TreeSitterExtractor(..).extract()→TreeSitterExtractor::extract×2new RegExp(context).test(url)→ a projecttest, wrong)new Array<boolean>(n).fill→DebugPolygon::fill, wrong)Known limit: a default-imported class whose local name differs from its declared name (
import Foo from './bar', where the class isBar) gets no edge. Bare-name matching sometimes guessed it before. That didn't come up in any of the three corpora.Tests
The new
__tests__/new-expression-receiver.test.tscovers:Three of its four cases fail on current main. The kernel parity test and
torture.jsare extended, the kernel is rebuilt, and the TS and kernel refs are identical. The TS/JS receiver, object-literal, CommonJS and store suites,kernel-tsjs-parity,resolution.test.tsandextraction.test.ts(28 files, 1193 tests) pass with the native kernel and withCODEGRAPH_KERNEL=0.🤖 Generated with Claude Code