Skip to content

perf: refactor states to be able to parse multiple characters#220

Merged
DylanPiercey merged 2 commits into
mainfrom
refactor-state-parsers
Jun 11, 2026
Merged

perf: refactor states to be able to parse multiple characters#220
DylanPiercey merged 2 commits into
mainfrom
refactor-state-parsers

Conversation

@DylanPiercey

Copy link
Copy Markdown
Contributor

Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in realworld tempaltes.

@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c9c2baf

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 Patch

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

@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 99.91729% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 99.33%. Comparing base (f46cc1f) to head (c9c2baf).

Files with missing lines Patch % Lines
src/states/PARSED_TEXT_CONTENT.ts 98.95% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #220      +/-   ##
==========================================
+ Coverage   92.02%   99.33%   +7.31%     
==========================================
  Files          28       28              
  Lines        1454     4209    +2755     
  Branches      329      773     +444     
==========================================
+ Hits         1338     4181    +2843     
+ Misses         54       14      -40     
+ Partials       62       14      -48     

☔ 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.

@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

The PR refactors the htmljs-parser state machine to shift from per-character callbacks (char, eol, eof) to a unified parse(data, maxPos, activeRange) callback. The StateDefinition interface is updated to this new contract, removing the forward public field from Parser. The main parsing loop is rewritten to repeatedly call each state's parse method until parsing completes. All ~25 parser states are then updated to implement the new callback, moving responsibility for position advancement, newline handling, and termination detection into each state's buffered scanning loop. A validator is refactored to support the new contract, and test fixtures and cases validate the refactored behavior including template literal newlines and attribute operators.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'perf: refactor states to be able to parse multiple characters' directly describes the main change: enabling states to process multiple characters for performance improvement.
Description check ✅ Passed The description states the parser was refactored to allow individual states to process multiple characters, enabling eager scanning and improving performance by ~30%, which aligns with the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor-state-parsers

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed due to a network error.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/states/HTML_CONTENT.ts (1)

138-141: 💤 Low value

Benign but imprecise: negative index read at position 0.

data.charCodeAt(this.pos - 1) reads index -1 when this.pos is 0, returning NaN. While isWhitespaceCode(NaN) correctly returns false (preventing false positives), this reads an undefined index.

In practice, HTML_CONTENT is entered after prior content, so pos > 0 should always hold here. If this assumption is guaranteed, consider adding a comment; otherwise, add this.pos > 0 && as a guard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/states/HTML_CONTENT.ts` around lines 138 - 141, The check in HTML_CONTENT
that does data.charCodeAt(this.pos - 1) can read index -1 when this.pos is 0;
update the condition to guard against that by adding this.pos > 0 && before
calling data.charCodeAt(this.pos - 1) (i.e., change the if that compares code
=== CODE.FORWARD_SLASH && isWhitespaceCode(...) to first ensure this.pos > 0),
referencing the HTML_CONTENT state, CODE.FORWARD_SLASH, isWhitespaceCode, and
this.pos; alternatively, if it is guaranteed pos>0 when HTML_CONTENT runs, add a
short comment stating that invariant instead of the guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.changeset/petite-signs-dance.md:
- Line 5: Fix typos and small phrasing in the changeset sentence that begins
"Refactor parser to allow individual states to process multiple characters."
Replace "realworld" with "real-world", correct "tempaltes" to "templates", and
change "simplifies things some" to "simplifies things somewhat" (or "simplifies
things a bit") so the release note reads clearly and correctly.

---

Nitpick comments:
In `@src/states/HTML_CONTENT.ts`:
- Around line 138-141: The check in HTML_CONTENT that does
data.charCodeAt(this.pos - 1) can read index -1 when this.pos is 0; update the
condition to guard against that by adding this.pos > 0 && before calling
data.charCodeAt(this.pos - 1) (i.e., change the if that compares code ===
CODE.FORWARD_SLASH && isWhitespaceCode(...) to first ensure this.pos > 0),
referencing the HTML_CONTENT state, CODE.FORWARD_SLASH, isWhitespaceCode, and
this.pos; alternatively, if it is guaranteed pos>0 when HTML_CONTENT runs, add a
short comment stating that invariant instead of the guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 018376fe-d258-4708-b663-b6a73d82354d

📥 Commits

Reviewing files that changed from the base of the PR and between f46cc1f and 5dd04ad.

⛔ Files ignored due to path filters (2)
  • src/__tests__/fixtures/attr-grouped-no-whitespace/__snapshots__/attr-grouped-no-whitespace.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/regexp-escaped-newline/__snapshots__/regexp-escaped-newline.expected.txt is excluded by !**/__snapshots__/** and included by **
📒 Files selected for processing (27)
  • .changeset/petite-signs-dance.md
  • src/__tests__/fixtures/attr-grouped-no-whitespace/input.marko
  • src/__tests__/fixtures/regexp-escaped-newline/input.marko
  • src/__tests__/validate.test.ts
  • src/core/Parser.ts
  • src/states/ATTRIBUTE.ts
  • src/states/BEGIN_DELIMITED_HTML_BLOCK.ts
  • src/states/CDATA.ts
  • src/states/CLOSE_TAG.ts
  • src/states/CONCISE_HTML_CONTENT.ts
  • src/states/DECLARATION.ts
  • src/states/DTD.ts
  • src/states/EXPRESSION.ts
  • src/states/HTML_COMMENT.ts
  • src/states/HTML_CONTENT.ts
  • src/states/INLINE_SCRIPT.ts
  • src/states/JS_COMMENT_BLOCK.ts
  • src/states/JS_COMMENT_LINE.ts
  • src/states/OPEN_TAG.ts
  • src/states/PARSED_STRING.ts
  • src/states/PARSED_TEXT_CONTENT.ts
  • src/states/PLACEHOLDER.ts
  • src/states/REGULAR_EXPRESSION.ts
  • src/states/STRING.ts
  • src/states/TAG_NAME.ts
  • src/states/TEMPLATE_STRING.ts
  • src/util/validators.ts

"htmljs-parser": patch
---

Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in realworld tempaltes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Fix typos in the changeset description.

The release note has spelling issues (realworld, tempaltes) that should be corrected before publish.

✏️ Proposed fix
-Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in realworld tempaltes.
+Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in real-world templates.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in realworld tempaltes.
Refactor parser to allow individual states to process multiple characters. This allows for eager scanning, simplifies things some, and improves performance by about 30% in real-world templates.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.changeset/petite-signs-dance.md at line 5, Fix typos and small phrasing in
the changeset sentence that begins "Refactor parser to allow individual states
to process multiple characters." Replace "realworld" with "real-world", correct
"tempaltes" to "templates", and change "simplifies things some" to "simplifies
things somewhat" (or "simplifies things a bit") so the release note reads
clearly and correctly.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/states/STRING.ts (1)

22-43: 💤 Low value

Edge case: backslash at end of input may skip past EOF without proper handling.

If the input ends with an unescaped backslash (e.g., "test\), when this.pos is at the backslash position (maxPos - 1), the code does this.pos += 2, setting pos = maxPos + 1. The loop then exits and emitError is called, which is correct.

However, the escape handling assumes there's always a character after the backslash. While the current behavior (advancing past EOF and emitting error) is functionally acceptable, consider adding a bounds check for clarity and to avoid reading past the string boundary in data.charCodeAt() on subsequent iterations (though the loop condition prevents this).

♻️ Optional: Add explicit bounds check for escaped character
       case CODE.BACK_SLASH:
-        this.pos += 2; // skip \ and escaped char
+        this.pos += 2; // skip \ and escaped char
+        // If backslash was at end, loop will exit and emit EOF error
         break;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/states/STRING.ts` around lines 22 - 43, The parse method in STRING state
can advance past EOF when encountering a trailing backslash; add an explicit
bounds check when handling CODE.BACK_SLASH inside parse so you only do this.pos
+= 2 (or advance and consume the escaped char) if this.pos + 1 < maxPos,
otherwise set this.pos = maxPos (or increment to maxPos), then break to let
emitError(ErrorCode.INVALID_STRING, ...) run; update the BACK_SLASH branch in
parse (referencing CODE.BACK_SLASH, this.pos, maxPos, data.charCodeAt,
exitState, emitError) to avoid calling data.charCodeAt beyond bounds.
src/states/CLOSE_TAG.ts (1)

72-78: 💤 Low value

Side-effect assignment inside object literal reduces readability.

The expression end: (parser.pos += skip) at line 75 advances parser.pos as a side effect while constructing the range object. While this works correctly (start captures the old value, end captures the new value), it's subtle and could confuse future readers.

♻️ Optional: Extract the position update for clarity
+    const closeTagStart = parser.pos;
+    parser.pos += skip;
     // Always succeeds since the closing tag name was matched above.
     ensureExpectedCloseTag(parser, {
-      start: parser.pos,
-      end: (parser.pos += skip),
+      start: closeTagStart,
+      end: parser.pos,
     });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/states/CLOSE_TAG.ts` around lines 72 - 78, The object literal passed to
ensureExpectedCloseTag currently updates parser.pos as a side effect via end:
(parser.pos += skip); instead, first compute the range by saving start =
parser.pos; then advance parser.pos by skip (parser.pos += skip) and set end =
parser.pos, and pass { start, end } to ensureExpectedCloseTag; update the block
around ensureExpectedCloseTag, parser.pos, skip and keep the subsequent
parser.exitState() and return true unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/states/CLOSE_TAG.ts`:
- Around line 72-78: The object literal passed to ensureExpectedCloseTag
currently updates parser.pos as a side effect via end: (parser.pos += skip);
instead, first compute the range by saving start = parser.pos; then advance
parser.pos by skip (parser.pos += skip) and set end = parser.pos, and pass {
start, end } to ensureExpectedCloseTag; update the block around
ensureExpectedCloseTag, parser.pos, skip and keep the subsequent
parser.exitState() and return true unchanged.

In `@src/states/STRING.ts`:
- Around line 22-43: The parse method in STRING state can advance past EOF when
encountering a trailing backslash; add an explicit bounds check when handling
CODE.BACK_SLASH inside parse so you only do this.pos += 2 (or advance and
consume the escaped char) if this.pos + 1 < maxPos, otherwise set this.pos =
maxPos (or increment to maxPos), then break to let
emitError(ErrorCode.INVALID_STRING, ...) run; update the BACK_SLASH branch in
parse (referencing CODE.BACK_SLASH, this.pos, maxPos, data.charCodeAt,
exitState, emitError) to avoid calling data.charCodeAt beyond bounds.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c266bf37-a163-4f2a-a9a2-8723dd497f3e

📥 Commits

Reviewing files that changed from the base of the PR and between 5dd04ad and c9c2baf.

⛔ Files ignored due to path filters (53)
  • package-lock.json is excluded by !**/package-lock.json and included by **
  • src/__tests__/fixtures/argument-attr-ternary/__snapshots__/argument-attr-ternary.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-bound-concise/__snapshots__/attr-bound-concise.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-eof-after-name/__snapshots__/attr-eof-after-name.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-eof-default-value/__snapshots__/attr-eof-default-value.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-eof-spread/__snapshots__/attr-eof-spread.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-eof-unnamed/__snapshots__/attr-eof-unnamed.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-grouped-bound/__snapshots__/attr-grouped-bound.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-grouped-comma/__snapshots__/attr-grouped-comma.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-name-hyphens-concise/__snapshots__/attr-name-hyphens-concise.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-operators-crlf/__snapshots__/attr-operators-crlf.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attr-ternary-as/__snapshots__/attr-ternary-as.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/attrs-crlf/__snapshots__/attrs-crlf.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/cdata-eof/__snapshots__/cdata-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/close-tag-eof/__snapshots__/close-tag-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/comment-js-line-eof/__snapshots__/comment-js-line-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/concise-crlf/__snapshots__/concise-crlf.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/division-after-string/__snapshots__/division-after-string.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/division-after-template/__snapshots__/division-after-template.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/expression-mismatched-group-pair/__snapshots__/expression-mismatched-group-pair.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/html-comment-eof/__snapshots__/html-comment-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/html-text-forward-slash/__snapshots__/html-text-forward-slash.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-attr-type-params/__snapshots__/invalid-attr-type-params.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-close-bracket-in-open-tag/__snapshots__/invalid-close-bracket-in-open-tag.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-code-after-comment-block/__snapshots__/invalid-code-after-comment-block.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-code-after-semicolon-angle/__snapshots__/invalid-code-after-semicolon-angle.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-code-after-semicolon-slash/__snapshots__/invalid-code-after-semicolon-slash.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-line-start-hyphen/__snapshots__/invalid-line-start-hyphen.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-line-start-slash/__snapshots__/invalid-line-start-slash.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-nested-attr-group/__snapshots__/invalid-nested-attr-group.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-tag-type-params-args/__snapshots__/invalid-tag-type-params-args.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/invalid-tag-types-after-args/__snapshots__/invalid-tag-types-after-args.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/mismatched-closing-tag-same-length/__snapshots__/mismatched-closing-tag-same-length.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/mismatched-closing-tag-shorthand/__snapshots__/mismatched-closing-tag-shorthand.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/multiline-html-block-blank-line-crlf/__snapshots__/multiline-html-block-blank-line-crlf.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/multiline-html-block-blank-line/__snapshots__/multiline-html-block-blank-line.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/multiline-html-block-trailing-space/__snapshots__/multiline-html-block-trailing-space.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/open-tag-comments-concise/__snapshots__/open-tag-comments-concise.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/parsed-string-eof/__snapshots__/parsed-string-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/parsed-text-crlf/__snapshots__/parsed-text-crlf.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/parsed-text-empty-close/__snapshots__/parsed-text-empty-close.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/placeholder-empty/__snapshots__/placeholder-empty.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/regexp-eof/__snapshots__/regexp-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/script-mismatched-close/__snapshots__/script-mismatched-close.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/scriptlet-block-space-semi-colon/__snapshots__/scriptlet-block-space-semi-colon.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/semicolon-comments/__snapshots__/semicolon-comments.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/tag-name-placeholder-empty/__snapshots__/tag-name-placeholder-empty.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/tag-name-placeholder-eof/__snapshots__/tag-name-placeholder-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/tag-var-comma-concise/__snapshots__/tag-var-comma-concise.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/template-string-dollar/__snapshots__/template-string-dollar.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/template-string-empty-placeholder/__snapshots__/template-string-empty-placeholder.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/text-block-eof/__snapshots__/text-block-eof.expected.txt is excluded by !**/__snapshots__/** and included by **
  • src/__tests__/fixtures/text-block-trailing-space/__snapshots__/text-block-trailing-space.expected.txt is excluded by !**/__snapshots__/** and included by **
📒 Files selected for processing (71)
  • .c8rc.json
  • package.json
  • src/__tests__/api.test.ts
  • src/__tests__/fixtures/argument-attr-ternary/input.marko
  • src/__tests__/fixtures/attr-bound-concise/input.marko
  • src/__tests__/fixtures/attr-eof-after-name/input.marko
  • src/__tests__/fixtures/attr-eof-default-value/input.marko
  • src/__tests__/fixtures/attr-eof-spread/input.marko
  • src/__tests__/fixtures/attr-eof-unnamed/input.marko
  • src/__tests__/fixtures/attr-grouped-bound/input.marko
  • src/__tests__/fixtures/attr-grouped-comma/input.marko
  • src/__tests__/fixtures/attr-name-hyphens-concise/input.marko
  • src/__tests__/fixtures/attr-operators-crlf/input.marko
  • src/__tests__/fixtures/attr-ternary-as/input.marko
  • src/__tests__/fixtures/attrs-crlf/input.marko
  • src/__tests__/fixtures/cdata-eof/input.marko
  • src/__tests__/fixtures/close-tag-eof/input.marko
  • src/__tests__/fixtures/comment-js-line-eof/input.marko
  • src/__tests__/fixtures/concise-crlf/input.marko
  • src/__tests__/fixtures/division-after-string/input.marko
  • src/__tests__/fixtures/division-after-template/input.marko
  • src/__tests__/fixtures/expression-mismatched-group-pair/input.marko
  • src/__tests__/fixtures/html-comment-eof/input.marko
  • src/__tests__/fixtures/html-text-forward-slash/input.marko
  • src/__tests__/fixtures/invalid-attr-type-params/input.marko
  • src/__tests__/fixtures/invalid-close-bracket-in-open-tag/input.marko
  • src/__tests__/fixtures/invalid-code-after-comment-block/input.marko
  • src/__tests__/fixtures/invalid-code-after-semicolon-angle/input.marko
  • src/__tests__/fixtures/invalid-code-after-semicolon-slash/input.marko
  • src/__tests__/fixtures/invalid-line-start-hyphen/input.marko
  • src/__tests__/fixtures/invalid-line-start-slash/input.marko
  • src/__tests__/fixtures/invalid-nested-attr-group/input.marko
  • src/__tests__/fixtures/invalid-tag-type-params-args/input.marko
  • src/__tests__/fixtures/invalid-tag-types-after-args/input.marko
  • src/__tests__/fixtures/mismatched-closing-tag-same-length/input.marko
  • src/__tests__/fixtures/mismatched-closing-tag-shorthand/input.marko
  • src/__tests__/fixtures/multiline-html-block-blank-line-crlf/input.marko
  • src/__tests__/fixtures/multiline-html-block-blank-line/input.marko
  • src/__tests__/fixtures/multiline-html-block-trailing-space/input.marko
  • src/__tests__/fixtures/open-tag-comments-concise/input.marko
  • src/__tests__/fixtures/parsed-string-eof/input.marko
  • src/__tests__/fixtures/parsed-text-crlf/input.marko
  • src/__tests__/fixtures/parsed-text-empty-close/input.marko
  • src/__tests__/fixtures/placeholder-empty/input.marko
  • src/__tests__/fixtures/regexp-eof/input.marko
  • src/__tests__/fixtures/script-mismatched-close/input.marko
  • src/__tests__/fixtures/scriptlet-block-space-semi-colon/input.marko
  • src/__tests__/fixtures/semicolon-comments/input.marko
  • src/__tests__/fixtures/tag-name-placeholder-empty/input.marko
  • src/__tests__/fixtures/tag-name-placeholder-eof/input.marko
  • src/__tests__/fixtures/tag-var-comma-concise/input.marko
  • src/__tests__/fixtures/template-string-dollar/input.marko
  • src/__tests__/fixtures/template-string-empty-placeholder/input.marko
  • src/__tests__/fixtures/text-block-eof/input.marko
  • src/__tests__/fixtures/text-block-trailing-space/input.marko
  • src/core/Parser.ts
  • src/states/CDATA.ts
  • src/states/CLOSE_TAG.ts
  • src/states/CONCISE_HTML_CONTENT.ts
  • src/states/DECLARATION.ts
  • src/states/DTD.ts
  • src/states/EXPRESSION.ts
  • src/states/HTML_COMMENT.ts
  • src/states/HTML_CONTENT.ts
  • src/states/JS_COMMENT_BLOCK.ts
  • src/states/JS_COMMENT_LINE.ts
  • src/states/PLACEHOLDER.ts
  • src/states/REGULAR_EXPRESSION.ts
  • src/states/STRING.ts
  • src/states/TAG_NAME.ts
  • src/util/validators.ts
💤 Files with no reviewable changes (1)
  • src/states/TAG_NAME.ts
✅ Files skipped from review due to trivial changes (35)
  • src/tests/fixtures/invalid-line-start-slash/input.marko
  • src/tests/fixtures/comment-js-line-eof/input.marko
  • src/tests/fixtures/tag-name-placeholder-empty/input.marko
  • src/tests/fixtures/html-text-forward-slash/input.marko
  • src/tests/fixtures/invalid-nested-attr-group/input.marko
  • src/tests/fixtures/parsed-text-crlf/input.marko
  • src/tests/fixtures/regexp-eof/input.marko
  • src/tests/fixtures/attrs-crlf/input.marko
  • src/tests/fixtures/text-block-trailing-space/input.marko
  • src/tests/fixtures/invalid-close-bracket-in-open-tag/input.marko
  • src/tests/fixtures/argument-attr-ternary/input.marko
  • src/tests/fixtures/invalid-code-after-semicolon-angle/input.marko
  • src/tests/fixtures/scriptlet-block-space-semi-colon/input.marko
  • src/tests/fixtures/attr-name-hyphens-concise/input.marko
  • src/tests/fixtures/template-string-dollar/input.marko
  • src/tests/fixtures/attr-grouped-comma/input.marko
  • src/tests/fixtures/invalid-code-after-comment-block/input.marko
  • src/tests/fixtures/tag-var-comma-concise/input.marko
  • src/tests/fixtures/parsed-string-eof/input.marko
  • src/tests/fixtures/parsed-text-empty-close/input.marko
  • src/tests/fixtures/mismatched-closing-tag-shorthand/input.marko
  • src/tests/fixtures/invalid-tag-type-params-args/input.marko
  • src/tests/fixtures/invalid-code-after-semicolon-slash/input.marko
  • .c8rc.json
  • src/tests/fixtures/attr-eof-spread/input.marko
  • src/tests/fixtures/invalid-tag-types-after-args/input.marko
  • src/tests/fixtures/attr-operators-crlf/input.marko
  • src/tests/fixtures/template-string-empty-placeholder/input.marko
  • src/tests/fixtures/script-mismatched-close/input.marko
  • src/tests/fixtures/attr-eof-unnamed/input.marko
  • src/tests/fixtures/attr-grouped-bound/input.marko
  • src/tests/fixtures/mismatched-closing-tag-same-length/input.marko
  • src/tests/fixtures/division-after-template/input.marko
  • src/tests/fixtures/multiline-html-block-blank-line-crlf/input.marko
  • src/tests/fixtures/expression-mismatched-group-pair/input.marko
🚧 Files skipped from review as they are similar to previous changes (10)
  • src/states/DECLARATION.ts
  • src/states/PLACEHOLDER.ts
  • src/states/HTML_COMMENT.ts
  • src/states/JS_COMMENT_BLOCK.ts
  • src/states/HTML_CONTENT.ts
  • src/states/REGULAR_EXPRESSION.ts
  • src/states/CONCISE_HTML_CONTENT.ts
  • src/util/validators.ts
  • src/states/CDATA.ts
  • src/states/EXPRESSION.ts

@DylanPiercey DylanPiercey merged commit 83d0f84 into main Jun 11, 2026
11 checks passed
@DylanPiercey DylanPiercey deleted the refactor-state-parsers branch June 11, 2026 23:45
@DylanPiercey DylanPiercey self-assigned this Jun 11, 2026
@github-project-automation github-project-automation Bot moved this to Done in Roadmap Jun 11, 2026
@github-actions github-actions Bot mentioned this pull request Jun 11, 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