Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7267cc4
feat(js_parser): add Glimmer template support for .gjs and .gts files
wagenet Nov 14, 2025
a062211
[autofix.ci] apply automated fixes
autofix-ci[bot] Nov 14, 2025
9d4cc68
Apply feedback
wagenet Nov 14, 2025
69c9f83
Add docstrings
wagenet Nov 14, 2025
8f04ab2
fix(js_parser): address CodeRabbit review suggestions for Glimmer tem…
wagenet Nov 14, 2025
1798ec7
test(js_parser): reorganize glimmer test files into subdirectories
wagenet Nov 14, 2025
44f3d4e
test(js_parser): add comprehensive backtracking tests for glimmer tem…
wagenet Nov 14, 2025
a432a44
refactor(js_parser): improve glimmer lexer with explicit lookahead co…
wagenet Nov 14, 2025
0541444
refactor(js_parser): derive parser options from file source type
wagenet Nov 14, 2025
0471037
refactor(service): update file handlers to use new parser options API
wagenet Nov 14, 2025
17067fc
docs(js_formatter): simplify verbose Glimmer template docstring
wagenet Nov 14, 2025
af7fac7
fix(js_parser): address CodeRabbit review - fix compilation errors fr…
wagenet Nov 15, 2025
ae263fb
chore: remove unused imports after parser API changes
wagenet Nov 15, 2025
99e2245
feat(html): add Glimmer variant to HtmlFileSource
wagenet Nov 14, 2025
a415b6f
feat(html): add Glimmer token types
wagenet Nov 14, 2025
fa31069
feat(html): define Glimmer grammar and AST nodes
wagenet Nov 14, 2025
e18aa3b
feat(html): add complete Glimmer grammar with all syntax constructs
wagenet Nov 14, 2025
e6fad6b
feat(html): implement Glimmer mustache comment parsing
wagenet Nov 14, 2025
cbf3fb3
feat(html): implement Glimmer block helper parsing
wagenet Nov 14, 2025
1b707cc
fix(html_parser): restrict DOCTYPE keyword to DOCTYPE context only
wagenet Nov 15, 2025
b55d62a
fix(html_parser): add error for empty path after @ symbol
wagenet Nov 15, 2025
03eb7bb
fix(html_parser): check for 'as' keyword specifically in block params
wagenet Nov 15, 2025
98213dd
fix(html_parser): add diagnostic for unterminated mustache comments
wagenet Nov 15, 2025
ce1070a
fix(html_parser): add diagnostic for missing block helper closing
wagenet Nov 15, 2025
4d4b99a
fix(html_parser): improve error recovery for missing }}}
wagenet Nov 15, 2025
9f762e2
fix(html_formatter): use method call for separator access
wagenet Nov 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .changeset/glimmer-template-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
"@biomejs/biome": minor
---

Added support for Glimmer template files (`.gjs` and `.gts`). Biome can now parse, format, and lint Glimmer Component files used in Ember.js applications.

Glimmer templates are recognized using the `<template>...</template>` syntax and can appear in:
- Variable assignments: `const Tpl = <template>...</template>;`
- Class bodies: `class C { <template>...</template> }`
- Expression contexts
- Single unassigned templates (treated as default exports)

**Phase 1 Implementation Notes:**
- Template content is treated as **opaque tokens** - the content is preserved exactly as written without internal parsing or linting
- The template syntax itself is validated (e.g., checking for unclosed tags)
- Templates work with whitespace in the opening tag (e.g., `<template >`, `<template\n>`)
- LSP language IDs "gjs" and "gts" are now recognized
- Future phases will add internal template parsing and linting support

The template content is preserved as-is during formatting, and the parser provides diagnostics for unclosed template tags.
8 changes: 4 additions & 4 deletions crates/biome_grit_patterns/src/grit_js_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::{
grit_analysis_ext::GritAnalysisExt, grit_target_language::GritTargetParser,
grit_tree::GritTargetTree,
};
use biome_js_parser::{JsParserOptions, parse};
use biome_js_parser::{JsParserOptions, parse, parse_with_options};
use biome_js_syntax::{JsFileSource, JsLanguage};
use biome_parser::AnyParse;
use camino::Utf8Path;
Expand Down Expand Up @@ -34,7 +34,7 @@ impl GritTargetParser for GritJsParser {
_ => JsFileSource::ts(),
};

parse(source, source_type, JsParserOptions::default()).into()
parse(source, source_type).into()
}
}

Expand All @@ -48,7 +48,7 @@ impl Parser for GritJsParser {
logs: &mut AnalysisLogs,
_old_tree: FileOrigin<'_, GritTargetTree>,
) -> Option<GritTargetTree> {
let parse_result = parse(
let parse_result = parse_with_options(
body,
JsFileSource::tsx(),
JsParserOptions::default().with_metavariables(),
Expand All @@ -75,7 +75,7 @@ impl Parser for GritJsParser {
|src: &str| src.len() as u32
};

let parse_result = parse(
let parse_result = parse_with_options(
&context,
JsFileSource::tsx(),
JsParserOptions::default().with_metavariables(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@ pub fn kind_by_name(node_name: &str) -> Option<JsSyntaxKind> {
"JsFunctionExpression" => lang::JsFunctionExpression::KIND_SET.iter().next(),
"JsGetterClassMember" => lang::JsGetterClassMember::KIND_SET.iter().next(),
"JsGetterObjectMember" => lang::JsGetterObjectMember::KIND_SET.iter().next(),
"JsGlimmerTemplate" => lang::JsGlimmerTemplate::KIND_SET.iter().next(),
"JsIdentifierAssignment" => lang::JsIdentifierAssignment::KIND_SET.iter().next(),
"JsIdentifierBinding" => lang::JsIdentifierBinding::KIND_SET.iter().next(),
"JsIdentifierExpression" => lang::JsIdentifierExpression::KIND_SET.iter().next(),
Expand Down
Loading