Repository navigation
fix(resolution): model CommonJS export values, with a pre-model fallback for unmodelled files - #29
Draft
inth3shadows wants to merge 8 commits into
Draft
inth3shadows wants to merge 8 commits into
inth3shadows wants to merge 8 commits into
Conversation
…p patch The full suite found PR29 dropped static members of exported class expressions (colbymchenry#2499). The uncommitted fix is now covered by the source hash manifest and the working-tree backup patch, which reconstructs all 30 pending paths from 87576a8. START_HERE notes that the harness results predate the fix.
Every harness stage on a build of the fixed checkout matches the pre-fix candidate run: replay, graph diffs, shadow, modes and metamorphic. The full suite passes apart from two load-sensitive UI timing tests that pass in isolation. The Express indexing regression remains open, and its profiling attribution is noted.
Track binding-owned values and object properties for CommonJS exports.
Reference, callable and constructor evidence are kept separate, so exported
data never becomes a call target and assigned functions resolve to their
implementations. Import resolution carries that intent through named,
default, namespace and forwarded imports, and failed forwarded calls retry
after their sources change.
Class expressions are seeded like class declarations (static members,
prototype and the construction check). This keeps `module.exports = class
{ static f() {} }` resolvable (colbymchenry#2499).
On Express this removes 64 call edges: 52 had wrong targets and 12 pointed
at external-import variables without a proven callable body. The other four
QA corpora are unchanged. Indexing is slower on CommonJS-heavy projects
(Express about +38%) because of per-file TypeScript analysis. That cost is
documented in the handoff and still open.
…17, F18, F19a) CommonJS export lookups now answer positive, blocked or unknown. Absent, non-callable and conflicting answers stay blocking. An unknown answer from code this analysis does not model (constructed or inherited instances, Object.assign/defineProperty, object spread, unparsable source, closure writes) may fall back to ordinary matching. The fallback is limited to functions, methods or classes in the module's evidence files, so it never lands on a decoy elsewhere or on a storage variable. An opaque call or dynamic write on a known value still gives no edge. Object.freeze and the other read-only Object calls no longer count as escapes, and spread require() calls are recorded as sources. A hashbang is blanked in place before wrapping. Legacy octal literals, octal escapes and Flow annotations no longer make the whole file unknown. IIFEs, UMD factories and callbacks that write module/exports now make the export unknown instead of a false complete "absent". The reviewer's F17, F18 and F19a cases recover their baseline edges. Replay, metamorphic and the five QA corpus graphs are unchanged.
…s (round 13) Replace the round-12 evidence-file fallback with a file-level bailout. A file the value model cannot answer for completely gets commonJs:false and resolves through the pre-model lexical path, exactly as before the model. - Rule 1: every use of module, exports, module.exports or an alias must be in a modelled position (member reads anywhere; writes and bare uses at top level only; no delete; no top-level this or return). - Rule 2: any unknown reachable from the exports, other than the opaque escapes the model blocks on, bails the file. - Also bail on unparsed source, __esModule with exports.default, and a whole-export forward into an unmodelled file. - Model: hashbang (BOM, CR), sloppy-mode diagnostics, Object.freeze-style reads, literal-key data defineProperty, hoisted function declarations, constructor-function prototypes. - Restore the pre-model COMMONJS_DEFAULT_EXPORT regex and lexical member reader for unmodelled files.
This was referenced Nov 10, 2026
… (round 14) - R14-S1: the lexical reader used for unmodelled files is now verbatim the PR's first commit (87576a8), restoring the wrap(eval) prefix guard. - R14-6: a member a modelled file forwards into a file outside the model resolves in that file: its ordinary export lookup, else its one top-level declaration of that name that it writes to exports.
This was referenced Nov 11, 2026
Open
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.
Warning
DO NOT MERGE (2026-11-11). This tip (f41f795) adds wrong edges that baseline does not have: review rounds 3 and 4 reproduced high-severity cases on accepted shapes (R3-1..R3-4, R4-1..R4-4). The value model is parked while codegraph-qa compares it with option 3B (PR #28 plus removal-only lexical rules). Issues #30-#41 track its known gaps and stay open for that comparison.
Follow-up to #28, targeting its branch. Draft.
What it does
wrap(eval)("…")) is no longer mistaken for a grouped direct eval. That mistake let a missing CommonJS member resolve to an unrelated decoy method.commonjs-export-evidence.ts,commonjs-value-graph.ts). It answers which declaration an export, or a member of it, really is, and whether that value is callable or constructible. Exported data, absent members and non-callable values therefore stop resolving to same-named functions elsewhere (F14, F15, F16).commonJs: falseand resolves through the pre-model lexical path, exactly as before this PR.module,exports,module.exportsor an alias of them must be in a modelled position. Member reads may be anywhere; writes and bare uses only at top level; nodelete, no top-levelthisorreturn.__esModulewithexports.default, and a whole-export forward into an unmodelled file.exports.Validation on f41f795
Known gaps (filed)
Lost edges in modelled files, mostly shared with 4064015: #30 control flow, #31 destructuring/for targets, #32 Rule 2 gaps, #33 Rule 1 gaps, #34 minified
__esModuleand read-only calls, #35 import reader and memo. Earlier open review items F22-F28 are unchanged. The indexing cost (Express about +38% CPU, from the per-file TS parse) is still open.Files outside the model keep the pre-PR graph, including its wrong edges. That is the accepted cost of answering only where the model is complete.
No merge, deployment or upstream report is included.