From aa5907747b731662fbe3633b1f46d40a3b591e4e Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Wed, 19 Jul 2023 23:40:59 +0200 Subject: [PATCH 1/7] Fix interpolated string identifiers --- corpus/expressions.txt | 4 ++-- corpus/literals.txt | 32 +++++++++++++++++++++++++++++--- corpus/patterns.txt | 6 +++--- grammar.js | 22 +++++++++++++++++++++- queries/scala/highlights.scm | 11 ++++++++++- queries/scala/locals.scm | 2 ++ 6 files changed, 67 insertions(+), 10 deletions(-) diff --git a/corpus/expressions.txt b/corpus/expressions.txt index b98c8e9..aca5a72 100644 --- a/corpus/expressions.txt +++ b/corpus/expressions.txt @@ -706,9 +706,9 @@ def matchTest(x: Int): String = x match { (identifier) (interpolated_string (interpolation - (identifier)) + (dollar_identifier)) (interpolation - (identifier)))) + (dollar_identifier)))) (infix_expression (identifier) (operator_identifier) diff --git a/corpus/literals.txt b/corpus/literals.txt index 2e8ad65..7d13c33 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -38,6 +38,10 @@ val string3 = raw"Not a new line \n${ha}" val string4 = s""" works even in multiline strings, ${name} """ + +val string5 = s"$works${without}$spaces" + +val string6 = s"$a$b" -------------------------------------------------------------------------------- (compilation_unit @@ -47,7 +51,7 @@ works even in multiline strings, ${name} (identifier) (interpolated_string (interpolation - (identifier)) + (dollar_identifier)) (interpolation (block (identifier)))))) @@ -57,7 +61,7 @@ works even in multiline strings, ${name} (identifier) (interpolated_string (interpolation - (identifier))))) + (dollar_identifier))))) (val_definition (identifier) (interpolated_string_expression @@ -73,7 +77,29 @@ works even in multiline strings, ${name} (interpolated_string (interpolation (block - (identifier))))))) + (identifier)))))) + (val_definition + (identifier) + (interpolated_string_expression + (identifier) + (interpolated_string + (interpolation + (dollar_identifier)) + (interpolation + (block + (identifier))) + (interpolation + (dollar_identifier))))) + (val_definition + (identifier) + (interpolated_string_expression + (identifier) + (interpolated_string + (interpolation + (dollar_identifier)) + (interpolation + (dollar_identifier)))))) + ================================================================================ Integer literals diff --git a/corpus/patterns.txt b/corpus/patterns.txt index a175314..b894a5d 100644 --- a/corpus/patterns.txt +++ b/corpus/patterns.txt @@ -104,13 +104,13 @@ def showNotification(notification: Notification): String = { (match_expression (identifier) (case_block (case_clause (case_class_pattern (type_identifier) (identifier) (identifier) (wildcard)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier)))))))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier)))))))))) ============================ Infix patterns diff --git a/grammar.js b/grammar.js index e3b848f..8163d31 100644 --- a/grammar.js +++ b/grammar.js @@ -1388,6 +1388,26 @@ module.exports = grammar({ _alpha_identifier: $ => /[\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\$\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F\$][\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\$\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F0-9\$_\p{Ll}]*(_[\-!#%&*+\/\\:<=>?@\u005e\u007c~\p{Sm}\p{So}]+)?/, + /** + * Despite what the lexical syntax suggests, the alphaid rule doesn't apply + * to identifiers that aren't in blocks in interpolated strings (e.g. $foo). + * A more accurate description is given in + * https://www.scala-lang.org/files/archive/spec/2.13/01-lexical-syntax.html + * where it states (regarding dollar sign escapes in interpolated strings) that + * """ + * The simpler form consists of a ‘$’-sign followed by an identifier starting + * with a letter and followed only by letters, digits, and underscore characters + * """ + * where "letters" does not include the $ character. + * + * This rule is similar to the _alpha_identifier rule, with the differences + * being that the $ character is excluded, along with the _(operator_chars) + * suffix and can be approximated as + * /[A-Za-z_][A-Z_a-z0-9]/; + */ + dollar_identifier: $ => + /[\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F][\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F0-9_\p{Ll}]*/, + _backquoted_id: $ => /`[^\n`]+`/, _identifier: $ => choice($.identifier, $.operator_identifier), @@ -1492,7 +1512,7 @@ module.exports = grammar({ _interpolated_multiline_string_start: $ => '"""', - interpolation: $ => seq("$", choice($.identifier, $.block)), + interpolation: $ => seq("$", choice($.dollar_identifier, $.block)), interpolated_string: $ => choice( diff --git a/queries/scala/highlights.scm b/queries/scala/highlights.scm index ed20b27..801f6ad 100644 --- a/queries/scala/highlights.scm +++ b/queries/scala/highlights.scm @@ -25,7 +25,7 @@ (self_type (identifier) @parameter) -(interpolation (identifier) @none) +(interpolation (dollar_identifier) @none) (interpolation (block) @none) ;; types @@ -256,6 +256,15 @@ (#match? @function.builtin "^super$") ) +((dollar_identifier) @type (#match? @type "^[A-Z]")) +((dollar_identifier) @variable.builtin + (#match? @variable.builtin "^this$")) + +( + (dollar_identifier) @function.builtin + (#match? @function.builtin "^super$") +) + ;; Scala CLI using directives (using_directive_key) @parameter (using_directive_value) @string diff --git a/queries/scala/locals.scm b/queries/scala/locals.scm index 8eaa75e..b8b3c33 100644 --- a/queries/scala/locals.scm +++ b/queries/scala/locals.scm @@ -27,3 +27,5 @@ name: (identifier) @local.definition) (identifier) @local.reference + +(dollar_identifier) @local.reference From 3aa86705b4f2379b51cfa7b9639208bebc6b8b35 Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Thu, 20 Jul 2023 14:20:54 +0200 Subject: [PATCH 2/7] Fix double dollar escapes --- corpus/literals.txt | 11 ++++++++++- grammar.js | 6 ++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/corpus/literals.txt b/corpus/literals.txt index 7d13c33..3714332 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -42,6 +42,8 @@ works even in multiline strings, ${name} val string5 = s"$works${without}$spaces" val string6 = s"$a$b" + +val string7 = s"$$ $a" -------------------------------------------------------------------------------- (compilation_unit @@ -98,7 +100,14 @@ val string6 = s"$a$b" (interpolation (dollar_identifier)) (interpolation - (dollar_identifier)))))) + (dollar_identifier))))) + (val_definition + (identifier) + (interpolated_string_expression + (identifier) + (interpolated_string + (interpolation + (dollar_identifier)))))) ================================================================================ diff --git a/grammar.js b/grammar.js index 8163d31..b7b8479 100644 --- a/grammar.js +++ b/grammar.js @@ -1512,18 +1512,20 @@ module.exports = grammar({ _interpolated_multiline_string_start: $ => '"""', + _dollar_escape: $ => seq('$', '$'), + interpolation: $ => seq("$", choice($.dollar_identifier, $.block)), interpolated_string: $ => choice( seq( $._interpolated_string_start, - repeat(seq($._interpolated_string_middle, $.interpolation)), + repeat(seq($._interpolated_string_middle, choice($._dollar_escape, $.interpolation))), $._interpolated_string_end, ), seq( $._interpolated_multiline_string_start, - repeat(seq($._interpolated_multiline_string_middle, $.interpolation)), + repeat(seq($._interpolated_multiline_string_middle, choice($._dollar_escape, $.interpolation))), $._interpolated_multiline_string_end, ), ), From f1c076472271952b1008b394889ef05874a83f4c Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Thu, 20 Jul 2023 14:22:48 +0200 Subject: [PATCH 3/7] Remove unnecessary highlighting queries --- queries/scala/highlights.scm | 9 --------- 1 file changed, 9 deletions(-) diff --git a/queries/scala/highlights.scm b/queries/scala/highlights.scm index 801f6ad..6ff8b00 100644 --- a/queries/scala/highlights.scm +++ b/queries/scala/highlights.scm @@ -256,15 +256,6 @@ (#match? @function.builtin "^super$") ) -((dollar_identifier) @type (#match? @type "^[A-Z]")) -((dollar_identifier) @variable.builtin - (#match? @variable.builtin "^this$")) - -( - (dollar_identifier) @function.builtin - (#match? @function.builtin "^super$") -) - ;; Scala CLI using directives (using_directive_key) @parameter (using_directive_value) @string From dda875eae9fb5137dc8d58432896a69d4289f4ea Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Thu, 20 Jul 2023 14:42:40 +0200 Subject: [PATCH 4/7] Rename interpolation_identifier --- corpus/expressions.txt | 4 ++-- corpus/literals.txt | 14 +++++++------- corpus/patterns.txt | 6 +++--- grammar.js | 4 ++-- queries/scala/highlights.scm | 2 +- queries/scala/locals.scm | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/corpus/expressions.txt b/corpus/expressions.txt index aca5a72..5f76897 100644 --- a/corpus/expressions.txt +++ b/corpus/expressions.txt @@ -706,9 +706,9 @@ def matchTest(x: Int): String = x match { (identifier) (interpolated_string (interpolation - (dollar_identifier)) + (interpolation_identifier)) (interpolation - (dollar_identifier)))) + (interpolation_identifier)))) (infix_expression (identifier) (operator_identifier) diff --git a/corpus/literals.txt b/corpus/literals.txt index 3714332..5a99a20 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -53,7 +53,7 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (dollar_identifier)) + (interpolation_identifier)) (interpolation (block (identifier)))))) @@ -63,7 +63,7 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (dollar_identifier))))) + (interpolation_identifier))))) (val_definition (identifier) (interpolated_string_expression @@ -86,28 +86,28 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (dollar_identifier)) + (interpolation_identifier)) (interpolation (block (identifier))) (interpolation - (dollar_identifier))))) + (interpolation_identifier))))) (val_definition (identifier) (interpolated_string_expression (identifier) (interpolated_string (interpolation - (dollar_identifier)) + (interpolation_identifier)) (interpolation - (dollar_identifier))))) + (interpolation_identifier))))) (val_definition (identifier) (interpolated_string_expression (identifier) (interpolated_string (interpolation - (dollar_identifier)))))) + (interpolation_identifier)))))) ================================================================================ diff --git a/corpus/patterns.txt b/corpus/patterns.txt index b894a5d..eb42ab1 100644 --- a/corpus/patterns.txt +++ b/corpus/patterns.txt @@ -104,13 +104,13 @@ def showNotification(notification: Notification): String = { (match_expression (identifier) (case_block (case_clause (case_class_pattern (type_identifier) (identifier) (identifier) (wildcard)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (dollar_identifier)) (interpolation (dollar_identifier)))))))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier)))))))))) ============================ Infix patterns diff --git a/grammar.js b/grammar.js index b7b8479..dfb8f04 100644 --- a/grammar.js +++ b/grammar.js @@ -1405,7 +1405,7 @@ module.exports = grammar({ * suffix and can be approximated as * /[A-Za-z_][A-Z_a-z0-9]/; */ - dollar_identifier: $ => + interpolation_identifier: $ => /[\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F][\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F0-9_\p{Ll}]*/, _backquoted_id: $ => /`[^\n`]+`/, @@ -1514,7 +1514,7 @@ module.exports = grammar({ _dollar_escape: $ => seq('$', '$'), - interpolation: $ => seq("$", choice($.dollar_identifier, $.block)), + interpolation: $ => seq("$", choice($.interpolation_identifier, $.block)), interpolated_string: $ => choice( diff --git a/queries/scala/highlights.scm b/queries/scala/highlights.scm index 6ff8b00..ad0d862 100644 --- a/queries/scala/highlights.scm +++ b/queries/scala/highlights.scm @@ -25,7 +25,7 @@ (self_type (identifier) @parameter) -(interpolation (dollar_identifier) @none) +(interpolation (interpolation_identifier) @none) (interpolation (block) @none) ;; types diff --git a/queries/scala/locals.scm b/queries/scala/locals.scm index b8b3c33..51927d4 100644 --- a/queries/scala/locals.scm +++ b/queries/scala/locals.scm @@ -28,4 +28,4 @@ (identifier) @local.reference -(dollar_identifier) @local.reference +(interpolation_identifier) @local.reference From f894d1d0cdc87e14a318e3032310dafb06a11fe4 Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Thu, 20 Jul 2023 18:47:29 +0200 Subject: [PATCH 5/7] Add highlighting test --- test/highlight/basics.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/highlight/basics.scala b/test/highlight/basics.scala index c879c01..a6b4d5f 100644 --- a/test/highlight/basics.scala +++ b/test/highlight/basics.scala @@ -79,5 +79,12 @@ object Hello { // ^method val hello2 = c"some $meth" // ^method + val hello3 = s"$$$meth$hello2%" +// ^string +// ^punctuation.special +// ^method +// ^punctuation.special +// ^variable +// ^string } From 9e30051ef712ce8b51ed7e8d07b816c60d24757e Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Thu, 20 Jul 2023 23:22:12 +0200 Subject: [PATCH 6/7] Alias interpolation_identifier to identifier to avoid query badness --- corpus/expressions.txt | 4 ++-- corpus/literals.txt | 14 +++++++------- corpus/patterns.txt | 6 +++--- grammar.js | 6 ++++-- queries/scala/highlights.scm | 2 +- queries/scala/locals.scm | 1 - 6 files changed, 17 insertions(+), 16 deletions(-) diff --git a/corpus/expressions.txt b/corpus/expressions.txt index 5f76897..b98c8e9 100644 --- a/corpus/expressions.txt +++ b/corpus/expressions.txt @@ -706,9 +706,9 @@ def matchTest(x: Int): String = x match { (identifier) (interpolated_string (interpolation - (interpolation_identifier)) + (identifier)) (interpolation - (interpolation_identifier)))) + (identifier)))) (infix_expression (identifier) (operator_identifier) diff --git a/corpus/literals.txt b/corpus/literals.txt index 5a99a20..e2bc758 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -53,7 +53,7 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (interpolation_identifier)) + (identifier)) (interpolation (block (identifier)))))) @@ -63,7 +63,7 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (interpolation_identifier))))) + (identifier))))) (val_definition (identifier) (interpolated_string_expression @@ -86,28 +86,28 @@ val string7 = s"$$ $a" (identifier) (interpolated_string (interpolation - (interpolation_identifier)) + (identifier)) (interpolation (block (identifier))) (interpolation - (interpolation_identifier))))) + (identifier))))) (val_definition (identifier) (interpolated_string_expression (identifier) (interpolated_string (interpolation - (interpolation_identifier)) + (identifier)) (interpolation - (interpolation_identifier))))) + (identifier))))) (val_definition (identifier) (interpolated_string_expression (identifier) (interpolated_string (interpolation - (interpolation_identifier)))))) + (identifier)))))) ================================================================================ diff --git a/corpus/patterns.txt b/corpus/patterns.txt index eb42ab1..a175314 100644 --- a/corpus/patterns.txt +++ b/corpus/patterns.txt @@ -104,13 +104,13 @@ def showNotification(notification: Notification): String = { (match_expression (identifier) (case_block (case_clause (case_class_pattern (type_identifier) (identifier) (identifier) (wildcard)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier))))) (case_clause (case_class_pattern (type_identifier) (identifier) (identifier)) - (interpolated_string_expression (identifier) (interpolated_string (interpolation (interpolation_identifier)) (interpolation (interpolation_identifier)))))))))) + (interpolated_string_expression (identifier) (interpolated_string (interpolation (identifier)) (interpolation (identifier)))))))))) ============================ Infix patterns diff --git a/grammar.js b/grammar.js index dfb8f04..e7b61fd 100644 --- a/grammar.js +++ b/grammar.js @@ -1405,7 +1405,7 @@ module.exports = grammar({ * suffix and can be approximated as * /[A-Za-z_][A-Z_a-z0-9]/; */ - interpolation_identifier: $ => + _interpolation_identifier: $ => /[\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F][\p{Lu}\p{Lt}\p{Nl}\p{Lo}\p{Lm}\p{Ll}_\u00AA\u00BB\u02B0-\u02B8\u02C0-\u02C1\u02E0-\u02E4\u037A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\uA69C-\uA69D\uA770\uA7F8-\uA7F9\uAB5C-\uAB5F0-9_\p{Ll}]*/, _backquoted_id: $ => /`[^\n`]+`/, @@ -1514,7 +1514,9 @@ module.exports = grammar({ _dollar_escape: $ => seq('$', '$'), - interpolation: $ => seq("$", choice($.interpolation_identifier, $.block)), + _aliased_interpolation_identifier: $ => alias($._interpolation_identifier, $.identifier), + + interpolation: $ => seq("$", choice($._aliased_interpolation_identifier, $.block)), interpolated_string: $ => choice( diff --git a/queries/scala/highlights.scm b/queries/scala/highlights.scm index ad0d862..ed20b27 100644 --- a/queries/scala/highlights.scm +++ b/queries/scala/highlights.scm @@ -25,7 +25,7 @@ (self_type (identifier) @parameter) -(interpolation (interpolation_identifier) @none) +(interpolation (identifier) @none) (interpolation (block) @none) ;; types diff --git a/queries/scala/locals.scm b/queries/scala/locals.scm index 51927d4..c5027b5 100644 --- a/queries/scala/locals.scm +++ b/queries/scala/locals.scm @@ -28,4 +28,3 @@ (identifier) @local.reference -(interpolation_identifier) @local.reference From 6f9683bbfba2b35fe5980a1bb3627952459b748e Mon Sep 17 00:00:00 2001 From: Johannes Coetzee Date: Fri, 21 Jul 2023 10:01:38 +0200 Subject: [PATCH 7/7] Handle quote dollar escape case as well --- corpus/literals.txt | 10 ++++++++++ grammar.js | 2 +- test/highlight/basics.scala | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/corpus/literals.txt b/corpus/literals.txt index e2bc758..6f28f07 100644 --- a/corpus/literals.txt +++ b/corpus/literals.txt @@ -44,6 +44,9 @@ val string5 = s"$works${without}$spaces" val string6 = s"$a$b" val string7 = s"$$ $a" + +val string8 = s"$"$a" + -------------------------------------------------------------------------------- (compilation_unit @@ -101,6 +104,13 @@ val string7 = s"$$ $a" (identifier)) (interpolation (identifier))))) + (val_definition + (identifier) + (interpolated_string_expression + (identifier) + (interpolated_string + (interpolation + (identifier))))) (val_definition (identifier) (interpolated_string_expression diff --git a/grammar.js b/grammar.js index e7b61fd..f55bff3 100644 --- a/grammar.js +++ b/grammar.js @@ -1512,7 +1512,7 @@ module.exports = grammar({ _interpolated_multiline_string_start: $ => '"""', - _dollar_escape: $ => seq('$', '$'), + _dollar_escape: $ => seq('$', choice('$', '"')), _aliased_interpolation_identifier: $ => alias($._interpolation_identifier, $.identifier), diff --git a/test/highlight/basics.scala b/test/highlight/basics.scala index a6b4d5f..9c9f988 100644 --- a/test/highlight/basics.scala +++ b/test/highlight/basics.scala @@ -86,5 +86,9 @@ object Hello { // ^punctuation.special // ^variable // ^string + val hello4 = s"$"$hello3" +// ^string +// ^punctuation.special +// ^variable }