diff --git a/src/razor/syntaxes/aspnetcorerazor.tmLanguage.json b/src/razor/syntaxes/aspnetcorerazor.tmLanguage.json index 8f6454c36..b82283682 100644 --- a/src/razor/syntaxes/aspnetcorerazor.tmLanguage.json +++ b/src/razor/syntaxes/aspnetcorerazor.tmLanguage.json @@ -525,6 +525,15 @@ }, { "include": "#using-directive" + }, + { + "include": "#rendermode-directive" + }, + { + "include": "#preservewhitespace-directive" + }, + { + "include": "#typeparam-directive" } ] }, @@ -849,6 +858,75 @@ } } }, + "rendermode-directive": { + "name": "meta.directive", + "match": "(@)(rendermode)\\s+([^$]+)?", + "captures": { + "1": { + "patterns": [ + { + "include": "#transition" + } + ] + }, + "2": { + "name": "keyword.control.razor.directive.rendermode" + }, + "3": { + "patterns": [ + { + "include": "source.cs#type" + } + ] + } + } + }, + "preservewhitespace-directive": { + "name": "meta.directive", + "match": "(@)(preservewhitespace)\\s+([^$]+)?", + "captures": { + "1": { + "patterns": [ + { + "include": "#transition" + } + ] + }, + "2": { + "name": "keyword.control.razor.directive.preservewhitespace" + }, + "3": { + "patterns": [ + { + "include": "source.cs#boolean-literal" + } + ] + } + } + }, + "typeparam-directive": { + "name": "meta.directive", + "match": "(@)(typeparam)\\s+([^$]+)?", + "captures": { + "1": { + "patterns": [ + { + "include": "#transition" + } + ] + }, + "2": { + "name": "keyword.control.razor.directive.typeparam" + }, + "3": { + "patterns": [ + { + "include": "source.cs#type" + } + ] + } + } + }, "attribute-directive": { "name": "meta.directive", "begin": "(@)(attribute)\\b\\s+", diff --git a/src/razor/syntaxes/aspnetcorerazor.tmLanguage.yml b/src/razor/syntaxes/aspnetcorerazor.tmLanguage.yml index 46b2accdb..66867921f 100644 --- a/src/razor/syntaxes/aspnetcorerazor.tmLanguage.yml +++ b/src/razor/syntaxes/aspnetcorerazor.tmLanguage.yml @@ -281,6 +281,9 @@ repository: - include: '#section-directive' - include: '#layout-directive' - include: '#using-directive' + - include: '#rendermode-directive' + - include: '#preservewhitespace-directive' + - include: '#typeparam-directive' #>>>>> @code and @functions <<<<< @@ -420,6 +423,36 @@ repository: 3: { patterns: [ include: 'source.cs#type' ] } 4: { name: 'entity.name.variable.property.cs' } + #>>>>> @rendermode <<<<< + + rendermode-directive: + name: 'meta.directive' + match: '(@)(rendermode)\s+([^$]+)?' + captures: + 1: { patterns: [ include: '#transition' ] } + 2: { name: 'keyword.control.razor.directive.rendermode'} + 3: { patterns: [ include: 'source.cs#type' ] } + + #>>>>> @preservewhitespace <<<<< + + preservewhitespace-directive: + name: 'meta.directive' + match: '(@)(preservewhitespace)\s+([^$]+)?' + captures: + 1: { patterns: [ include: '#transition' ] } + 2: { name: 'keyword.control.razor.directive.preservewhitespace'} + 3: { patterns: [ include: 'source.cs#boolean-literal' ] } + + #>>>>> @typeparam <<<<< + + typeparam-directive: + name: 'meta.directive' + match: '(@)(typeparam)\s+([^$]+)?' + captures: + 1: { patterns: [ include: '#transition' ] } + 2: { name: 'keyword.control.razor.directive.typeparam'} + 3: { patterns: [ include: 'source.cs#type' ] } + #>>>>> @attribute <<<<< attribute-directive: @@ -925,4 +958,4 @@ repository: - include: 'source.cs#punctuation-semicolon' end: '(\))' endCaptures: - 1: { name: 'punctuation.parenthesis.close.cs' } \ No newline at end of file + 1: { name: 'punctuation.parenthesis.close.cs' } diff --git a/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/__snapshots__/grammarTests.test.ts.snap b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/__snapshots__/grammarTests.test.ts.snap index 88b77e4ce..901635556 100644 --- a/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/__snapshots__/grammarTests.test.ts.snap +++ b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/__snapshots__/grammarTests.test.ts.snap @@ -2820,6 +2820,58 @@ exports[`Grammar tests @page directive Routed spaced 1`] = ` " `; +exports[`Grammar tests @preservewhitespace directive Bool provided (false) 1`] = ` +"Line: @preservewhitespace false + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace + - token from 19 to 20 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 20 to 25 (false) with scopes text.aspnetcorerazor, meta.directive, constant.language.boolean.false.cs +" +`; + +exports[`Grammar tests @preservewhitespace directive Bool provided (true) 1`] = ` +"Line: @preservewhitespace true + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace + - token from 19 to 20 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 20 to 24 (true) with scopes text.aspnetcorerazor, meta.directive, constant.language.boolean.true.cs +" +`; + +exports[`Grammar tests @preservewhitespace directive Bool provided spaced 1`] = ` +"Line: @preservewhitespace false + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace + - token from 19 to 33 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 33 to 38 (false) with scopes text.aspnetcorerazor, meta.directive, constant.language.boolean.false.cs + - token from 38 to 48 ( ) with scopes text.aspnetcorerazor, meta.directive +" +`; + +exports[`Grammar tests @preservewhitespace directive Incomplete bool 1`] = ` +"Line: @preservewhitespace fal + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace + - token from 19 to 20 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 20 to 24 (fal) with scopes text.aspnetcorerazor, meta.directive +" +`; + +exports[`Grammar tests @preservewhitespace directive No bool 1`] = ` +"Line: @preservewhitespace + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace +" +`; + +exports[`Grammar tests @preservewhitespace directive No bool spaced 1`] = ` +"Line: @preservewhitespace + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 19 (preservewhitespace) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.preservewhitespace + - token from 19 to 34 ( ) with scopes text.aspnetcorerazor, meta.directive +" +`; + exports[`Grammar tests @removeTagHelper directive Incomplete parameter 1`] = ` "Line: @removeTagHelper " - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition @@ -2876,6 +2928,49 @@ exports[`Grammar tests @removeTagHelper directive Unquoted parameter 1`] = ` " `; +exports[`Grammar tests @rendermode directive Incomplete mode 1`] = ` +"Line: @rendermode InteractiveWebAssemb + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 11 (rendermode) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.rendermode + - token from 11 to 12 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 12 to 32 (InteractiveWebAssemb) with scopes text.aspnetcorerazor, meta.directive, entity.name.type.cs +" +`; + +exports[`Grammar tests @rendermode directive Mode provided 1`] = ` +"Line: @rendermode InteractiveServer + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 11 (rendermode) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.rendermode + - token from 11 to 12 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 12 to 29 (InteractiveServer) with scopes text.aspnetcorerazor, meta.directive, entity.name.type.cs +" +`; + +exports[`Grammar tests @rendermode directive Mode provided spaced 1`] = ` +"Line: @rendermode InteractiveAuto + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 11 (rendermode) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.rendermode + - token from 11 to 25 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 25 to 40 (InteractiveAuto) with scopes text.aspnetcorerazor, meta.directive, entity.name.type.cs + - token from 40 to 50 ( ) with scopes text.aspnetcorerazor, meta.directive +" +`; + +exports[`Grammar tests @rendermode directive No mode 1`] = ` +"Line: @rendermode + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 11 (rendermode) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.rendermode +" +`; + +exports[`Grammar tests @rendermode directive No mode spaced 1`] = ` +"Line: @rendermode + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 11 (rendermode) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.rendermode + - token from 11 to 26 ( ) with scopes text.aspnetcorerazor, meta.directive +" +`; + exports[`Grammar tests @section directive As C# local 1`] = ` "Line: @section.method() - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.expression.implicit.cshtml, keyword.control.cshtml.transition @@ -3661,6 +3756,63 @@ exports[`Grammar tests @try { ... } catch/finally { ... } Single line 1`] = ` " `; +exports[`Grammar tests @typeparam directive Complete type, generic 1`] = ` +"Line: @typeparam SomeViewBase + - token from 0 to 1 (@) with scopes text.aspnetcorerazor, meta.directive, keyword.control.cshtml.transition + - token from 1 to 10 (typeparam) with scopes text.aspnetcorerazor, meta.directive, keyword.control.razor.directive.typeparam + - token from 10 to 11 ( ) with scopes text.aspnetcorerazor, meta.directive + - token from 11 to 23 (SomeViewBase) with scopes text.aspnetcorerazor, meta.directive, entity.name.type.cs + - token from 23 to 24 (<) with scopes text.aspnetcorerazor, meta.directive, punctuation.definition.typeparameters.begin.cs + - token from 24 to 30 (string) with scopes text.aspnetcorerazor, meta.directive, keyword.type.cs + - token from 30 to 31 (>) with scopes text.aspnetcorerazor, meta.directive, punctuation.definition.typeparameters.end.cs +" +`; + +exports[`Grammar tests @typeparam directive Incomplete type, generic 1`] = ` +"Line: @typeparam SomeViewBase { RunSectionDirectiveSuite(); RunLayoutDirectiveSuite(); RunUsingDirectiveSuite(); + RunRendermodeDirectiveSuite(); + RunPreservewhitespaceDirectiveSuite(); + RunTypeparamDirectiveSuite(); // Razor C# Control Structures RunUsingStatementSuite(); diff --git a/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/preservewhitespaceDirective.ts b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/preservewhitespaceDirective.ts new file mode 100644 index 000000000..c81b59d01 --- /dev/null +++ b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/preservewhitespaceDirective.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { describe, it } from '@jest/globals'; +import { assertMatchesSnapshot } from './infrastructure/testUtilities'; + +// See GrammarTests.test.ts for details on exporting this test suite instead of running in place. + +export function RunPreservewhitespaceDirectiveSuite() { + describe('@preservewhitespace directive', () => { + it('No bool', async () => { + await assertMatchesSnapshot('@preservewhitespace'); + }); + + it('No bool spaced', async () => { + await assertMatchesSnapshot('@preservewhitespace '); + }); + + it('Incomplete bool', async () => { + await assertMatchesSnapshot('@preservewhitespace fal'); + }); + + it('Bool provided (true)', async () => { + await assertMatchesSnapshot('@preservewhitespace true'); + }); + + it('Bool provided (false)', async () => { + await assertMatchesSnapshot('@preservewhitespace false'); + }); + + it('Bool provided spaced', async () => { + await assertMatchesSnapshot('@preservewhitespace false '); + }); + }); +} diff --git a/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/rendermodeDirective.ts b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/rendermodeDirective.ts new file mode 100644 index 000000000..9da60b4e5 --- /dev/null +++ b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/rendermodeDirective.ts @@ -0,0 +1,33 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { describe, it } from '@jest/globals'; +import { assertMatchesSnapshot } from './infrastructure/testUtilities'; + +// See GrammarTests.test.ts for details on exporting this test suite instead of running in place. + +export function RunRendermodeDirectiveSuite() { + describe('@rendermode directive', () => { + it('No mode', async () => { + await assertMatchesSnapshot('@rendermode'); + }); + + it('No mode spaced', async () => { + await assertMatchesSnapshot('@rendermode '); + }); + + it('Incomplete mode', async () => { + await assertMatchesSnapshot('@rendermode InteractiveWebAssemb'); + }); + + it('Mode provided', async () => { + await assertMatchesSnapshot('@rendermode InteractiveServer'); + }); + + it('Mode provided spaced', async () => { + await assertMatchesSnapshot('@rendermode InteractiveAuto '); + }); + }); +} diff --git a/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/typeparamDirective.ts b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/typeparamDirective.ts new file mode 100644 index 000000000..893020549 --- /dev/null +++ b/test/razorTests/Microsoft.AspNetCore.Razor.VSCode.Grammar.Test/tests/typeparamDirective.ts @@ -0,0 +1,37 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import { describe, it } from '@jest/globals'; +import { assertMatchesSnapshot } from './infrastructure/testUtilities'; + +// See GrammarTests.test.ts for details on exporting this test suite instead of running in place. + +export function RunTypeparamDirectiveSuite() { + describe('@typeparam directive', () => { + it('No type', async () => { + await assertMatchesSnapshot('@typeparam'); + }); + + it('No type spaced', async () => { + await assertMatchesSnapshot('@typeparam '); + }); + + it('Incomplete type, generic', async () => { + await assertMatchesSnapshot('@typeparam SomeViewBase { + await assertMatchesSnapshot('@typeparam SomeViewBase'); + }); + + it('Type provided', async () => { + await assertMatchesSnapshot('@typeparam Person'); + }); + + it('Type provided spaced', async () => { + await assertMatchesSnapshot('@typeparam Person '); + }); + }); +}