Skip to content

fix: pass keepCommentsInBody: true to preserve zmod comment traversal#13

Closed
johanrd wants to merge 1 commit into
NullVoxPopuli:mainfrom
johanrd:opt-in-keep-comments-in-body
Closed

fix: pass keepCommentsInBody: true to preserve zmod comment traversal#13
johanrd wants to merge 1 commit into
NullVoxPopuli:mainfrom
johanrd:opt-in-keep-comments-in-body

Conversation

@johanrd
Copy link
Copy Markdown

@johanrd johanrd commented Apr 23, 2026

Draft — companion to NullVoxPopuli/ember-estree#39. Should land only if/after that proposal is accepted.

Cowritten by claude

Summary

ember-estree is restoring the 0.4.2 ESLint-facing default (comments as ESTree `Block` in `astRoot.comments`, removed from `GlimmerTemplate.body`) to stop silently breaking every ESLint consumer downstream. zmod-ember depends on the other shape — comments in the body with semantic Glimmer types, so `root.find("GlimmerCommentStatement")` / `root.find("GlimmerMustacheCommentStatement")` can walk them via visitor keys.

The two shapes are genuinely exclusive (ESLint's token-store `createIndexMap` infinite-loops if a token and a comment share the same `range[0]`, which you can't avoid if a body-resident comment is to be find-able via `getLastToken`). The proposal in ember-estree#39 gates the body-retention behavior behind an opt-in `keepCommentsInBody: true` flag. This PR opts in.

Why this is needed (original zmod-ember motivation)

The very reason zmod-ember was extended to preserve comments in the body was to enable codemods like johanrd/eslint-plugin-ember#3 (migrate-template-lint-directives-codemod) — which rewrites Handlebars `{{! template-lint-disable ... }}` directives in `.gjs` / `.gts` templates. That codemod discovers targets via `root.find("GlimmerMustacheCommentStatement")`, which in turn requires them to be reachable through the walker. Without `keepCommentsInBody: true`, that codemod (and any future comment-rewriting codemod) can't find its targets.

Change

`src/index.ts`:

```diff

  • const ast = toTree(source, { ...(options as any), includeParentLinks: false });
  • const ast = toTree(source, {
  •  ...(options as any),
    
  •  includeParentLinks: false,
    
  •  keepCommentsInBody: true,
    
  • });
    ```

Verified

`pnpm test`: all 100 tests pass (6 skipped). No test-code changes. No user-visible API change.

Release coordination

Ship this after ember-estree 0.4.4 lands with the flag. Bump the ember-estree dep constraint here to `^0.4.4` in the same PR.

ember-estree's 0.4.2 contract removed Glimmer comment nodes from
`GlimmerTemplate.body` and mirrored them into `ast.comments` as
ESTree `Block` clones. 0.4.3 (PR #31) flipped that default to keep
them in the body with semantic types — load-bearing for zmod (we
rely on `root.find("GlimmerCommentStatement")` and
`root.find("GlimmerMustacheCommentStatement")` walking visitor keys)
but broken for ESLint consumers (directive scanner, indent rule,
Block-filter rules). Upstream ember-estree is moving back to the
0.4.2 default and gating body-retention behind an opt-in flag so
both contracts can coexist cleanly.

Set `keepCommentsInBody: true` in the parse adapter to preserve
zmod's comment-traversal behavior. No user-visible changes — all
106 tests continue to pass, including the 24-case
`tests/glimmer-comments.test.ts` suite.

Depends on ember-estree proposal/option-b-opt-in-keep-comments-in-body.
@johanrd johanrd closed this Apr 23, 2026
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