Skip to content

compat-eslint: SyntheticLazyNode base β€” architectural boundary for synthetic intermediates#91

Merged
johnsoncodehk merged 1 commit into
masterfrom
refactor/factory-dsl-phase3
May 2, 2026
Merged

compat-eslint: SyntheticLazyNode base β€” architectural boundary for synthetic intermediates#91
johnsoncodehk merged 1 commit into
masterfrom
refactor/factory-dsl-phase3

Conversation

@johnsoncodehk
Copy link
Copy Markdown
Owner

Summary

  • Closes the last drift path in the lazy ESTree shim. Synthetic intermediates (nodes with no direct TS counterpart, like TSTypeAnnotation / ClassBody / ChainExpression-wrapper) used to opt out of map registration via a registerInMaps=false constructor flag. Easy to forget when adding a new synthetic class β€” and a forgotten one produces silently-wrong parent references on bottom-up materialise.
  • Replace the boolean with SyntheticLazyNode, an abstract base that overrides _registersInMaps() to return false. The 14 synthetic-creating classes now extend SyntheticLazyNode instead of extend LazyNode. Adding a 15th is a visible architectural act in code review.
  • JSXOpeningElementNode is hybrid (synthetic only when wrapping a JsxSelfClosingElement) β€” keeps LazyNode base but overrides _registersInMaps() based on this._ts.kind, so the synthetic constructor arg is gone too.
  • Also drops a dead registerInMaps param on JSXIdentifierNode (all 6 call sites passed true) and stale comments referencing the removed flag.

Why this is the last phase

Drift class Phase that closed it
Phantom output types (e.g. TSJsxAttributes) #90 β€” KnownEstreeType compile-time gate
Shape knowledge duplicated between top-down getters and bottom-up walk #88, #89 β€” navigation tables + factory DSL
Synthetic intermediate added without registering in nav tables this PR β€” SyntheticLazyNode boundary

After this, every "synthetic intermediate" is grep-able in one place (extends SyntheticLazyNode) and the registration distinction is a class boundary, not a magic constructor arg.

Test plan

  • predicate-coverage (152/152 covered, 16 ignored)
  • lazy-estree.test (parity sweep + factory tests + phantom-types invariant)
  • scope-compat (24/24 fixtures clean)
  • selector-analysis, ts-ast-scan, compat-pipeline
  • dogfood.js β€” 107 rules Γ— 30 files, 0 divergences, 0 crashes
  • Dify web cold lint β€” 5.1s on this branch vs 5.1-5.5s on master (no regression)

…nthetic intermediates

Synthetic intermediate classes (TSTypeAnnotation, ClassBody, ChainExpression
wrapper, etc.) opted out of map registration via a `registerInMaps=false`
constructor arg. Easy to forget β€” and a forgotten synthetic class produces
silently-wrong parents on bottom-up materialise because the wrapper-route
tables don't see it.

Replace the boolean param with a `SyntheticLazyNode` abstract base. The 14
synthetic-creating classes now `extend SyntheticLazyNode` instead of
`extend LazyNode`; the base overrides `_registersInMaps()` to return false.
Adding a 15th synthetic class is now a visible architectural act in code
review (extends a different base + needs a navigation-table entry). Grep
`extends SyntheticLazyNode` to find all current synthetic classes.

JSXOpeningElementNode is hybrid (synthetic only when wrapping a
JsxSelfClosingElement); keeps the LazyNode base but overrides
`_registersInMaps()` to dispatch on `this._ts.kind`. Drops the now-unneeded
`synthetic` constructor arg.

Also drops a dead `registerInMaps` param on JSXIdentifierNode (all 6 call
sites passed `true`) and stale comments referencing the removed flag.

Tested: predicate-coverage / lazy-estree / scope-compat / selector-analysis
/ ts-ast-scan / compat-pipeline + dogfood (107 rules Γ— 30 files clean) +
Dify cold/warm bench (no regression vs master).
@johnsoncodehk johnsoncodehk merged commit 7a81e2d into master May 2, 2026
1 check passed
@johnsoncodehk johnsoncodehk deleted the refactor/factory-dsl-phase3 branch May 27, 2026 17:28
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.

1 participant