From b85f5eb20cdb8aefa8c58956bccbe27aa85dbc27 Mon Sep 17 00:00:00 2001 From: ecmel Date: Mon, 16 Dec 2024 17:34:42 +0300 Subject: [PATCH] implemented semantic highlighting for lambda definitions --- server/src/parser/parser.ts | 8 +++----- server/src/parser/utils.ts | 4 ++++ server/src/qLangServer.ts | 31 ++++++++++++++++++------------- test/suite/qLangServer.test.ts | 6 +++--- 4 files changed, 28 insertions(+), 21 deletions(-) diff --git a/server/src/parser/parser.ts b/server/src/parser/parser.ts index 566ba6e1..3211b9cc 100644 --- a/server/src/parser/parser.ts +++ b/server/src/parser/parser.ts @@ -86,11 +86,9 @@ function assignment(state: State, token: Token) { } else { let top = peek(stack); if (top?.tokenType === Colon || top?.tokenType === DoubleColon) { - token.assignment = [top]; - stack.pop(); - if (stack.length > 0) { - token.assignment.push(...stack); - clear(stack); + token.assignment = []; + while ((top = stack.pop())) { + token.assignment.push(top); } } stack.push(token); diff --git a/server/src/parser/utils.ts b/server/src/parser/utils.ts index fb2569e1..30617308 100644 --- a/server/src/parser/utils.ts +++ b/server/src/parser/utils.ts @@ -166,6 +166,10 @@ export function tokenId(token: Token) { return (token.tokenType.tokenTypeIdx?.toString(16) || "").padStart(2, "0"); } +export function lamdaDefinition(token: Token) { + return token.assignment?.find((value) => value.tokenType === LCurly); +} + export const enum FindKind { Reference, Definition, diff --git a/server/src/qLangServer.ts b/server/src/qLangServer.ts index 016e316e..e393d5f6 100644 --- a/server/src/qLangServer.ts +++ b/server/src/qLangServer.ts @@ -74,6 +74,8 @@ import { WhiteSpace, RCurly, local, + LCurly, + lamdaDefinition, } from "./parser"; import { lint } from "./linter"; import { readFileSync } from "node:fs"; @@ -158,7 +160,7 @@ export default class QLangServer { semanticTokensProvider: { full: true, legend: { - tokenTypes: ["variable"], + tokenTypes: ["variable", "function"], tokenModifiers: ["declaration", "readonly"], }, }, @@ -468,18 +470,21 @@ export default class QLangServer { let character = 0; let delta = 0; for (const token of tokens) { - if (assignable(token) && local(token, tokens)) { - line = range.start.line; - character = range.start.character; - range = rangeFromToken(token); - delta = range.start.line - line; - result.data.push( - delta, - delta ? range.start.character : range.start.character - character, - token.image.length, - 0, - 3, - ); + if (assignable(token)) { + let kind = lamdaDefinition(token) ? 1 : local(token, tokens) ? 0 : -1; + if (kind >= 0) { + line = range.start.line; + character = range.start.character; + range = rangeFromToken(token); + delta = range.start.line - line; + result.data.push( + delta, + delta ? range.start.character : range.start.character - character, + token.image.length, + kind, + 3, + ); + } } } return result; diff --git a/test/suite/qLangServer.test.ts b/test/suite/qLangServer.test.ts index 98bd75d6..185509a8 100644 --- a/test/suite/qLangServer.test.ts +++ b/test/suite/qLangServer.test.ts @@ -384,19 +384,19 @@ describe("qLangServer", () => { it("should tokenize local variables", () => { const params = createDocument("a:{[b;c]d:1;b*c*d}"); const result = server.onSemanticTokens(params); - assert.strictEqual(result.data.length, 30); + assert.strictEqual(result.data.length, 35); }); it("should ignore qualified variables", () => { const params = createDocument("a:{.ns.b:1;.ns.b}"); const result = server.onSemanticTokens(params); - assert.strictEqual(result.data.length, 0); + assert.strictEqual(result.data.length, 5); }); it("should detect empty lists", () => { const params = createDocument("a:{b:();b}"); const result = server.onSemanticTokens(params); - assert.strictEqual(result.data.length, 10); + assert.strictEqual(result.data.length, 15); }); });