Skip to content

feat: end types at void, end values at a postfix !, and read delete as an operator - #253

Merged
DylanPiercey merged 2 commits into
mainfrom
dpiercey-ws-marko-invariants-jcdpv7-parserfixes-operators
Sep 28, 2026
Merged

DylanPiercey merged 2 commits into
mainfrom
dpiercey-ws-marko-invariants-jcdpv7-parserfixes-operators

Conversation

@DylanPiercey

@DylanPiercey DylanPiercey commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Fixes expression misparses that changed events only for input that errored or compiled to the wrong code. Inside a type, void is the void type rather than a prefix operator, so a type ending in void (export type H = () => void, (): void {) no longer runs into the next line or the function body. A ! directly after an operand is a TypeScript non-null assertion, so <div title=x! id="a"/> is two attributes; after a keyword operator (typeof!, in!) it stays prefix. delete now continues a value like typeof and void. isValidStatement shares the parser's type-statement look-ahead, and an empty placeholder stops at its error instead of also emitting a placeholder past the input.

Also narrows the AGENTS.md rule: changing events for input that already parses and compiles correctly is breaking, while fixing a misparse ships as a minor.

🤖 Generated with Claude Code

DylanPiercey and others added 2 commits September 28, 2026 09:13
…tor, and stop after an empty-placeholder error

Inside a type, `void` was read as a prefix operator, so a type ending in
`void` (`export type H = () => void`, `<let/x: void>`, `(): void {`) carried
on into the next line, the open tag end, or the function body. In a type it
is always the `void` type, so it is now only a unary keyword outside types.

A trailing `!` was always read as a prefix operator waiting for an operand,
so a TypeScript non-null assertion ending an unenclosed value (`x!`, `f()!`,
`a[0]!`) swallowed what followed. Directly after an operand it is now
postfix; after a keyword operator (`typeof!`, `in!`) it stays prefix.

`isValidStatement` skipped the `type `/`interface `/`declare ` look-ahead
that statement tags use, so it lexed types as JavaScript and disagreed with
the parser. Both now share `prepareStatement`.

`delete` was missing from the prefix keywords, so `<div a=delete x.y/>` split
into two attributes. It now continues like `typeof` and `void`. `return`,
`throw` and `yield` stay out: JavaScript allows no line break after them.

An empty placeholder (`${}`) reported its error and then still emitted
`onPlaceholder` with an end past the input. It now stops at the error.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A misparse fix changes events only for input that errored or compiled to
the wrong code, so it ships as a feature. Raising the parser floor in the
compiler and prettier-plugin-marko together keeps them agreeing on which
values need parentheses.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Sep 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c821771

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
htmljs-parser Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@DylanPiercey
DylanPiercey added this pull request to stack #257 September 28, 2026 16:36
@DylanPiercey DylanPiercey changed the title dpiercey ws marko invariants jcdpv7 parserfixes operators feat: end types at void, end values at a postfix !, and read delete as an operator Sep 28, 2026
@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.95%. Comparing base (80fdd78) to head (c821771).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #253   +/-   ##
=======================================
  Coverage   99.95%   99.95%           
=======================================
  Files          35       35           
  Lines        4611     4652   +41     
  Branches      888      896    +8     
=======================================
+ Hits         4609     4650   +41     
  Misses          2        2           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@DylanPiercey
DylanPiercey merged commit 0c71b1c into main Sep 28, 2026
11 checks passed
@DylanPiercey DylanPiercey self-assigned this Oct 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant