Skip to content

Use void placeholders so statement-start templates survive ASI - #78

Merged
NullVoxPopuli merged 1 commit into
NullVoxPopuli:mainfrom
NullVoxPopuli-ai-agent:void-placeholder
Aug 24, 2026
Merged

NullVoxPopuli merged 1 commit into
NullVoxPopuli:mainfrom
NullVoxPopuli-ai-agent:void-placeholder

Conversation

@NullVoxPopuli-ai-agent

Copy link
Copy Markdown
Contributor

In a file without semicolons, a module-level template after an expression statement disappears:

const x = 1
const y = x
<template>{{x}}</template>

The placeholder JS is const y = x\n\...` which parses as the tagged template ``x...``, soprogram.bodyhas twoVariableDeclarations and no GlimmerTemplate. Same for setup()\n, arr[0]\n`, etc.

This PR emits void \...`instead of a bare backtick literal for expression templates (class members keepstatic{`...`}). voidcannot continue an expression, so ASI applies exactly as it does for the real; being a keyword, it adds no identifier reference for scope analysis to trip over (unlike a tag identifier). Length budget is unchanged (void + two backticks = 7 chars, under the 10-char` tag).

Consumer-visible change: templateInfos[].placeholder (custom-parser path) is now a UnaryExpression rather than a TemplateLiteral, and the TS node it maps to is void-typed rather than string-typed. Both were stand-ins; flagging in case ember-eslint-parser inspects the placeholder type.

Tests added for the two ASI shapes; the custom-parser tests that asserted on the placeholder type are updated.

Found while wiring glint's rewriteModuleStandalone (typed-ember/glint#1226) onto ember-estree.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FsXgxh6vNRWMCNcAQ3g6TN

@NullVoxPopuli NullVoxPopuli added bug Something isn't working ASI labels Aug 24, 2026
A bare backtick placeholder after an unterminated expression statement
continues it as a tagged template: `const y = x\n<template>` became
`x`...`` and the template vanished from the tree. `void` cannot continue
an expression, so automatic semicolon insertion applies exactly as it
does for the real `<template>`, and being a keyword it adds no identifier
reference for scope analysis.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FsXgxh6vNRWMCNcAQ3g6TN
@NullVoxPopuli
NullVoxPopuli merged commit 3131403 into NullVoxPopuli:main Aug 24, 2026
4 checks passed
@NullVoxPopuli
NullVoxPopuli deleted the void-placeholder branch August 24, 2026 23:52
@github-actions github-actions Bot mentioned this pull request Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ASI bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants