From e9cd6e6fe2d3a69fbaa46dd2d9e3813aded89c8f Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Mon, 24 Feb 2025 14:49:12 -0800 Subject: [PATCH] Fix syntax highlighting when using decorator before escaped identifier (#6125) fix [#4720](https://github.com/microsoft/typespec/issues/4720) --- ...-decorator-escaped-id-2025-1-24-9-30-58.md | 7 +++++++ grammars/typespec.json | 6 +++--- packages/compiler/src/server/tmlanguage.ts | 2 +- .../compiler/test/server/colorization.test.ts | 20 +++++++++++++++++++ 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 .chronus/changes/fix-tmlanguage-decorator-escaped-id-2025-1-24-9-30-58.md diff --git a/.chronus/changes/fix-tmlanguage-decorator-escaped-id-2025-1-24-9-30-58.md b/.chronus/changes/fix-tmlanguage-decorator-escaped-id-2025-1-24-9-30-58.md new file mode 100644 index 00000000000..4f03cf1a0e5 --- /dev/null +++ b/.chronus/changes/fix-tmlanguage-decorator-escaped-id-2025-1-24-9-30-58.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/compiler" +--- + +Fix tmlanguage syntax highlighting when using decorator before escaped identifier \ No newline at end of file diff --git a/grammars/typespec.json b/grammars/typespec.json index 5855819f5ae..e7836b1182a 100644 --- a/grammars/typespec.json +++ b/grammars/typespec.json @@ -58,7 +58,7 @@ "name": "entity.name.tag.tsp" } }, - "end": "(?=[_$[:alpha:]])|(?=,|;|@|\\)|\\}|\\b(?:extern)\\b|\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b)", + "end": "(?=([_$[:alpha:]]|`))|(?=,|;|@|\\)|\\}|\\b(?:extern)\\b|\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b)", "patterns": [ { "include": "#token" @@ -141,7 +141,7 @@ "name": "entity.name.tag.tsp" } }, - "end": "(?=[_$[:alpha:]])|(?=,|;|@|\\)|\\}|\\b(?:extern)\\b|\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b)", + "end": "(?=([_$[:alpha:]]|`))|(?=,|;|@|\\)|\\}|\\b(?:extern)\\b|\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b)", "patterns": [ { "include": "#token" @@ -737,7 +737,7 @@ }, "namespace-name": { "name": "meta.namespace-name.typespec", - "begin": "(?=[_$[:alpha:]])", + "begin": "(?=([_$[:alpha:]]|`))", "end": "((?=\\{)|(?=,|;|@|\\)|\\}|\\b(?:extern)\\b|\\b(?:namespace|model|op|using|import|enum|alias|union|interface|dec|fn)\\b))", "patterns": [ { diff --git a/packages/compiler/src/server/tmlanguage.ts b/packages/compiler/src/server/tmlanguage.ts index 4e25826ea5c..344a5658d40 100644 --- a/packages/compiler/src/server/tmlanguage.ts +++ b/packages/compiler/src/server/tmlanguage.ts @@ -59,7 +59,7 @@ const meta: typeof tm.meta = tm.meta; const identifierStart = "[_$[:alpha:]]"; // cspell:disable-next-line const identifierContinue = "[_$[:alnum:]]"; -const beforeIdentifier = `(?=${identifierStart})`; +const beforeIdentifier = `(?=(${identifierStart}|\`))`; const escapedIdentifier = "`(?:[^`\\\\]|\\\\.)*`"; const simpleIdentifier = `\\b${identifierStart}${identifierContinue}*\\b`; const identifier = `${simpleIdentifier}|${escapedIdentifier}`; diff --git a/packages/compiler/test/server/colorization.test.ts b/packages/compiler/test/server/colorization.test.ts index 853a3fa1f30..0eabca1a643 100644 --- a/packages/compiler/test/server/colorization.test.ts +++ b/packages/compiler/test/server/colorization.test.ts @@ -918,6 +918,26 @@ function testColorization(description: string, tokenize: Tokenize) { ]); }); + it("decorators on escaped members", async () => { + const tokens = await tokenize("enum Direction { @foo `Val 123`, @foo(123) `456 after`}"); + deepStrictEqual(tokens, [ + Token.keywords.enum, + Token.identifiers.type("Direction"), + Token.punctuation.openBrace, + Token.identifiers.tag("@"), + Token.identifiers.tag("foo"), + Token.identifiers.variable("`Val 123`"), + Token.punctuation.comma, + Token.identifiers.tag("@"), + Token.identifiers.tag("foo"), + Token.punctuation.openParen, + Token.literals.numeric("123"), + Token.punctuation.closeParen, + Token.identifiers.variable("`456 after`"), + Token.punctuation.closeBrace, + ]); + }); + it("enum with string values", async () => { const tokens = await tokenize(`enum Direction { up: "Up", down: "Down"}`); deepStrictEqual(tokens, [