Skip to content

Commit d9cf7a2

Browse files
Merge pull request #19 from andsmedeiros/main
Fix ASI not firing before <template> in class bodies
2 parents 2376e3c + 7587177 commit d9cf7a2

2 files changed

Lines changed: 53 additions & 0 deletions

File tree

src/scanner.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,5 +63,33 @@ bool tree_sitter_glimmer_javascript_external_scanner_scan(void *payload, TSLexer
6363
if (valid_symbols[RAW_TEXT]) {
6464
return scan_raw_text(payload, lexer);
6565
}
66+
67+
// The upstream JS scanner refuses to insert an automatic semicolon before `<`
68+
// because in standard JS it could be a less-than operator. In GJS/GTS, `<template>`
69+
// is a valid class body member, so we handle the AUTOMATIC_SEMICOLON case ourselves:
70+
// we call scan_automatic_semicolon directly (accessible from the included scanner.h),
71+
// and when it refuses due to `<`, we check whether `<template>` follows and insert
72+
// the semicolon if so.
73+
if (valid_symbols[AUTOMATIC_SEMICOLON]) {
74+
bool scanned_comment = false;
75+
bool result = scan_automatic_semicolon(lexer, !valid_symbols[LOGICAL_OR], &scanned_comment);
76+
if (!result && !scanned_comment) {
77+
if (lexer->lookahead == '<') {
78+
skip(lexer);
79+
const char *tag = "template>";
80+
for (unsigned i = 0; tag[i] != '\0'; i++) {
81+
if ((char)lexer->lookahead != tag[i]) return false;
82+
skip(lexer);
83+
}
84+
lexer->result_symbol = AUTOMATIC_SEMICOLON;
85+
return true;
86+
}
87+
if (valid_symbols[TERNARY_QMARK] && lexer->lookahead == '?') {
88+
return scan_ternary_qmark(lexer);
89+
}
90+
}
91+
return result;
92+
}
93+
6694
return tree_sitter_javascript_external_scanner_scan(payload, lexer, valid_symbols);
6795
}

test/corpus/glimmer.txt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,31 @@ class InClass {
155155
(glimmer_closing_tag
156156
(glimmer_template_tag_name))))))
157157

158+
============================================
159+
Class Component with Field Without Semicolon
160+
============================================
161+
162+
class Foo {
163+
foo = bar
164+
<template>{{this.foo}}</template>
165+
}
166+
167+
----
168+
169+
(program
170+
(class_declaration
171+
(identifier)
172+
(class_body
173+
(field_definition
174+
(property_identifier)
175+
(identifier))
176+
(glimmer_template
177+
(glimmer_opening_tag
178+
(glimmer_template_tag_name))
179+
(raw_text)
180+
(glimmer_closing_tag
181+
(glimmer_template_tag_name))))))
182+
158183
============================================
159184
JS Regex Evasion
160185
============================================

0 commit comments

Comments
 (0)