From 265d83f0412a8232c3309170bf102c5e645ec1cd Mon Sep 17 00:00:00 2001 From: Matt Godbolt Date: Mon, 15 Feb 2021 17:15:34 -0600 Subject: [PATCH 1/2] Support better C++ annotation highlighting * Uses some simple highlighting within annotations * Supports multi-line annotations (see compiler-explorer/compiler-explorer#878) --- src/cpp/cpp.test.ts | 50 +++++++++++++++++++++++++++++++++++++++++++++ src/cpp/cpp.ts | 11 +++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/src/cpp/cpp.test.ts b/src/cpp/cpp.test.ts index 580b8411..b31a89ec 100644 --- a/src/cpp/cpp.test.ts +++ b/src/cpp/cpp.test.ts @@ -856,5 +856,55 @@ testTokenization('cpp', [ { startIndex: 4, type: 'comment.cpp' } ] } + ], + + [ + { + line: '[[nodiscard]]', + tokens: [{ startIndex: 0, type: 'annotation.cpp' }] + } + ], + [ + { + // Example from http://eel.is/c++draft/dcl.attr + line: '[[using CC: opt(1), debug]]', + tokens: [ + { startIndex: 0, type: 'annotation.cpp' }, // [[ + { startIndex: 2, type: 'keyword.cpp' }, // using + { startIndex: 7, type: '' }, + { startIndex: 8, type: 'annotation.cpp' }, // CC + { startIndex: 10, type: 'delimiter.cpp' }, // colon + { startIndex: 11, type: '' }, + { startIndex: 12, type: 'annotation.cpp' }, // opt + { startIndex: 15, type: 'delimiter.parenthesis.cpp' }, // ( + { startIndex: 16, type: 'annotation.cpp' }, // 1 + { startIndex: 17, type: 'delimiter.parenthesis.cpp' }, // ) + { startIndex: 18, type: 'delimiter.cpp' }, // , + { startIndex: 19, type: '' }, + { startIndex: 20, type: 'annotation.cpp' } // debug]] + ] + } + ], + [ + // Multiline and comments. + { + line: '[[nodiscard /*commented*/', + tokens: [ + { startIndex: 0, type: 'annotation.cpp' }, + { startIndex: 11, type: '' }, + { startIndex: 12, type: 'comment.cpp' } + ] + }, + { + line: ']] int i;', + tokens: [ + { startIndex: 0, type: 'annotation.cpp' }, + { startIndex: 2, type: '' }, + { startIndex: 3, type: 'keyword.int.cpp' }, + { startIndex: 6, type: '' }, + { startIndex: 7, type: 'identifier.cpp' }, + { startIndex: 8, type: 'delimiter.cpp' } + ] + } ] ]); diff --git a/src/cpp/cpp.ts b/src/cpp/cpp.ts index 0e0bc737..d0c29f90 100644 --- a/src/cpp/cpp.ts +++ b/src/cpp/cpp.ts @@ -298,7 +298,7 @@ export const language = { { include: '@whitespace' }, // [[ attributes ]]. - [/\[\[.*\]\]/, 'annotation'], + [/\[\[/, { token: 'annotation', next: '@annotation' }], [/^\s*#include/, { token: 'keyword.directive.include', next: '@include' }], @@ -384,6 +384,15 @@ export const language = { [/.*/, 'string.raw'] ], + annotation: [ + { include: '@whitespace' }, + [/using|alignas/, 'keyword'], + [/[a-zA-Z0-9_]+/, 'annotation'], + [/[,:]/, 'delimiter'], + [/[()]/, '@brackets'], + [/\]\]/, { token: 'annotation', next: '@pop' }] + ], + include: [ [ /(\s*)(<)([^<>]*)(>)/, From c8c2ebc2778263e4fc07b074f7a97671e85bcad7 Mon Sep 17 00:00:00 2001 From: Matt Godbolt Date: Mon, 15 Feb 2021 17:39:19 -0600 Subject: [PATCH 2/2] Support whitespace between annotation brackets See compiler-explorer/compiler-explorer#880 --- src/cpp/cpp.test.ts | 8 ++++++++ src/cpp/cpp.ts | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/cpp/cpp.test.ts b/src/cpp/cpp.test.ts index b31a89ec..e1aa2d99 100644 --- a/src/cpp/cpp.test.ts +++ b/src/cpp/cpp.test.ts @@ -858,6 +858,7 @@ testTokenization('cpp', [ } ], + // Annotations [ { line: '[[nodiscard]]', @@ -906,5 +907,12 @@ testTokenization('cpp', [ { startIndex: 8, type: 'delimiter.cpp' } ] } + ], + [ + // We don't support newlines between annotation square brackets, but we do support other whitespace. + { + line: '[ [nodiscard] ]', + tokens: [{ startIndex: 0, type: 'annotation.cpp' }] + } ] ]); diff --git a/src/cpp/cpp.ts b/src/cpp/cpp.ts index d0c29f90..ac2ff50c 100644 --- a/src/cpp/cpp.ts +++ b/src/cpp/cpp.ts @@ -298,7 +298,7 @@ export const language = { { include: '@whitespace' }, // [[ attributes ]]. - [/\[\[/, { token: 'annotation', next: '@annotation' }], + [/\[\s*\[/, { token: 'annotation', next: '@annotation' }], [/^\s*#include/, { token: 'keyword.directive.include', next: '@include' }], @@ -390,7 +390,7 @@ export const language = { [/[a-zA-Z0-9_]+/, 'annotation'], [/[,:]/, 'delimiter'], [/[()]/, '@brackets'], - [/\]\]/, { token: 'annotation', next: '@pop' }] + [/\]\s*\]/, { token: 'annotation', next: '@pop' }] ], include: [