fix: resolve JavaScript and TypeScript default imports - #56
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (9)
Included review availability: Your plan provides up to 4 included reviews per hour; 0 remain after this review. 📝 SummarySummary by CodeRabbit
WalkthroughThe change adds JavaScript and TypeScript default-import and default-export extraction, resolves unique bindings, marks ambiguous exports, invalidates older parser caches, and adds integration coverage. ChangesDefault binding resolution
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to Default import/export resolution, ambiguity handling, cache invalidation, and regression coverage are aligned with the stated behavior; no merge-blocking risk remains. Sequence Diagram(s)sequenceDiagram
participant JSModule
participant captureJsImportFacts
participant jsModuleBindingCount
participant buildJsImportTables
JSModule->>captureJsImportFacts: Parse default import/export syntax
captureJsImportFacts->>jsModuleBindingCount: Count matching module-scope bindings
jsModuleBindingCount-->>captureJsImportFacts: Return binding count
captureJsImportFacts->>buildJsImportTables: Store resolved or ambiguous default facts
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 7 files. (2 skipped: 2 unsupported.)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
Thank you — and thank you for coming back. Your named-import fix from #45 shipped in v0.5.0 yesterday and you're named in the changelog for it; opening three more PRs the same evening is the best signal this project has had that the contribution path actually works. Default imports are the right next gap. Queued behind #57's review — we're prioritising language coverage over new surface for the next couple of weeks, and this sits squarely in that. I'll give it the same treatment: full battery, ASan, and an adversarial corpus rather than just the fixture. If it holds up the way #45 did, it lands. |
|
Merged — thank you, this is a careful fix and the reasoning in the description is the best part of it. "Resolve by module and exported identity, not by the importer's chosen local name" is exactly the right Three things you did that I want to name, because they are the parts that made this cheap to land: You bumped You left Your new coverage adds NO name to the absorb list. Putting the logic in On the conflict. Both this branch and #57 (Ruby constant references) spent parser version 82. I Nothing was needed from you. Thanks again. |
…ndriy Tyurnikov) Round two of the Ruby constant work, on top of redhat-et#57. `User.find` now edges to the file that defines `User`: a call whose receiver is a constant chain is a symbolic directive resolved through round one's index. That is the Zeitwerk dependency proper — a Rails file almost never says `require`, it names the constant and the autoloader loads the file on that first reference. Before this, `--impact=User` on a Rails app named nobody. CONFLICT RESOLUTION — seven files, and the interesting part is which ones git did NOT flag. kParserVer 83 -> 84. THIRD version collision today. main spent 83 on redhat-et#56's JS/TS default imports (itself renumbered from 82 on merge, because redhat-et#57 had taken 82). This PR also claimed 83. Renumbered to 84 with BOTH changelog entries kept and a line recording the renumber, so neither lineage is lost. kIngestParserVerMirror moved in the same edit — that pair is the nastiest trap in this codebase. test/regression.sh absorb list: took main's line VERBATIM and inserted `rubyrecvcheck` into it, rather than rebuilding it from parsed tokens. Rebuilding drops every name the filter misses and the trailing `; do`, which silently stops gates running — done exactly that once today. 561 names, and it correctly retains the two gates that landed after this PR branched. The eight gate-count sites did NOT conflict, and that is the hazard: main said 560, this PR said 559, and git would have merged one of them cleanly into a number that is wrong either way. Every count conflict was resolved to main's side FIRST and the number re-derived afterwards. Never carry a count across a rebase. docs/COMMANDS.md REGENERATED, not merged (it is generated output; docscommandscheck arm (G) checks which capture produced it): 4 lines, 161 samples intact. test/printf_parity.manifest re-pinned with ONLY the `help` label moving — the check that proves nothing else drifted. test/qschemetrip.hash re-pinned, kQSnapCacheScheme left at 8. This PR does not touch src/quality.h; the hash moved solely because the version MIRROR is inside the hashed region. Same call as redhat-et#56's merge. Coupled gates verified: manifestcheck (561), qextractionkeycheck, qschemetripcheck, docscommandscheck, printffmtparitycheck, rubyrecvcheck, rubyconstcheck. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
Resolve JS/TS default-import calls by module and exported identity, not by the importer's chosen local name.
For example,
import save from './storage.js'must call the function exported as default bystorage.js; an unrelated function namedsaveis not evidence of that edge.This extends the existing ES import/export fact tables to default imports, named default declarations, local identifier defaults, and
export { local as default }. Existing lexical-shadow and module-ambiguity handling is reused. Named default classes use the same declaration seam to preserve constructor edges. The parser cache version and its quality mirror are bumped together.Unsupported anonymous expressions remain unresolved. Conflicting default exports or module value bindings cannot select a function simply because it is the only function-shaped symbol.
Regression proof
The new sub-gate, called by
tsimportprecisecheck.sh, covers TS/TSX/MTS/CTS and JS/JSX/MJS/CJS:The original regression fails on the current upstream-base binary; the fixed binary passes. Source review findings were reproduced or covered by added regression arms and repaired before publication.
Validation
FETCHCONTENT_FULLY_DISCONNECTED=ON.bash test/lib/jsdefaultimport.sh <binary>passes for all three build flavours. Existingjsimportalias.shandjsimportfacts.shpass in development and Release.python3 test/pargates.py . ./build/ripwire -j 4: 571 gates, 565 pass, 3 skip, 3 fail on the first full run. The parser-identity fingerprint and two README example coordinates were then refreshed in a separate proof-reference commit;qschemetripcheck.sh,qextractionkeycheck.shandreadmeexamplecheck.shpass after that refresh.legendcoveragecheck.sh, scans installed host skills with bare--scan-skills; it passes with a disposable empty home. The legend baseline and host skills are unchanged.Scope and limits
No new graph mechanism, general TypeScript semantic analysis, anonymous-symbol synthesis, barrel traversal, reassignment analysis or
--usesbehavior change. Existing named-import handling stays on its current path. The meaningful behavior change is confined to default bindings; reverting the commit restores the previous extraction/resolution behavior.AI-assisted implementation with independent source review. Validation is static-source/real-CLI proof, not execution of the JavaScript programs.