From 83364d3d7a026ee46a1220023c1b583ae7a50c9a Mon Sep 17 00:00:00 2001 From: Lars Reimann Date: Tue, 24 Oct 2023 22:47:02 +0200 Subject: [PATCH] feat: syntax highlighting in documentation comments (#690) Closes partially #669 ### Summary of Changes Highlight tags in documentation comments: ![image](https://github.com/Safe-DS/DSL/assets/2501322/940096a3-a248-4856-bd47-b1ecd7aa8fa5) --- .../lsp/safe-ds-semantic-token-provider.ts | 7 + syntaxes/safe-ds.tmLanguage.json | 196 ++++++++++-------- .../safe-ds-semantic-token-provider.test.ts | 5 + 3 files changed, 119 insertions(+), 89 deletions(-) diff --git a/src/language/lsp/safe-ds-semantic-token-provider.ts b/src/language/lsp/safe-ds-semantic-token-provider.ts index 794e2281f..52590d398 100644 --- a/src/language/lsp/safe-ds-semantic-token-provider.ts +++ b/src/language/lsp/safe-ds-semantic-token-provider.ts @@ -24,6 +24,7 @@ import { isSdsPipeline, isSdsPlaceholder, isSdsReference, + isSdsResult, isSdsSchema, isSdsSegment, isSdsTypeArgument, @@ -207,6 +208,12 @@ export class SafeDsSemanticTokenProvider extends AbstractSemanticTokenProvider { type: SemanticTokenTypes.variable, modifier: [SemanticTokenModifiers.readonly, ...additionalModifiers], }; + } else if (isSdsResult(node)) { + return { + // For lack of a better option, we use the token type for parameters here + type: SemanticTokenTypes.parameter, + modifier: additionalModifiers, + }; } else if (isSdsSchema(node)) { return { type: SemanticTokenTypes.type, diff --git a/syntaxes/safe-ds.tmLanguage.json b/syntaxes/safe-ds.tmLanguage.json index d6cfc2e6c..a7b20b7e0 100644 --- a/syntaxes/safe-ds.tmLanguage.json +++ b/syntaxes/safe-ds.tmLanguage.json @@ -1,98 +1,116 @@ { - "name": "safe-ds", - "scopeName": "source.safe-ds", - "fileTypes": [ - ".sdspipe", - ".sdsstub", - ".sdstest" - ], - "patterns": [ - { - "include": "#comments" - }, - { - "name": "constant.numeric.safe-ds", - "match": "\\b([0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?)\\b" - }, - { - "name": "constant.language.safe-ds", - "match": "\\b(false|null|true)\\b" - }, - { - "name": "storage.type.safe-ds", - "match": "\\b(annotation|attr|class|enum|fun|package|pipeline|schema|segment|val)\\b" - }, - { - "name": "storage.modifier.safe-ds", - "match": "\\b(const|in|internal|out|private|static)\\b" - }, - { - "name": "keyword.operator.safe-ds", - "match": "\\b(and|not|or|sub|super)\\b" - }, - { - "name": "keyword.other.safe-ds", - "match": "\\b(as|from|import|literal|union|where|yield)\\b" - }, - { - "name": "meta.safe-ds", - "begin": "\\`", - "end": "\\`" - }, - { - "name": "string.interpolated.safe-ds", - "begin": "\"|}}", - "end": "{{|\"", - "patterns": [ + "name": "safe-ds", + "scopeName": "source.safe-ds", + "fileTypes": [ + ".sdspipe", + ".sdsstub", + ".sdstest" + ], + "patterns": [ { - "include": "#string-character-escape" - } - ] - }, - { - "name": "string.quoted.double.safe-ds", - "begin": "\"", - "end": "\"", - "patterns": [ + "include": "#comments" + }, { - "include": "#string-character-escape" - } - ] - } - ], - "repository": { - "comments": { - "patterns": [ + "name": "constant.numeric.safe-ds", + "match": "\\b([0-9]+(\\.[0-9]+)?([eE][+-]?[0-9]+)?)\\b" + }, { - "name": "comment.line.double-slash.safe-ds", - "begin": "//", - "beginCaptures": { - "1": { - "name": "punctuation.whitespace.comment.leading.safe-ds" - } - }, - "end": "(?=$)" + "name": "constant.language.safe-ds", + "match": "\\b(false|null|true)\\b" }, { - "name": "comment.block.safe-ds", - "begin": "/\\*", - "beginCaptures": { - "0": { - "name": "punctuation.definition.comment.safe-ds" - } - }, - "end": "\\*/", - "endCaptures": { - "0": { - "name": "punctuation.definition.comment.safe-ds" - } - } + "name": "storage.type.safe-ds", + "match": "\\b(annotation|attr|class|enum|fun|package|pipeline|schema|segment|val)\\b" + }, + { + "name": "storage.modifier.safe-ds", + "match": "\\b(const|in|internal|out|private|static)\\b" + }, + { + "name": "keyword.operator.safe-ds", + "match": "\\b(and|not|or|sub|super)\\b" + }, + { + "name": "keyword.other.safe-ds", + "match": "\\b(as|from|import|literal|union|where|yield)\\b" + }, + { + "name": "meta.safe-ds", + "begin": "\\`", + "end": "\\`" + }, + { + "name": "string.interpolated.safe-ds", + "begin": "\"|}}", + "end": "{{|\"", + "patterns": [ + { + "include": "#string-character-escape" + } + ] + }, + { + "name": "string.quoted.double.safe-ds", + "begin": "\"", + "end": "\"", + "patterns": [ + { + "include": "#string-character-escape" + } + ] + } + ], + "repository": { + "comments": { + "patterns": [ + { + "name": "comment.line.double-slash.safe-ds", + "begin": "//", + "end": "(?=$)" + }, + { + "name": "comment.block.documentation.safe-ds", + "begin": "/\\*\\*", + "end": "\\*/", + "patterns": [ + { + "match": "(@param|@result)\\s+([_a-zA-Z][_a-zA-Z0-9]*)?", + "captures": { + "1": { + "name": "keyword.other.safe-ds" + }, + "2": { + "name": "variable.parameter.safe-ds" + } + } + }, + { + "match": "(@since)\\b", + "name": "keyword.other.safe-ds" + }, + { + "match": "(@typeParam)\\s+([_a-zA-Z][_a-zA-Z0-9]*)?", + "captures": { + "1": { + "name": "keyword.other.safe-ds" + }, + "2": { + "name": "entity.name.type.parameter" + } + } + } + ] + }, + { + "name": "comment.block.safe-ds", + "begin": "/\\*", + "end": "\\*/" + } + ] + }, + "string-character-escape": { + "name": "constant.character.escape.safe-ds", + "match": "\\\\(b|f|n|r|t|v|0|'|\"|{|\\\\|u[0-9a-fA-F]{4})" } - ] - }, - "string-character-escape": { - "name": "constant.character.escape.safe-ds", - "match": "\\\\(b|f|n|r|t|v|0|'|\"|{|\\\\|u[0-9a-fA-F]{4})" } - } } diff --git a/tests/language/lsp/safe-ds-semantic-token-provider.test.ts b/tests/language/lsp/safe-ds-semantic-token-provider.test.ts index 01639db9a..508d65269 100644 --- a/tests/language/lsp/safe-ds-semantic-token-provider.test.ts +++ b/tests/language/lsp/safe-ds-semantic-token-provider.test.ts @@ -100,6 +100,11 @@ describe('SafeDsSemanticTokenProvider', async () => { `, expectedTokenTypes: [SemanticTokenTypes.variable], }, + { + testName: 'result declaration', + code: 'fun f() -> (<|r|>: String)', + expectedTokenTypes: [SemanticTokenTypes.parameter], + }, { testName: 'schema declaration', code: 'schema <|S|>() {}',