| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
…ons (#2033) extractObjectLiteralFunctions only fired for object literals assigned via a variable declarator (const x = {...}), so calls inside a closure property returned from a function body (return { prop: () => f() }) attributed to the enclosing factory itself rather than the property — misleading call-graph edges since the factory's own body never executes that call. Extend the mechanism to return_statement object literals, qualifying against the nearest enclosing named function (or ClassName.method for methods, or the variable a function/arrow is directly assigned to). Also add a self-typing return-type inference so const p = factory(); p.prop() resolves through the qualified definition, closing the loop with #2032's reachability-based dead code detection. Mirrored in both WASM (shared runCollectorWalk, used by both extraction paths) and native (match_js_node/match_js_type_map/store_return_type). docs check acknowledged: internal extractor/resolver fix, no new commands, languages, or architecture changes — README/CLAUDE.md/ROADMAP unaffected. Impact: 9 functions changed, 14 affected
Greptile SummaryThe PR extends JavaScript factory-return extraction while preventing the previously reported impossible call edges for async and generator wrappers.
Confidence Score: 5/5The PR appears safe to merge. No blocking failure remains. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart LR
Factory["Synchronous factory"] --> Returned["Returned object literal"]
Returned --> Qualified["Qualified property definitions"]
Factory --> SelfType["Factory self return type"]
SelfType --> Variable["Call-result variable type"]
Variable --> Call["Resolved property call edge"]
Async["Async or generator factory"] --> Wrapper["Promise or generator wrapper"]
Wrapper --> Skip["Skip self-type inference"]
Reviews (2): Last reviewed commit: "fix(extractors): skip return-type self-i..." | Re-trigger Greptile |
Sorry, something went wrong.
| const body = fnNode.childForFieldName('body'); | ||
| if (body) { | ||
| const inferred = findReturnNewExprType(body); | ||
| const inferred = findReturnNewExprType(body) ?? findReturnObjectLiteralSelfType(body, fnName); |
There was a problem hiding this comment.
Async and generator return types
When an async or generator factory directly returns an object literal with callable properties, this inference types the immediate call result as the object itself. Calls such as make().run() can then resolve to make.run even though the runtime result is a Promise or generator object, producing impossible call edges and incorrect reachability and dead-code results.
Knowledge Base Used:
Sorry, something went wrong.
There was a problem hiding this comment.
Fixed in b1fbfbd: added isAsyncFunctionNode/isGeneratorFunctionNode guards (mirrored in both TS and native) that skip the return-type self-inference — and the pre-existing return new Ctor() inference, which had the identical flaw — for async/generator factories. The qualified property definitions are still extracted regardless; only the self-typing that would let a caller resolve through the wrapper without await/iteration is skipped. Added regression tests on both engines (async factory, generator factory, and the pre-existing return-new-Constructor case).
Sorry, something went wrong.
Codegraph Impact Analysis11 functions changed → 16 callers affected across 3 files
|
Sorry, something went wrong.
…factories An async or generator function's runtime return value is a Promise/Generator wrapper around the returned expression, not the expression itself. Both the new #2033 self-type inference and the pre-existing `return new Ctor()` inference wrongly typed such factories as their own return shape, which would let `const p = asyncMakeThing(); p.method()` resolve without the required await/iteration. Gate both inferences on isAsyncFunctionNode/ isGeneratorFunctionNode in TS and native; the qualified property definitions themselves are still extracted regardless. docs check acknowledged: internal extractor/resolver fix, no docs impact. Impact: 3 functions changed, 10 affected
| Back | FazBrowse Home | New Git URL |
Summary
Closes #2033.
extractObjectLiteralFunctions (the mechanism that creates qualified varName.propName definitions so calls inside an object-literal property's closure attribute to the property, not the enclosing scope) only fired for object literals assigned via a variable declarator (const x = {...}). It never fired for object literals appearing in a return statement inside a function body — so calls inside those closures fell through to generic caller-attribution, which resolved to the enclosing factory function itself, even though the factory's own body never executes that call.
Before: computeDeltaCPM's caller showed as makePartition. After: makePartition.deltaCPM.
Changes
Verification
Follow-ups filed (out of scope, discovered during validation)
Test plan