Skip to content
82 changes: 16 additions & 66 deletions grammar.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ module.exports = grammar({
[$._record_field_name, $.record_pattern],
[$.decorator],
[$._statement, $._one_or_more_statements],
[$._simple_extension],
[$._inline_type, $.function_type_parameters],
[$.primary_expression, $.parameter, $._pattern],
[$.parameter, $._pattern],
Expand Down Expand Up @@ -1141,65 +1140,13 @@ module.exports = grammar({
))
)),

extension_expression: $ => prec('call', seq(
extension_expression: $ => prec.right(seq(
repeat1('%'),
choice(
$._raw_js_extension,
$._raw_gql_extension,
$._simple_extension,
),
)),

_simple_extension: $ => seq(
$.extension_identifier,
optional($._extension_expression_payload),
),

_raw_js_extension: $ => seq(
alias(token('raw'), $.extension_identifier),
'(',
alias($._raw_js, $.expression_statement),
')',
),

_raw_js: $ => choice(
alias($._raw_js_template_string, $.template_string),
alias($._raw_js_string, $.string),
),

_raw_js_string: $ => alias($.string, $.raw_js),

_raw_js_template_string: $ => seq(
token(seq(
optional(choice(
'j',
'js',
)),
'`',
)),
alias(repeat($._template_string_content), $.raw_js),
'`',
),

_raw_gql_extension: $ => seq(
alias(token('graphql'), $.extension_identifier),
'(',
alias($._raw_gql, $.expression_statement),
')',
),

_raw_gql: $ => choice(
alias($._raw_gql_template_string, $.template_string),
alias($._raw_gql_string, $.string),
),

_raw_gql_string: $ => alias($.string, $.raw_gql),

_raw_gql_template_string: $ => seq(
'`',
alias(repeat($._template_string_content), $.raw_gql),
'`',
),
optional(
$._extension_expression_payload,
)
)),

_extension_expression_payload: $ => seq(
'(',
Expand Down Expand Up @@ -1441,18 +1388,21 @@ module.exports = grammar({
)),
'`',
)),
repeat($._template_string_content),
$.template_string_content,
'`'
),

_template_string_content: $ => choice(
$._template_chars,
$.template_substitution,
choice(
alias('\\`', $.escape_sequence),
$.escape_sequence,
template_string_content: $ =>
repeat1(
choice(
$._template_chars,
$.template_substitution,
choice(
alias('\\`', $.escape_sequence),
$.escape_sequence,
)
),
),
),

template_substitution: $ => choice(
seq('$', $.value_identifier),
Expand Down
22 changes: 20 additions & 2 deletions queries/injections.scm
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
(raw_js) @javascript
(raw_gql) @graphql
(comment) @comment

; %re
(extension_expression
(extension_identifier) @_name
(#eq? @_name "re")
(expression_statement (_) @regex))

; %raw
(extension_expression
(extension_identifier) @_name
(#eq? @_name "raw")
(expression_statement
(_ (_) @javascript)))

; %graphql
(extension_expression
(extension_identifier) @_name
(#eq? @_name "graphql")
(expression_statement
(_ (_) @graphql)))
9 changes: 4 additions & 5 deletions test/corpus/expressions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1118,8 +1118,7 @@ module Test = %graphql(`
(extension_identifier)
(expression_statement
(string
(raw_js
(string_fragment))))))
(string_fragment)))))
(expression_statement
(extension_expression
(extension_identifier)
Expand Down Expand Up @@ -1148,7 +1147,7 @@ module Test = %graphql(`
(extension_identifier)
(expression_statement
(template_string
(raw_js
(template_string_content
(escape_sequence)
(escape_sequence))))))
(let_binding
Expand All @@ -1157,7 +1156,7 @@ module Test = %graphql(`
(extension_identifier)
(expression_statement
(template_string
(raw_js
(template_string_content
(escape_sequence)
(escape_sequence))))))
(module_declaration
Expand All @@ -1166,7 +1165,7 @@ module Test = %graphql(`
(extension_identifier)
(expression_statement
(template_string
(raw_gql))))))
(template_string_content))))))

===========================================
Raise expression
Expand Down
51 changes: 29 additions & 22 deletions test/corpus/literals.txt
Original file line number Diff line number Diff line change
Expand Up @@ -129,23 +129,30 @@ The caller should either handle this error, or expect that exit code.`
----

(source_file
(expression_statement (template_string))
(expression_statement (template_string))
(expression_statement (template_string))
(expression_statement (template_string
(template_substitution
(binary_expression (number) (number)))
(template_substitution
(binary_expression (number) (number)))))
(expression_statement (template_string
(escape_sequence)
(template_substitution (call_expression
(value_identifier)
(arguments (string (string_fragment)))))
(escape_sequence)
(template_substitution (value_identifier))))
(expression_statement (template_string))
(expression_statement (template_string (escape_sequence))))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content)))
(expression_statement
(template_string
(template_string_content
(template_substitution
(binary_expression (number) (number)))
(template_substitution
(binary_expression (number) (number))))))
(expression_statement
(template_string
(template_string_content
(escape_sequence)
(template_substitution
(call_expression
(value_identifier)
(arguments
(string
(string_fragment)))))
(escape_sequence)
(template_substitution (value_identifier)))))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content (escape_sequence)))))

============================================
Tricky template strings
Expand All @@ -160,11 +167,11 @@ Tricky template strings
---

(source_file
(expression_statement (template_string))
(expression_statement (template_string))
(expression_statement (template_string))
(expression_statement (template_string))
(expression_statement (template_string)))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content)))
(expression_statement (template_string (template_string_content))))

============================================
Characters
Expand Down
2 changes: 1 addition & 1 deletion test/corpus/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ external add: (
(parameter
(type_identifier_path (module_identifier) (type_identifier)))
(parameter
(decorator (decorator_identifier) (decorator_arguments (template_string)))
(decorator (decorator_identifier) (decorator_arguments (template_string (template_string_content))))
(type_identifier))
(parameter
(decorator (decorator_identifier) (decorator_arguments (string)))
Expand Down
18 changes: 18 additions & 0 deletions test/manual/embedded.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// NOT AN AUTOMATED TEST.
//
// Looks like Tree-sitter test framework does not allow to test
// for correct language embedding. So, this file is just a showcase
// to observe results with eyes.
//
// You should see comprehensive highlighting for constructs inside
// strings. That is, they should not look like plain strings if
// you have corresponding grammar installed.

// :TSInstall javascript
let inc = %raw(`function(x) {return x + 1;}`)

// :TSInstall graphql
let gql = %graphql(`{ hero { name } }`)

// :TSInstall regex
let re = %re(`^[A-Z][a-z0-9]*$`)