Skip to content

Match the template block of a semicolon-less TOC in multi-template files - #49

Merged
johanrd merged 1 commit into
mainfrom
fix-toc-template-range
Aug 28, 2026
Merged

Match the template block of a semicolon-less TOC in multi-template files#49
johanrd merged 1 commit into
mainfrom
fix-toc-template-range

Conversation

@johanrd

@johanrd johanrd commented Aug 28, 2026

Copy link
Copy Markdown
Owner

readGts resolves a component in a multi-template .gts by finding the named declaration in a copy of the file with the templates blanked, then picking the <template> block inside that declaration's range. For the expression form without a trailing semicolon —

export const Bar = <template>
  <div class='bar'>{{yield}}</div>
</template>

— the blanked initializer leaves export const Bar = with nothing after it, so the statement's range ends at = and no block is ever "inside" it. The lookup returned null silently and the consumer kept whatever the TypeScript side had said (usually transparent), losing the <div> substitution. Surfaced on a real app where <HeaderLoadingBar/> (a semicolon-less TOC exported from a multi-template file) never resolved.

Fix: accept a block that starts inside the range, or follows it across whitespace only. Regression test with a two-TOC fixture (Bar<div>, Baz<span>), red before / green after; the full suite stays at 289 + 1 expected fail.

Independent of #48 (found while comparing its two backends; affects both).

Cowritten by Claude

`readGts` picks the template block that lies inside the named
declaration's range, computed on the file with templates blanked. For
`export const X = <template>…</template>` without a trailing semicolon
the blanked initializer leaves the statement ending at `=`, so no block
was ever inside the range and the lookup failed silently; the consumer
fell back to the TypeScript-side result (typically `transparent`).

Accept a block that starts inside the range or follows it across
whitespace only.

Cowritten by Claude

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The change is small, focused, and well-tested, but block-matching logic in the resolver is subtle enough that final human review is warranted before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR fixes a resolution gap in readGts (lib/resolver/template-source.ts) for multi-template .gts/.gjs files. When a template-only component is written in expression form without a trailing semicolon (export const Bar = <template>…</template>), blanking the initializer before the TypeScript parse leaves the statement range ending at =, so no template block was ever considered "inside" the declaration's range. The lookup returned null silently, causing the consumer to keep the (usually transparent) TypeScript-side result and lose the real element substitution. The fix relaxes the block-matching condition to also accept a block that starts at or after the range and is separated from it by whitespace only.

Changes:

  • Replace the strict "block fully contained in declaration range" check with one that accepts a block starting inside the range, or immediately following it across whitespace only.
  • Add a regression fixture (toc-expression-no-semicolon.gts) with two semicolon-less expression-form TOCs (Bar<div>, Baz<span>).
  • Add a unit test asserting both components resolve to their correct template blocks by name.
File summaries
File Description
lib/resolver/template-source.ts Relaxes the template-block match in readGts to handle semicolon-less expression-form TOCs whose blanked range ends at =.
test/glint-fixtures/toc-expression-no-semicolon.gts New fixture with two semicolon-less expression-form template-only components.
test/resolver/template-source.test.ts New regression test verifying Bar/Baz resolve to the correct template by name.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 0
  • Review effort level: Balanced

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@johanrd
johanrd merged commit 85d73cb into main Aug 28, 2026
3 checks passed
@johanrd johanrd added the bug Something isn't working label Aug 28, 2026
@github-actions github-actions Bot mentioned this pull request Aug 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants