diff --git a/.travis.yml b/.travis.yml index c3a4ce12c8..36a2c807a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,6 @@ install: script: - npm test --silent - - npm run test-syntax deploy: provider: releases diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 8474a73013..19e4004654 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,16 +1,27 @@ { "version": "0.1.0", - "command": "gulp", - "isShellCommand": true, "tasks": [ + { + "taskName": "build", + "command": "npm", + "isShellCommand": true, + "args": ["run", "compile"], + "showOutput": "always", + "isBuildCommand": true + }, { "taskName": "test", + "command": "echo", "showOutput": "always", + "isShellCommand": true, + "args": ["Run tests in VS Code by launching the debugg with the 'Launch Tests' configuration."], "isTestCommand": true }, { "taskName": "tslint", - "args": [], + "command": "gulp", + "isShellCommand": true, + "args": ["tslint"], "problemMatcher": { "owner": "tslint", "fileLocation": [ diff --git a/CHANGELOG.md b/CHANGELOG.md index 1381055d35..244d0d713c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,60 @@ +## 1.7.0 _(Not Yet Released)_ + +#### Syntax Hightlighting + +* Introduced a brand new TextMate grammar written from scratch that provides much more robust C# syntax highlighting. ([#101](https://github.com/OmniSharp/omnisharp-vscode/issues/101), [#225](https://github.com/OmniSharp/omnisharp-vscode/issues/225), [#268](https://github.com/OmniSharp/omnisharp-vscode/issues/268), [#316](https://github.com/OmniSharp/omnisharp-vscode/issues/316), [#674](https://github.com/OmniSharp/omnisharp-vscode/issues/674), [#706](https://github.com/OmniSharp/omnisharp-vscode/issues/706), [#731](https://github.com/OmniSharp/omnisharp-vscode/issues/731), [#746](https://github.com/OmniSharp/omnisharp-vscode/issues/746), [#782](https://github.com/OmniSharp/omnisharp-vscode/issues/782), [#802](https://github.com/OmniSharp/omnisharp-vscode/issues/802), [#816](https://github.com/OmniSharp/omnisharp-vscode/issues/816), [#829](https://github.com/OmniSharp/omnisharp-vscode/issues/829), [#830](https://github.com/OmniSharp/omnisharp-vscode/issues/830), [#861](https://github.com/OmniSharp/omnisharp-vscode/issues/861), [#1078](https://github.com/OmniSharp/omnisharp-vscode/issues/1078), [#1084](https://github.com/OmniSharp/omnisharp-vscode/issues/1084), [#1086](https://github.com/OmniSharp/omnisharp-vscode/issues/1086), [#1091](https://github.com/OmniSharp/omnisharp-vscode/issues/1091), [#1096](https://github.com/OmniSharp/omnisharp-vscode/issues/1096), [#1097](https://github.com/OmniSharp/omnisharp-vscode/issues/1097), [#1106](https://github.com/OmniSharp/omnisharp-vscode/issues/1106), [#1115](https://github.com/OmniSharp/omnisharp-vscode/issues/1108)) +* The C# TextMate grammar has a new home! Issues and contributions are welcome at [https://github.com/dotnet/csharp-tmLanguage](https://github.com/dotnet/csharp-tmLanguage). + +### Project Support + +* Updated with the latest changes for .NET Core .csproj projects. ([omnisharp-roslyn#738](https://github.com/OmniSharp/omnisharp-roslyn/pull/738)) +* Automatic package restore and out-of-date notifications implemented for .NET Core .csproj projects. ([#770](https://github.com/OmniSharp/omnisharp-vscode/issues/770)) +* Correctly update project when dotnet restore is performed on a .NET Core .csproj project. ([#1114](https://github.com/OmniSharp/omnisharp-vscode/issues/1114)) +* Properly handle .csproj projects in .sln files that were added via .NET CLI commands. ([omnisharp-roslyn#741](https://github.com/OmniSharp/omnisharp-roslyn/pull/741)) +* Fix `dotnet restore` Visual Studio Code command to execute for .csproj .NET Core projects. ([#1175](https://github.com/OmniSharp/omnisharp-vscode/issues/1175)) +* Respect `nowarn` in project.json projects. ([omnisharp#734](https://github.com/OmniSharp/omnisharp-roslyn/pull/734)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Fix problem with project.json projects that wrap assemblies. ([#424](https://github.com/OmniSharp/omnisharp-vscode/issues/424)) + +### Debugging + +* Enable debugger support for Zorin OS 12. ([#1160](https://github.com/OmniSharp/omnisharp-vscode/issues/1160)) _(Contributed by [@mkaziz](https://github.com/mkaziz))_ +* Added off-road support for [Windows Subsystem for Linux](https://blogs.msdn.microsoft.com/wsl/2016/04/22/windows-subsystem-for-linux-overview/) (NOTE: requires newer version of Windows than have been publicly released yet) +* Fixed issue with debugger pause and multithreaded call stacks ([#1107](https://github.com/OmniSharp/omnisharp-vscode/issues/1107) and [#1105](https://github.com/OmniSharp/omnisharp-vscode/issues/1105)) + +### C# Scripting + +* Support resolving `#r` references from the GAC. ([omnisharp-roslyn#721](https://github.com/OmniSharp/omnisharp-roslyn/pull/721)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Include System.ValueTuple in C# scripts implicitly. ([omnisharp-roslyn#722](https://github.com/OmniSharp/omnisharp-roslyn/pull/722)) _(Contributed by [@filipw](https://github.com/filipw))_ + +### Code Actions + +* Fixed code actions that add files, such as "Move Type to File". ([#975](https://github.com/OmniSharp/omnisharp-vscode/issues/975)) +* Properly surface code actions that have "nested code actions". This allows "generate type" to work properly. ([#302](https://github.com/OmniSharp/omnisharp-vscode/issues/302)) +* Don't display the Remove Unnecessary Usings code action unless it is relevant. ([omnisharp-roslyn#742](https://github.com/OmniSharp/omnisharp-roslyn/issues/742)) +* Don't show the Extract Interface refactoring as it requires a dialog that does not exist in VS Code. ([#925](https://github.com/OmniSharp/omnisharp-vscode/issues/925)) + +### Completion List + +* A namespace icon should be displayed for namespaces in the completion list. ([#1125](https://github.com/OmniSharp/omnisharp-vscode/issues/1124)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Add icons for several symbol kinds in the completion list, fixing many symbols that incorrectly displayed a property "wrench" icon. ([#1145](https://github.com/OmniSharp/omnisharp-vscode/issues/1145)) + +### Other Updates and Fixes + +* Add schema validation for omnisharp.json files. ([#1082](https://github.com/OmniSharp/omnisharp-vscode/pull/1082)) _(Contributed by [@Thaina](https://github.com/Thaina))_ +* Add support for auto-closing and surrounding characters. ([#749](https://github.com/OmniSharp/omnisharp-vscode/issues/749), [#842](https://github.com/OmniSharp/omnisharp-vscode/issues/842)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Fix running and debugging of tests defined in nested classes. ([#743](https://github.com/OmniSharp/omnisharp-vscode/issues/743), [#1151](https://github.com/OmniSharp/omnisharp-vscode/issues/1151)) +* Fix error when 'tasks.json' does not contain a 'tasks' node, or contains os-specific 'tasks' nodes. ([#1140](https://github.com/OmniSharp/omnisharp-vscode/issues/1140)) +* Better detection of Windows architecture (x86 or x64) when determining extension dependencies to download. The detection logic now uses well-known environment variables rather than launching 'wmic'. ([#1110](https://github.com/OmniSharp/omnisharp-vscode/issues/1110), [#1125](https://github.com/OmniSharp/omnisharp-vscode/issues/1125)) +* Improvements to the OmniSharp Log ([#1155](https://github.com/OmniSharp/omnisharp-vscode/pull/1155)) +* Add new values to the `omnisharp.logginglevel` option to allow more granualar control of OmniSharp logging. ([#993](https://github.com/OmniSharp/omnisharp-vscode/issues/993)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Don't display the "some projects have trouble loading" message if projects only contain warnings. ([#707](https://github.com/OmniSharp/omnisharp-vscode/issues/707)) +* Update Mono detection logic to succeed even if another shell is set as the default (e.g. zsh). ([#1031](https://github.com/OmniSharp/omnisharp-vscode/issues/1031)) + +### Known Issues + +* Running and debugging of tests are not supported in .csproj-based .NET Core projects. However, there will still be clickable "run test" and "debug test" indicators above test methods. ([#1100](https://github.com/OmniSharp/omnisharp-vscode/issues/1100)) +* When opening a .csproj-based .NET Core project in VS Code, the C# extension will not activate until a C# file is opened in the editor. ([#1150](https://github.com/OmniSharp/omnisharp-vscode/issues/1150)) + ## 1.6.2 (December 24, 2016) * Fix performance issue when editing type names containing multiple generic type parameters. ([#1088](https://github.com/OmniSharp/omnisharp-vscode/issues/1088), [#1086](https://github.com/OmniSharp/omnisharp-vscode/issues/1086)) diff --git a/README.md b/README.md index 8a4c193f33..daad8e6795 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ See our [change log](https://github.com/OmniSharp/omnisharp-vscode/blob/master/C * Windows (64-bit only) * macOS * Ubuntu 14.04 / Linux Mint 17 / Linux Mint 18 / Elementary OS 0.3 - * Ubuntu 16.04 / Elementary OS 0.4 / Arch + * Ubuntu 16.04 / Elementary OS 0.4 / Arch / Zorin OS 12 * Ubuntu 16.10 * Debian 8.2 * CentOS 7.1 / Oracle Linux 7 @@ -54,8 +54,6 @@ First install: * Node.js (newer than 4.3.1) * Npm (newer 2.14.12) -In case you get a *node-gyp* error [follow the instrutions here](https://github.com/nodejs/node-gyp/blob/master/README.md) to fix it. The *vscode-textmate* package pulls in a native node dependency and those instructions will set up the node build tool which deals with those. - To **run and develop** do the following: * Run `npm i` diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index 18eea98849..f4d3c8d54b 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -12,7 +12,6 @@ expressly granted, whether by implication, estoppel or otherwise. 3. run-in-terminal version 0.0.2 (https://github.com/microsoft/run-in-terminal) 4. semver version 5.1.0 (https://github.com/npm/node-semver) 5. DefinitelyTyped version 0.0.1 (https://github.com/borisyankov/DefinitelyTyped) -6. language-csharp version 0.11.0 (https://github.com/atom/language-csharp) %% omnisharp-roslyn NOTICES AND INFORMATION BEGINS HERE ============================================================ @@ -123,42 +122,3 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ============================================================ END OF DefinitelyTyped NOTICES AND INFORMATION - -%% language-csharp NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright (c) 2014 GitHub Inc. - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - -This package was derived from a TextMate bundle located at -https://github.com/wintermi/csharp-tmbundle by Matthew Winter @wintermi and -Adam Lickel @lickel and distributed under the following license, located in -`README.markdown`: - -This bundle is dual-licensed under MIT and GPL licenses. - - - http://www.opensource.org/licenses/mit-license.php - - http://www.gnu.org/licenses/gpl.html - -Use it, change it, fork it, sell it. Do what you will, but please leave the -author attribution. -========================================= -END OF language-csharp NOTICES AND INFORMATION diff --git a/csharp.configuration.json b/csharp.configuration.json index 7c3c76c3c4..8707c381f6 100644 --- a/csharp.configuration.json +++ b/csharp.configuration.json @@ -1,11 +1,27 @@ { - "comments": { - "lineComment": "//", - "blockComment": ["/*", "*/"] - }, - "brackets": [ - ["{", "}"], - ["[", "]"], - ["(", ")"] - ] + "comments": { + "lineComment": "//", + "blockComment": ["/*", "*/"] + }, + "brackets": [ + ["{", "}"], + ["[", "]"], + ["(", ")"] + ], + "autoClosingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + { "open": "'", "close": "'", "notIn": ["string", "comment"] }, + { "open": "\"", "close": "\"", "notIn": ["string", "comment"] }, + { "open": "/*", "close": " */", "notIn": ["string"] } + ], + "surroundingPairs": [ + ["{", "}"], + ["[", "]"], + ["(", ")"], + ["<", ">"], + ["'", "'"], + ["\"", "\""] + ] } \ No newline at end of file diff --git a/debugger.md b/debugger.md index 15f59b487b..802ee1dad9 100644 --- a/debugger.md +++ b/debugger.md @@ -14,7 +14,7 @@ File bugs and feature requests [here](https://github.com/OmniSharp/omnisharp-vsc ###First Time setup ##### 1: Get Visual Studio Code -Install Visual Studio Code (VSC). Pick the latest VSC version from here: https://code.visualstudio.com Make sure it is at least 0.10.10. +Install Visual Studio Code (VSC). Pick the latest VSC version from here: https://code.visualstudio.com Make sure it is at least 1.5. If you are not sure what version you have, you can see your version of VS Code: @@ -29,7 +29,7 @@ Install the .NET Core command line tools (CLI) by following the installation par ##### 3: Install C# Extension for VS Code Open the command palette in VS Code (F1) and type "ext install C#" to trigger the installation of the extension. VS Code will show a message that the extension has been installed and it will restart. -If you have previously installed the C# extension, make sure that you have version 1.2 or newer. You can check this by opening the command palette (F1) and running 'Extensions: Show Installed Extensions'. +If you have previously installed the C# extension, make sure that you have a recent version. You can check this by opening the command palette (F1) and running 'Extensions: Show Installed Extensions'. ##### 4: Wait for download of platform-specific files The first time that C# code is opened in VS Code, the extension will download the platform-specific files needed for debugging and editing. Debugging and editor features will not work until these steps finish. @@ -47,20 +47,11 @@ You can start from scratch by creating an empty project with `dotnet new`: dotnet new dotnet restore -You can also find some example projects on https://github.com/aspnet/cli-samples +If you want a web project (ASP.NET project) pass `-t web`. For web projects, makes sure to run `bower install` before running so that they can restore assets. ##### 2: Open the directory in VS Code Go to File->Open and open the directory in Visual Studio Code. If this is the first time that the C# extension has been activated, it will now download additional platform-specific dependencies. -**Troubleshooting 'Error while installing .NET Core Debugger':** If the debugger is failing to download its platform-specific dependencies, first verify that you have the 1.0.0-preview2-003121 or newer build of the .NET CLI installed, and it is functioning. You can check this by starting a bash/command prompt and running 'dotnet --info'. - -If the CLI is installed, here are a few additional suggestions: - -* If clicking on 'View Log' doesn't show a log this means that running the 'dotnet --info' command failed. If it succeeds in bash/command prompt, but fails from VS Code, this likely means that your computer once had an older build of .NET CLI installed, and there are still remnants of it which cause VS Code and other processes besides bash to use the older version instead of the current version. You can resolve this issue by uninstalling the .NET Core CLI, and reinstalling the version you want (see below for macOS). -* If 'dotnet restore' is failing, make sure you have an internet connection to nuget.org, and make sure that if additional NuGet.Config files are being used, they have valid content. The log will indicate what NuGet.Config files were used. Try removing the files other than the one coming from the extension itself. - -MacOS .NET CLI Reinstall Instructions: macOS doesn't have uninstall for pkg files (see [known issue](https://github.com/dotnet/core/blob/master/cli/known-issues.md#uninstallingreinstalling-the-pkg-on-os-x)), one option is to remove the dotnet cli directory with `sudo rm -rf /usr/local/share/dotnet` and then install the pkg again. - ##### 3: Add VS Code configuration files to the workspace VS Code needs to be configured so it understands how to build your project and debug it. For this there are two files which need to be added -- .vscode/tasks.json and .vscode/launch.json. @@ -86,24 +77,15 @@ If your code has multiple projects or you would rather generate these files by h ... "program": "${workspaceRoot}/MyLaunchingProject/bin/Debug/netcoreapp1.0/MyLaunchingProject.dll", -##### 4: Windows Only: Enable Portable PDBs -In the future, this step will go away, but for now you need to [change the project.json to use portable PDBs](https://github.com/OmniSharp/omnisharp-vscode/wiki/Portable-PDBs#net-cli-projects-projectjson). - -##### 5: Pick your debug configuration - -The default launch.json offers several different launch configurations depending on what kind of app you are building -- one for command line, one for web, and one for attaching to a running process. - -To configure which configuration you want, bring up the Debug view by clicking on the Debugging icon in the View Bar on the side of VS Code. - -![Debug view icon](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/debugging_debugicon.png) - -Now open the configuration drop down from the top and select the one you want. - -![Debug launch configuration drop down](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/debug-launch-configurations.png) +##### 4: Start debugging +Your project is now all set. Set a breakpoint or two where you want to stop, click the debugger play button (or hit F5) and you are off. ###Debugging Code compiled on another computer -* If the target binary is built on Linux / OSX, dotnet CLI will produce portable pdbs by default so no action is necessary. -* On Windows, you will need to take additional steps to build [portable PDBs](https://github.com/OmniSharp/omnisharp-vscode/wiki/Portable-PDBs#how-to-generate-portable-pdbs). +If your code was built on a different computer from where you would like to run in there are a few things to keep in mind -- + +* **Source Maps**: Unless your local source code is at exactly the same path as where the code was originally built you will need to add a [sourceFileMap](#source-file-map) to launch.json. +* **Portable PDBs**: If the code was built on Windows, it might have been built using Windows PDBs instead of portable PDBs, but the C# extension only supports portable PDBs. See the [portable PDB documentation](https://github.com/OmniSharp/omnisharp-vscode/wiki/Portable-PDBs#how-to-generate-portable-pdbs) for more information. +* **Debug vs. Release**: It is much easier to debug code which has been compiled in the 'Debug' configuration. So unless the issue you are looking at only reproduces with optimizations, it is much better to use Debug bits. If you do need to debug optimized code, you will need to disable [justMyCode](#just-my-code) in launch.json. ####More things to configure In launch.json #####Just My Code @@ -126,7 +108,7 @@ You can optionally configure a file by file mapping by providing map following t #####Symbol Path You can optionally provide paths to symbols following this schema: - "symbolPath":"[ \"/Volumes/symbols\"]" + "symbolPath": [ "/Volumes/symbols" ] #####Environment variables Environment variables may be passed to your program using this schema: diff --git a/gulpfile.js b/gulpfile.js index 0eb960b7bf..b668c0dcb7 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -145,18 +145,6 @@ gulp.task('package:offline', ['clean'], () => { return promise; }); -/// Test Task -gulp.task('test', () => { - gulp.src('out/test/**/*.tests.js') - .pipe(mocha({ ui: "tdd" })) - .once('error', () => { - process.exit(1); - }) - .once('end', () => { - process.exit(); - }); -}); - /// Misc Tasks const allTypeScript = [ 'src/**/*.ts', diff --git a/package.json b/package.json index 7e5fc7a759..e9ec951725 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.6.2", + "version": "1.7.0-beta5", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", @@ -27,7 +27,6 @@ "compile": "tsc -p ./ && gulp tslint", "watch": "tsc -watch -p ./", "test": "node ./node_modules/vscode/bin/test", - "test-syntax": "mocha --timeout 15000 --ui bdd ./out/test/syntaxes/*.test.syntax.js", "postinstall": "node ./node_modules/vscode/bin/install" }, "dependencies": { @@ -57,17 +56,17 @@ "gulp-mocha": "^2.1.3", "gulp-tslint": "^4.3.0", "mocha": "^2.3.3", + "plist": "^2.0.1", "tslint": "^3.15.1", "tslint-microsoft-contrib": "^2.0.12", "typescript": "^2.0.3", "vsce": "^1.7.0", - "vscode": "^1.0.0", - "vscode-textmate": "^2.1.1" + "vscode": "^1.0.0" }, "runtimeDependencies": [ { "description": "Mono Runtime (Linux / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.linux-x86-4.6.1.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.linux-x86-4.8.0.478.zip", "installPath": "./bin", "platforms": [ "linux" @@ -82,7 +81,7 @@ }, { "description": "Mono Runtime (Linux / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.linux-x86_64-4.6.1.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.linux-x86_64-4.8.0.478.zip", "installPath": "./bin", "platforms": [ "linux" @@ -97,7 +96,7 @@ }, { "description": "Mono Runtime (macOS)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.osx-4.6.1.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/mono.osx-4.8.0.478.zip", "installPath": "./bin", "platforms": [ "darwin" @@ -109,7 +108,7 @@ }, { "description": "Mono Framework Assemblies", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/framework-4.6.1.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/framework-4.8.0.478.zip", "installPath": "./bin/framework", "platforms": [ "darwin", @@ -118,7 +117,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.9-beta22.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.9-beta25.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -129,7 +128,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.9-beta22.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.9-beta25.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -140,7 +139,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.9-beta22.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.9-beta25.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", @@ -149,8 +148,8 @@ }, { "description": ".NET Core Debugger (Windows / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-win7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-win7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "win7-x64" @@ -158,8 +157,8 @@ }, { "description": ".NET Core Debugger (macOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-osx.10.11-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-osx.10.11-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-osx.10.11-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-osx.10.11-x64.zip", "installPath": ".debugger", "runtimeIds": [ "osx.10.11-x64" @@ -171,8 +170,8 @@ }, { "description": ".NET Core Debugger (CentOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-centos.7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-centos.7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-centos.7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-centos.7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "centos.7-x64" @@ -184,8 +183,8 @@ }, { "description": ".NET Core Debugger (Debian / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-debian.8-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-debian.8-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-debian.8-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-debian.8-x64.zip", "installPath": ".debugger", "runtimeIds": [ "debian.8-x64" @@ -197,8 +196,8 @@ }, { "description": ".NET Core Debugger (Fedora 23 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-fedora.23-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-fedora.23-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-fedora.23-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-fedora.23-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.23-x64" @@ -210,8 +209,8 @@ }, { "description": ".NET Core Debugger (Fedora 24 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-fedora.24-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-fedora.24-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-fedora.24-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-fedora.24-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.24-x64" @@ -223,8 +222,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 13 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-opensuse.13.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-opensuse.13.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-opensuse.13.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-opensuse.13.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.13.2-x64" @@ -236,8 +235,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 42 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-opensuse.42.1-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-opensuse.42.1-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-opensuse.42.1-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-opensuse.42.1-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.42.1-x64" @@ -249,8 +248,8 @@ }, { "description": ".NET Core Debugger (RHEL / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-rhel.7.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-rhel.7.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-rhel.7.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-rhel.7.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "rhel.7-x64" @@ -262,8 +261,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 14.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.14.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.14.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.14.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.14.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.14.04-x64" @@ -275,8 +274,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.16.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.16.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.16.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.16.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.04-x64" @@ -288,8 +287,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.10 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.16.10-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-6-3/coreclr-debug-ubuntu.16.10-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.16.10-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-7-1/coreclr-debug-ubuntu.16.10-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.10-x64" @@ -357,10 +356,14 @@ }, "omnisharp.loggingLevel": { "type": "string", - "default": "default", + "default": "information", "enum": [ - "default", - "verbose" + "trace", + "debug", + "information", + "warning", + "error", + "critical" ], "description": "Specifies the level of logging output from the OmniSharp server." }, @@ -390,13 +393,17 @@ { "language": "csharp", "scopeName": "source.cs", - "path": "./syntaxes/csharp.json" + "path": "./syntaxes/csharp.tmLanguage" } ], "jsonValidation": [ { "fileMatch": "project.json", "url": "http://json.schemastore.org/project" + }, + { + "fileMatch": "omnisharp.json", + "url": "http://json.schemastore.org/omnisharp" } ], "commands": [ @@ -418,7 +425,7 @@ { "command": "dotnet.restore", "title": "Restore Packages", - "category": "dotnet" + "category": ".NET" }, { "command": "csharp.downloadDebugger", @@ -707,7 +714,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -747,7 +754,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -784,7 +791,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -821,7 +828,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -957,7 +964,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -997,7 +1004,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -1034,7 +1041,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -1071,7 +1078,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -1144,4 +1151,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/assets.ts b/src/assets.ts index 27f782e321..fc84f874b3 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -95,7 +95,7 @@ export class AssetGenerator { this.hasProject = true; this.projectPath = path.dirname(targetMSBuildProject.Path); this.projectFilePath = targetMSBuildProject.Path; - this.targetFramework = findNetCoreAppTargetFramework(targetMSBuildProject).ShortName; + this.targetFramework = protocol.findNetCoreAppTargetFramework(targetMSBuildProject).ShortName; this.executableName = targetMSBuildProject.AssemblyName + ".dll"; this.configurationName = configurationName; return; @@ -284,15 +284,11 @@ export class AssetGenerator { } } -function findNetCoreAppTargetFramework(project: protocol.MSBuildProject): protocol.TargetFramework { - return project.TargetFrameworks.find(tf => tf.ShortName.startsWith('netcoreapp')); -} - function findExecutableMSBuildProjects(projects: protocol.MSBuildProject[]) { let result: protocol.MSBuildProject[] = []; projects.forEach(project => { - if (project.IsExe && findNetCoreAppTargetFramework(project) !== undefined) { + if (project.IsExe && protocol.findNetCoreAppTargetFramework(project) !== undefined) { result.push(project); } }); @@ -346,6 +342,35 @@ function getOperations(generator: AssetGenerator) { getLaunchOperations(generator.launchJsonPath, operations)); } +function getBuildTasks(tasksConfiguration: tasks.TaskConfiguration): tasks.TaskDescription[] { + let result: tasks.TaskDescription[] = []; + + function findBuildTask(tasksDescriptions: tasks.TaskDescription[]) { + if (tasksDescriptions) { + const buildTask = tasksDescriptions.find(td => td.taskName === 'build'); + if (buildTask !== undefined) { + result.push(buildTask); + } + } + } + + findBuildTask(tasksConfiguration.tasks); + + if (tasksConfiguration.windows) { + findBuildTask(tasksConfiguration.windows.tasks); + } + + if (tasksConfiguration.osx) { + findBuildTask(tasksConfiguration.osx.tasks); + } + + if (tasksConfiguration.linux) { + findBuildTask(tasksConfiguration.linux.tasks); + } + + return result; +} + function getBuildOperations(tasksJsonPath: string) { return new Promise((resolve, reject) => { fs.exists(tasksJsonPath, exists => { @@ -356,19 +381,19 @@ function getBuildOperations(tasksJsonPath: string) { } const text = buffer.toString(); - - let buildTask: tasks.TaskDescription; + let tasksConfiguration: tasks.TaskConfiguration; try { - const tasksJson: tasks.TaskConfiguration = tolerantParse(text); - buildTask = tasksJson.tasks.find(td => td.taskName === 'build'); + tasksConfiguration = tolerantParse(text); } catch (error) { vscode.window.showErrorMessage(`Failed to parse tasks.json file`); - buildTask = undefined; + return resolve({ updateTasksJson: false }); } - resolve({ updateTasksJson: (buildTask === undefined) }); + let buildTasks = getBuildTasks(tasksConfiguration); + + resolve({ updateTasksJson: buildTasks.length === 0 }); }); } else { diff --git a/src/features/commands.ts b/src/features/commands.ts index 3c239446b2..4aa22400b9 100644 --- a/src/features/commands.ts +++ b/src/features/commands.ts @@ -83,9 +83,9 @@ interface Command { execute(): Thenable; } -function projectsToCommands(projects: protocol.DotNetProject[]): Promise[] { +function projectsToCommands(projects: protocol.ProjectDescriptor[]): Promise[] { return projects.map(project => { - let projectDirectory = project.Path; + let projectDirectory = project.Directory; return new Promise((resolve, reject) => { fs.lstat(projectDirectory, (err, stats) => { @@ -98,7 +98,7 @@ function projectsToCommands(projects: protocol.DotNetProject[]): Promise { - if (!info.DotNet || info.DotNet.Projects.length < 1) { + let descriptors = protocol.getDotNetCoreProjectDescriptors(info); + + if (descriptors.length === 0) { return Promise.reject("No .NET Core projects found"); } - let commandPromises = projectsToCommands(info.DotNet.Projects); + let commandPromises = projectsToCommands(descriptors); return Promise.all(commandPromises).then(commands => { return vscode.window.showQuickPick(commands); @@ -133,7 +135,7 @@ export function dotnetRestoreAllProjects(server: OmniSharpServer) { }); } -export function dotnetRestoreForProject(server: OmniSharpServer, fileName: string) { +export function dotnetRestoreForProject(server: OmniSharpServer, filePath: string) { if (!server.isRunning()) { return Promise.reject('OmniSharp server is not running.'); @@ -141,21 +143,21 @@ export function dotnetRestoreForProject(server: OmniSharpServer, fileName: strin return serverUtils.requestWorkspaceInformation(server).then(info => { - if (!info.DotNet || info.DotNet.Projects.length < 1) { + let descriptors = protocol.getDotNetCoreProjectDescriptors(info); + + if (descriptors.length === 0) { return Promise.reject("No .NET Core projects found"); } - let directory = path.dirname(fileName); - - for (let project of info.DotNet.Projects) { - if (project.Path === directory) { - return dotnetRestore(directory, fileName); + for (let descriptor of descriptors) { + if (descriptor.FilePath === filePath) { + return dotnetRestore(descriptor.Directory, filePath); } } }); } -function dotnetRestore(cwd: string, fileName?: string) { +function dotnetRestore(cwd: string, filePath?: string) { return new Promise((resolve, reject) => { channel.clear(); channel.show(); @@ -163,8 +165,8 @@ function dotnetRestore(cwd: string, fileName?: string) { let cmd = 'dotnet'; let args = ['restore']; - if (fileName) { - args.push(fileName); + if (filePath) { + args.push(filePath); } let dotnet = cp.spawn(cmd, args, { cwd: cwd, env: process.env }); diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index f0cdfd47b2..855c66963d 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -79,13 +79,27 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp } const _kinds: { [kind: string]: CompletionItemKind; } = Object.create(null); -_kinds['Variable'] = CompletionItemKind.Variable; -_kinds['Struct'] = CompletionItemKind.Interface; -_kinds['Interface'] = CompletionItemKind.Interface; -_kinds['Enum'] = CompletionItemKind.Enum; -_kinds['EnumMember'] = CompletionItemKind.Property; -_kinds['Property'] = CompletionItemKind.Property; + +// types _kinds['Class'] = CompletionItemKind.Class; +_kinds['Delegate'] = CompletionItemKind.Class; // need a better option for this. +_kinds['Enum'] = CompletionItemKind.Enum; +_kinds['Interface'] = CompletionItemKind.Interface; +_kinds['Struct'] = CompletionItemKind.Class; // need a better option for this. + +// variables +_kinds['Local'] = CompletionItemKind.Variable; +_kinds['Parameter'] = CompletionItemKind.Variable; +_kinds['RangeVariable'] = CompletionItemKind.Variable; + +// members +_kinds['EnumMember'] = CompletionItemKind.Property; // need a better option for this. +_kinds['Event'] = CompletionItemKind.Field; // need a better option for this. _kinds['Field'] = CompletionItemKind.Field; -_kinds['EventField'] = CompletionItemKind.File; +_kinds['Property'] = CompletionItemKind.Property; _kinds['Method'] = CompletionItemKind.Method; + +// other stuff +_kinds['Label'] = CompletionItemKind.Unit; // need a better option for this. +_kinds['Keyword'] = CompletionItemKind.Keyword; +_kinds['Namespace'] = CompletionItemKind.Module; diff --git a/src/features/processPicker.ts b/src/features/processPicker.ts index fcf9c385bd..d0604a0271 100644 --- a/src/features/processPicker.ts +++ b/src/features/processPicker.ts @@ -6,8 +6,7 @@ import * as os from 'os'; import * as vscode from 'vscode'; import * as child_process from 'child_process'; -import * as fs from 'fs'; -import * as path from 'path'; +import { PlatformInformation } from '../platform'; export interface AttachItem extends vscode.QuickPickItem { id: string; @@ -61,43 +60,20 @@ export class RemoteAttachPicker { return Promise.reject(new Error("Name not defined in current configuration.")); } - // Build path for launch.json to find pipeTransport - const vscodeFolder: string = path.join(vscode.workspace.rootPath, '.vscode'); - let launchJsonPath: string = path.join(vscodeFolder, 'launch.json'); - - // Read launch.json - let json: any = JSON.parse(fs.readFileSync(launchJsonPath).toString()); - - // Find correct pipeTransport via selected name - let config; - let configIdx: number; - for (configIdx = 0; configIdx < json.configurations.length; ++configIdx) { - if (json.configurations[configIdx].name === name) { - config = json.configurations[configIdx]; - break; - } - } - - if (configIdx == json.configurations.length) { - // Name not found in list of given configurations. - return Promise.reject(new Error(name + " could not be found in configurations.")); - } - - if (!config.pipeTransport || !config.pipeTransport.debuggerPath) { + if (!args.pipeTransport || !args.pipeTransport.debuggerPath) { // Missing PipeTransport and debuggerPath, prompt if user wanted to just do local attach. return Promise.reject(new Error("Configuration \"" + name + "\" in launch.json does not have a " + "pipeTransport argument with debuggerPath for pickRemoteProcess. Use pickProcess for local attach.")); } else { - let pipeProgram = config.pipeTransport.pipeProgram; - let pipeArgs = config.pipeTransport.pipeArgs; - let platformSpecificPipeTransportOptions = RemoteAttachPicker.getPlatformSpecificPipeTransportOptions(config); + let pipeProgram = args.pipeTransport.pipeProgram; + let pipeArgs = args.pipeTransport.pipeArgs; + let platformSpecificPipeTransportOptions = RemoteAttachPicker.getPlatformSpecificPipeTransportOptions(args); if (platformSpecificPipeTransportOptions) { pipeProgram = platformSpecificPipeTransportOptions.pipeProgram || pipeProgram; pipeArgs = platformSpecificPipeTransportOptions.pipeArgs || pipeArgs; } - let argList = RemoteAttachPicker.createArgumentList(pipeArgs); let pipeCmd: string = `"${pipeProgram}" ${argList}`; return RemoteAttachPicker.getRemoteOSAndProcesses(pipeCmd).then(processes => { @@ -107,7 +83,7 @@ export class RemoteAttachPicker { placeHolder: "Select the process to attach to" }; return vscode.window.showQuickPick(processes, attachPickOptions).then(item => { - return item ? item.id : null; + return item ? item.id : Promise.reject(new Error("Could not find a process id to attach.")); }); }); } @@ -142,13 +118,13 @@ export class RemoteAttachPicker { public static getRemoteOSAndProcesses(pipeCmd: string): Promise { // Commands to get OS and processes - const command = `uname && if [ $(uname) == "Linux" ] ; then ${RemoteAttachPicker.linuxPsCommand} ; elif [ $(uname) == "Darwin" ] ; ` + - `then ${RemoteAttachPicker.osxPsCommand}; fi`; + const command = `bash -c 'uname && if [ $(uname) == "Linux" ] ; then ${RemoteAttachPicker.linuxPsCommand} ; elif [ $(uname) == "Darwin" ] ; ` + + `then ${RemoteAttachPicker.osxPsCommand}; fi'`; return execChildProcessAndOutputErrorToChannel(`${pipeCmd} "${command}"`, null, RemoteAttachPicker._channel).then(output => { // OS will be on first line // Processess will follow if listed - let lines = output.split(os.EOL); + let lines = output.split(/\r?\n/); if (lines.length == 0) { return Promise.reject(new Error("Pipe transport failed to get OS and processes.")); @@ -170,14 +146,6 @@ export class RemoteAttachPicker { } }); } - - public static getRemoteProcesses(pipeCmd: string, os: string): Promise { - const psCommand = os === 'darwin' ? RemoteAttachPicker.osxPsCommand : RemoteAttachPicker.linuxPsCommand; - - return execChildProcessAndOutputErrorToChannel(`${pipeCmd} ${psCommand}`, null, RemoteAttachPicker._channel).then(output => { - return sortProcessEntries(PsOutputParser.parseProcessFromPs(output), os); - }); - } } class Process { @@ -422,33 +390,51 @@ function execChildProcess(process: string, workingDirectory: string): Promise { + return PlatformInformation.GetCurrent().then(platformInfo => { + let env = process.env; + if (platformInfo.isWindows && platformInfo.architecture === "x86_64") { + let sysnative : String = process.env.WINDIR + "\\sysnative"; + env.Path = process.env.PATH + ";" + sysnative; + } + + return env; + }); +} + function execChildProcessAndOutputErrorToChannel(process: string, workingDirectory: string, channel: vscode.OutputChannel): Promise { - channel.appendLine(`Executing: ${process}`); + channel.appendLine(`Executing: ${process}`); + return new Promise((resolve, reject) => { - child_process.exec(process, { cwd: workingDirectory, maxBuffer: 500 * 1024 }, (error: Error, stdout: string, stderr: string) => { - let channelOutput = ""; - - if (stdout && stdout.length > 0) { - channelOutput.concat(stdout); - } + return GetSysNativePathIfNeeded().then(newEnv => { + child_process.exec(process, { cwd: workingDirectory, env: newEnv, maxBuffer: 500 * 1024 }, (error: Error, stdout: string, stderr: string) => { + let channelOutput = ""; + + if (stdout && stdout.length > 0) { + channelOutput.concat(stdout); + } - if (stderr && stderr.length > 0) { - channelOutput.concat(stderr); - } + if (stderr && stderr.length > 0) { + channelOutput.concat(stderr); + } - if (error) { - channelOutput.concat(error.message); - } + if (error) { + channelOutput.concat(error.message); + } - if (error || (stderr && stderr.length > 0)) { - channel.append(channelOutput); - channel.show(); - reject(new Error("See remote-attach output")); - return; - } + if (error || (stderr && stderr.length > 0)) { + channel.append(channelOutput); + channel.show(); + reject(new Error("See remote-attach output")); + return; + } - resolve(stdout); + resolve(stdout); + }); }); }); diff --git a/src/features/status.ts b/src/features/status.ts index a28109a325..718a31dc22 100644 --- a/src/features/status.ts +++ b/src/features/status.ts @@ -241,7 +241,10 @@ export function reportServerStatus(server: OmniSharpServer): vscode.Disposable{ message.Errors.forEach(error => asErrorMessage); message.Warnings.forEach(warning => asWarningMessage); appendLine(); - showMessageSoon(); + + if (message.Errors.length > 0) { + showMessageSoon(); + } } }); diff --git a/src/main.ts b/src/main.ts index 9b7d8a57ca..e7c6fd093a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -66,6 +66,9 @@ function installRuntimeDependencies(extension: vscode.Extension, logger: Lo } }; + // Sends "AcquisitionStart" telemetry to indicate an acquisition started. + reporter.sendTelemetryEvent("AcquisitionStart"); + let platformInfo: PlatformInformation; let packageManager: PackageManager; let installationStage = 'touchBeginFile'; diff --git a/src/omnisharp/options.ts b/src/omnisharp/options.ts index 5cd72f0f3d..2f62130c51 100644 --- a/src/omnisharp/options.ts +++ b/src/omnisharp/options.ts @@ -33,7 +33,12 @@ export class Options { ? csharpConfig.get('omnisharpUsesMono') : omnisharpConfig.get('useMono'); - const loggingLevel = omnisharpConfig.get('loggingLevel'); + // support the legacy "verbose" level as "debug" + let loggingLevel = omnisharpConfig.get('loggingLevel'); + if (loggingLevel.toLowerCase() === 'verbose') { + loggingLevel = 'debug'; + } + const autoStart = omnisharpConfig.get('autoStart', true); const projectLoadTimeout = omnisharpConfig.get('projectLoadTimeout', 60); diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 351651c31e..4fb8865bfd 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -5,6 +5,8 @@ 'use strict'; +import * as path from 'path'; + export module Requests { export const AddToProject = '/addtoproject'; export const AutoComplete = '/autocomplete'; @@ -509,4 +511,47 @@ export namespace V2 { Failure: string; Pass: boolean; } +} + +export function findNetCoreAppTargetFramework(project: MSBuildProject): TargetFramework { + return project.TargetFrameworks.find(tf => tf.ShortName.startsWith('netcoreapp')); +} + +export function findNetStandardTargetFramework(project: MSBuildProject): TargetFramework { + return project.TargetFrameworks.find(tf => tf.ShortName.startsWith('netstandard')); +} + +export interface ProjectDescriptor { + Name: string; + Directory: string; + FilePath: string; +} + +export function getDotNetCoreProjectDescriptors(info: WorkspaceInformationResponse): ProjectDescriptor[] { + let result = []; + + if (info.DotNet && info.DotNet.Projects.length > 0) { + for (let project of info.DotNet.Projects) { + result.push({ + Name: project.Name, + Directory: project.Path, + FilePath: path.join(project.Path, 'project.json') + }); + } + } + + if (info.MsBuild && info.MsBuild.Projects.length > 0) { + for (let project of info.MsBuild.Projects) { + if (findNetCoreAppTargetFramework(project) !== undefined || + findNetStandardTargetFramework(project) !== undefined) { + result.push({ + Name: path.basename(project.Path), + Directory: path.dirname(project.Path), + FilePath: project.Path + }); + } + } + } + + return result; } \ No newline at end of file diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index cf4f886a27..80174e7f42 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -13,6 +13,7 @@ import { DelayTracker } from './delayTracker'; import { LaunchTarget, findLaunchTargets } from './launcher'; import { Request, RequestQueueCollection } from './requestQueue'; import TelemetryReporter from 'vscode-extension-telemetry'; +import * as os from 'os'; import * as path from 'path'; import * as protocol from './protocol'; import * as vscode from 'vscode'; @@ -234,20 +235,17 @@ export class OmniSharpServer { const solutionPath = launchTarget.target; const cwd = path.dirname(solutionPath); + this._options = Options.Read(); + let args = [ '-s', solutionPath, '--hostPID', process.pid.toString(), '--stdio', 'DotNet:enablePackageRestore=false', - '--encoding', 'utf-8' + '--encoding', 'utf-8', + '--loglevel', this._options.loggingLevel ]; - this._options = Options.Read(); - - if (this._options.loggingLevel === 'verbose') { - args.push('-v'); - } - this._logger.appendLine(`Starting OmniSharp server at ${new Date().toLocaleString()}`); this._logger.increaseIndent(); this._logger.appendLine(`Target: ${solutionPath}`); @@ -539,7 +537,7 @@ export class OmniSharpServer { if (packet.Event === 'log') { const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body; this._logOutput(entry.LogLevel, entry.Name, entry.Message); - } + } else { // fwd all other events this._fireEvent(packet.Event, packet.Body); @@ -569,13 +567,34 @@ export class OmniSharpServer { return id; } + private static getLogLevelPrefix(logLevel: string) { + switch (logLevel) { + case "TRACE": return "trce"; + case "DEBUG": return "dbug"; + case "INFORMATION": return "info"; + case "WARNING": return "warn"; + case "ERROR": return "fail"; + case "CRITICAL": return "crit"; + default: throw new Error(`Unknown log level value: ${logLevel}`); + } + } + + private _isFilterableOutput(logLevel: string, name: string, message: string) { + // filter messages like: /codecheck: 200 339ms + const timing200Pattern = /^\/[\/\w]+: 200 \d+ms/; + + return logLevel === "INFORMATION" + && name === "OmniSharp.Middleware.LoggingMiddleware" + && timing200Pattern.test(message); + } + private _logOutput(logLevel: string, name: string, message: string) { - const timing200Pattern = /^\[INFORMATION:OmniSharp.Middleware.LoggingMiddleware\] \/[\/\w]+: 200 \d+ms/; + if (this._debugMode || !this._isFilterableOutput(logLevel, name, message)) { + let output = `[${OmniSharpServer.getLogLevelPrefix(logLevel)}]: ${name}${os.EOL}${message}`; + + const newLinePlusPadding = os.EOL + " "; + output = output.replace(os.EOL, newLinePlusPadding); - const output = `[${logLevel}:${name}] ${message}`; - - // strip stuff like: /codecheck: 200 339ms - if (this._debugMode || !timing200Pattern.test(output)) { this._logger.appendLine(output); } } diff --git a/src/platform.ts b/src/platform.ts index 3720cfd056..f19289f1c1 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -167,27 +167,14 @@ export class PlatformInformation { } private static GetWindowsArchitecture(): Promise { - return util.execChildProcess('wmic os get osarchitecture') - .then(architecture => { - if (architecture) { - let archArray: string[] = architecture.split(os.EOL); - if (archArray.length >= 2) { - let arch = archArray[1].trim(); - - // Note: This string can be localized. So, we'll just check to see if it contains 32 or 64. - if (arch.indexOf('64') >= 0) { - return "x86_64"; - } - else if (arch.indexOf('32') >= 0) { - return "x86"; - } - } - } - - return unknown; - }).catch((error) => { - return unknown; - }); + return new Promise((resolve, reject) => { + if (process.env.PROCESSOR_ARCHITECTURE === 'x86' && process.env.PROCESSOR_ARCHITEW6432 === undefined) { + resolve('x86'); + } + else { + resolve('x86_64'); + } + }); } private static GetUnixArchitecture(): Promise { @@ -278,6 +265,11 @@ export class PlatformInformation { const ubuntu_16_10 = 'ubuntu.16.10-x64'; switch (distributionName) { + case 'Zorin OS': + if (distributionVersion === "12") { + return ubuntu_16_04; + } + break; case 'ubuntu': if (distributionVersion === "14.04") { // This also works for Linux Mint diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index 71b81eccf1..62f52c114a 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -26,7 +26,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, @@ -64,7 +64,7 @@ }, "pipeArgs": { "type": "array", - "description": "Command line arguments passed to the pipe program.", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", "items": { "type": "string" }, diff --git a/src/tools/README.md b/src/tools/README.md index 7f2585c39d..bab72413f2 100644 --- a/src/tools/README.md +++ b/src/tools/README.md @@ -2,7 +2,7 @@ OptionsSchema.json defines the type for Launch/Attach options. # GenerateOptionsSchema -If there are any modifications to the OptionsSchema.json file. Please run `gulp updateOptionsSchema` at the repo root. +If there are any modifications to the OptionsSchema.json file. Please run `gulp generateOptionsSchema` at the repo root. This will call GenerateOptionsSchema and update the package.json file. **NOTE:** *Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes will be diff --git a/syntaxes/csharp.json b/syntaxes/csharp.json deleted file mode 100644 index a3b1af6104..0000000000 --- a/syntaxes/csharp.json +++ /dev/null @@ -1,814 +0,0 @@ -{ - "scopeName": "source.cs", - "name": "C#", - "fileTypes": [ - "cs" - ], - "foldingStartMarker": "^\\s*#\\s*region|^\\s*/\\*|^(?![^{]*?//|[^{]*?/\\*(?!.*?\\*/.*?\\{)).*?\\{\\s*($|//|/\\*(?!.*?\\*/.*\\S))", - "foldingStopMarker": "^\\s*#\\s*endregion|^\\s*\\*/|^\\s*\\}", - "patterns": [ - { - "include": "#using" - }, - { - "include": "#namespace" - }, - { - "include": "#code" - } - ], - "repository": { - "using": { - "begin": "^\\s*(using)\\b\\s*", - "captures": { - "1": { - "name": "keyword.other.using.cs" - } - }, - "end": "\\s*(?:$|;)" - }, - "namespace": { - "begin": "^\\s*[^@]?((namespace)\\s+([\\w.]+))", - "beginCaptures": { - "1": { - "name": "meta.namespace.identifier.cs" - }, - "2": { - "name": "keyword.other.namespace.cs" - }, - "3": { - "name": "entity.name.type.namespace.cs" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.namespace.end.cs" - } - }, - "name": "meta.namespace.cs", - "patterns": [ - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.namespace.begin.cs" - } - }, - "end": "(?=})", - "name": "meta.namespace.body.cs", - "patterns": [ - { - "include": "#using" - }, - { - "include": "#namespace" - }, - { - "include": "#code" - } - ] - } - ] - }, - "field-declaration": { - "patterns": [ - { - "begin": "(?=(?:(?:(?:private|public|volatile|internal|protected|static|readonly|const|event)\\s*)*)(?:[\\w\\s,<>\\[\\]]+?)(?:[\\w]+)\\s*(?:;|=|=>))", - "end": "(?=;)", - "patterns": [ - { - "match": "^\\s*((?:(?:private|public|volatile|internal|protected|static|readonly|const|event)\\s*)*)\\s*(.+?)\\s*([\\w]+)\\s*(?=;|=)", - "captures": { - "1" : { - "patterns": [ - { - "include": "#storage-modifiers" - } - ] - }, - "2" : { - "patterns": [ - { - "include": "#type" - } - ] - }, - "3": { - "name": "entity.name.variable.cs" - } - } - }, - { - "begin": "(?==>?)", - "end": "(?=;|$)", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - } - ] - }, - "variable": { - "patterns": [ - { - "match": "^\\s*\\b(var)\\s+(.*?)(?=(=|;))", - "captures": { - "1": { - "name": "keyword.other.var.cs" - } - } - }, - { - "match": "^\\s*\\b(?!var|return|yield|throw)([\\w<>*?\\[\\]]+)\\s+([\\w]+)\\s*(?=(=(?!=)|;))", - "captures": { - "1": { - "name": "storage.type.variable.cs" - } - } - } - ] - }, - "block": { - "patterns": [ - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.block.begin.cs" - } - }, - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.block.end.cs" - } - }, - "name": "meta.block.cs", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - }, - "builtinTypes": { - "patterns": [ - { - "match": "\\b(bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|class|struct|enum|interface)\\b", - "name": "storage.type.cs" - } - ] - }, - "type": { - "patterns": [ - { - "match": "([\\w\\.]+\\s*<(?:[\\w\\s,\\.`\\[\\]\\*]+)+>(?:\\s*\\[\\s*\\])?)", - "comment": "generic type", - "captures": { - "1": { - "name": "storage.type.cs" - } - } - }, - { - "match": "\\b([a-zA-Z]+[\\w\\.]*\\b(?:\\s*\\[\\s*\\])?\\*?)", - "comment": "non-generic type", - "captures": { - "1": { - "name": "storage.type.cs" - } - } - } - ] - }, - "generic-constraints": { - "begin": "(where)\\s+(\\w+)\\s*:", - "end": "(?=where|{|$)", - "beginCaptures": { - "1": { - "name": "keyword.other.cs" - }, - "2": { - "name": "storage.type.cs" - } - }, - "patterns": [ - { - "match": "\\b(class|struct)\\b", - "name": "keyword.other.cs" - }, - { - "match": "(new)\\s*\\(\\s*\\)", - "captures": { - "1": { - "name": "keyword.other.cs" - } - } - }, - { - "include": "#type" - }, - { - "include": "#generic-constraints" - } - ] - }, - "type-declaration": { - "begin": "(?=\\w?[\\w\\s]*[^@]?(?:class|struct|interface|enum)\\s+\\w+)", - "end": "}", - "endCaptures": { - "0": { - "name": "punctuation.section.class.end.cs" - } - }, - "name": "meta.class.cs", - "patterns": [ - { - "include": "#storage-modifiers" - }, - { - "include": "#comments" - }, - { - "begin": "(class|struct|interface|enum)\\s+", - "end": "(?={|:|$|where)", - "name": "meta.class.identifier.cs", - "beginCaptures": { - "1": { - "name": "storage.modifier.cs" - } - }, - "patterns": [ - { - "include": "#type" - } - ] - }, - { - "begin": ":", - "end": "(?={|where)", - "patterns": [ - { - "include": "#type" - }, - { - "match": "([\\w<>]+)\\s*", - "captures": { - "1": { - "name": "storage.type.cs" - } - } - } - ] - }, - { - "include": "#generic-constraints" - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.class.begin.cs" - } - }, - "end": "(?=})", - "name": "meta.class.body.cs", - "patterns": [ - { - "include": "#type-body" - } - ] - } - ] - }, - "type-body": { - "patterns": [ - { - "include": "type-declaration" - }, - { - "include": "#field-declaration" - }, - { - "include": "#property-declaration" - }, - { - "include": "#method" - }, - { - "include": "#storage-modifiers" - }, - { - "include": "#code" - } - ] - }, - "code": { - "patterns": [ - { - "include": "#block" - }, - { - "include": "#comments" - }, - { - "include": "#type-declaration" - }, - { - "include": "#variable" - }, - { - "include": "#constants" - }, - { - "include": "#storage-modifiers" - }, - { - "include": "#keywords" - }, - { - "include": "#preprocessor" - }, - { - "include": "#method-call" - }, - { - "include": "#builtinTypes" - }, - { - "include": "#documentation" - } - ] - }, - "comments": { - "patterns": [ - { - "begin": "///", - "captures": { - "0": { - "name": "punctuation.definition.comment.cs" - } - }, - "end": "$\\n?", - "name": "comment.block.documentation.cs", - "patterns": [ - { - "include": "text.xml" - } - ] - }, - { - "begin": "/\\*", - "captures": { - "0": { - "name": "punctuation.definition.comment.cs" - } - }, - "end": "\\*/\\n?", - "name": "comment.block.cs" - }, - { - "begin": "//", - "captures": { - "1": { - "name": "punctuation.definition.comment.cs" - } - }, - "end": "$\\n?", - "name": "comment.line.double-slash.cs" - } - ] - }, - "string-interpolated": { - "patterns": [ - { - "begin": "\\$\"", - "end": "\"|$", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.cs" - } - }, - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cs" - } - }, - "patterns": [ - { - "begin": "([^{}]+?)(?={|\"|$)", - "end": "(?={|\"|$)", - "beginCaptures": { - "1": { - "name": "string.quoted.double.cs" - } - } - }, - { - "begin": "{", - "end": "}", - "name": "meta.interpolated.expression.cs", - "patterns":[ - { - "include":"#code" - } - ] - }, - { - "begin": "([^{}]+?)(?={|\"|$)", - "end": "(?={|\"|$)", - "beginCaptures": { - "1": { - "name": "string.quoted.double.cs" - } - } - } - ] - } - ] - }, - "string-interpolated-verbatim": { - "patterns": [ - { - "begin": "\\$@\"", - "end": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.cs" - } - }, - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cs" - } - }, - "patterns": [ - { - "begin": "([^{}]+?)(?={|\"|$)", - "end": "(?={|\"|$)", - "beginCaptures": { - "1": { - "name": "string.quoted.double.literal.cs" - } - } - }, - { - "begin": "{", - "end": "}", - "name": "meta.interpolated.expression.cs", - "patterns":[ - { - "include":"#code" - } - ] - }, - { - "begin": "([^{}]+?)(?={|\"|$)", - "end": "(?={|\"|$)", - "beginCaptures": { - "1": { - "name": "string.quoted.double.literal.cs" - } - } - } - ] - } - ] - }, - "string": { - "patterns":[ - { - "include": "#string-interpolated-verbatim" - }, - { - "include": "#string-interpolated" - }, - { - "captures": { - "0": { - "name": "punctuation.definition.string.begin.cs" - } - }, - "match": "@\"([^\"]|\"\")*\"", - "name": "string.quoted.double.literal.cs" - }, - { - "begin": "\"", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.cs" - } - }, - "end": "\"", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cs" - } - }, - "name": "string.quoted.double.cs", - "patterns": [ - { - "match": "\\\\.", - "name": "constant.character.escape.cs" - } - ] - }, - { - "begin": "'", - "beginCaptures": { - "0": { - "name": "punctuation.definition.string.begin.cs" - } - }, - "end": "'", - "endCaptures": { - "0": { - "name": "punctuation.definition.string.end.cs" - } - }, - "name": "string.quoted.single.cs", - "patterns": [ - { - "match": "\\\\.", - "name": "constant.character.escape.cs" - } - ] - } - ] - }, - "constants": { - "patterns": [ - { - "match": "\\b(true|false|null|this|base)\\b", - "name": "constant.language.cs" - }, - { - "match": "\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)(L|l|UL|ul|u|U|F|f|ll|LL|ull|ULL)?\\b", - "name": "constant.numeric.cs" - }, - { - "include": "#string" - } - ] - }, - "keywords": { - "patterns": [ - { - "match": "\\b(if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await|when)\\b", - "name": "keyword.control.cs" - }, - { - "match": "\\b(from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending)\\b", - "name": "keyword.linq.cs" - }, - { - "match": "\\b(event|delegate|fixed|add|remove|set|get|value|new|is|as|using|checked|unchecked|typeof|sizeof|stackalloc|nameof)\\b", - "name": "keyword.other.cs" - }, - { - "match": "[@]\\b(namespace|class|var|event|delegate|add|remove|set|get|value|new|is|as|using|checked|unchecked|typeof|sizeof|nameof|when|override|readonly|stackalloc|from|where|select|group|into|orderby|join|let|on|equals|by|ascending|descending|if|else|while|for|foreach|in|do|return|continue|break|switch|case|default|goto|throw|try|catch|finally|lock|yield|await|internal|public|protected|private|static|const|sealed|abstract|virtual|extern|unsafe|volatile|implicit|explicit|operator|async|partial|bool|byte|sbyte|char|decimal|double|float|int|uint|long|ulong|object|short|ushort|string|void|struct|enum|interface)\\b", - "name": "meta.class.body.cs" - } - ] - }, - "attribute": { - "begin": "\\[", - "end": "\\]", - "name": "meta.method.annotation.cs", - "patterns": [ - { - "include": "#constants" - }, - { - "include": "#preprocessor" - }, - { - "include": "#builtinTypes" - } - ] - }, - "property-declaration": { - "begin": "^\\s*(?!.*\\b(?:class|interface|struct)\\b)((?:\\w+\\s+)*?)(?!(?:private|public|internal|protected|static|new|virtual|override))(\\w.+?)\\s+(\\w+)\\s*(?={|$)", - "end": "}|;|$", - "beginCaptures": { - "1" : { - "patterns": [ - { - "include": "#storage-modifiers" - } - ] - }, - "2" : { - "patterns": [ - { - "include": "#type" - } - ] - }, - "3": { - "name": "entity.name.function.cs" - } - }, - "name": "meta.property.cs", - "patterns": [ - { - "include": "#block" - }, - { - "begin": "=", - "end": "(?=;)", - "patterns":[ - { - "include": "#code" - } - ] - } - ] - }, - "method": { - "patterns": [ - { - "include": "attribute" - }, - { - "begin": "(?=\\bnew\\s+)(?=[\\w<].*\\s+)(?=[^=]+\\()", - "end": "(?={|;)", - "name": "meta.new-object.cs", - "patterns": [ - { - "include": "#code" - } - ] - }, - { - "begin": "(?\\s,`?]*>)?)\\s*\\(", - "beginCaptures": { - "1": { - "name": "entity.name.function.cs" - } - }, - "end": "\\)", - "name": "meta.method.identifier.cs", - "patterns": [ - { - "include": "#parameters" - }, - { - "include": "#constants" - } - ] - }, - { - "begin": "(?=\\w.*\\s+[\\w.]+\\s*\\()", - "end": "(?=[\\w.]+\\s*\\()", - "name": "meta.method.return-type.cs", - "patterns": [ - { - "include": "#builtinTypes" - } - ] - }, - { - "begin": ":\\s*(this|base)\\s*\\(", - "beginCaptures": { - "1": { - "name": "constant.language.cs" - } - }, - "end": "\\)", - "name": "meta.method.base-call.cs", - "patterns": [ - { - "include": "#builtinTypes" - } - ] - }, - { - "begin": "=>", - "beginCaptures": { - "0": { - "name": "punctuation.section.method.begin.cs" - } - }, - "end": "(?=;)", - "name": "meta.method.body.cs", - "patterns": [ - { - "include": "#code" - } - ] - }, - { - "begin": "{", - "beginCaptures": { - "0": { - "name": "punctuation.section.method.begin.cs" - } - }, - "end": "(?=})", - "name": "meta.method.body.cs", - "patterns": [ - { - "include": "#code" - } - ] - } - ] - } - ] - }, - "method-call": { - "begin": "([\\w$]+)\\s*(\\()", - "beginCaptures": { - "1": { - "name": "meta.method.cs" - }, - "2": { - "name": "punctuation.definition.method-parameters.begin.cs" - } - }, - "end": "\\)", - "endCaptures": { - "0": { - "name": "punctuation.definition.method-parameters.end.cs" - } - }, - "name": "meta.method-call.cs", - "patterns": [ - { - "match": ",", - "name": "punctuation.definition.seperator.parameter.cs" - }, - { - "include": "#code" - } - ] - }, - "parameters": { - "begin": "\\b(ref|params|out)?\\s*\\b(\\w+(?:\\s*<.*?>)?(?:\\s*\\*)*(?:\\s*\\?)?(?:\\s*\\[.*?\\])?)\\s+(@?\\w+)\\s*(=)?", - "beginCaptures": { - "1": { - "name": "storage.type.modifier.cs" - }, - "2": { - "name": "storage.type.generic.cs" - }, - "3": { - "name": "variable.parameter.function.cs" - }, - "4": { - "name": "keyword.operator.assignment.cs" - } - }, - "end": "(?:(,)|(?=[\\)]))", - "endCaptures": { - "1": { - "name": "punctuation.definition.separator.parameter.cs" - } - }, - "patterns": [ - { - "include": "#constants" - }, - { - "include": "#block" - } - ] - }, - "preprocessor": { - "patterns": [ - { - "captures": { - "2": { - "name": "entity.name.function.preprocessor.cs" - } - }, - "match": "^\\s*#\\s*(if|else|elif|endif|define|undef|warning|error|line|pragma|region|endregion)\\b\\s*(.*?)(?=$|\\/\\/)", - "name": "meta.preprocessor.cs" - } - ] - }, - "storage-modifiers": { - "match": "\\b(event|delegate|internal|public|protected|private|static|const|new|sealed|abstract|virtual|override|extern|unsafe|readonly|volatile|implicit|explicit|operator|async|partial)\\b", - "name": "storage.modifier.cs" - } - } -} diff --git a/syntaxes/csharp.tmLanguage b/syntaxes/csharp.tmLanguage new file mode 100644 index 0000000000..97bc5501ea --- /dev/null +++ b/syntaxes/csharp.tmLanguage @@ -0,0 +1,6792 @@ + + + + + name + C# + scopeName + source.cs + fileTypes + + cs + + uuid + f7de61e2-bdde-4e2a-a139-8221b179584e + patterns + + + include + #preprocessor + + + include + #comment + + + include + #directives + + + include + #declarations + + + include + #script-top-level + + + repository + + directives + + patterns + + + include + #extern-alias-directive + + + include + #using-directive + + + include + #attribute-section + + + include + #punctuation-semicolon + + + + declarations + + patterns + + + include + #namespace-declaration + + + include + #type-declarations + + + include + #punctuation-semicolon + + + + script-top-level + + patterns + + + include + #method-declaration + + + include + #statement + + + include + #punctuation-semicolon + + + + type-declarations + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #storage-modifier + + + include + #class-declaration + + + include + #delegate-declaration + + + include + #enum-declaration + + + include + #interface-declaration + + + include + #struct-declaration + + + include + #attribute-section + + + include + #punctuation-semicolon + + + + class-or-struct-members + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #storage-modifier + + + include + #type-declarations + + + include + #field-declaration + + + include + #event-declaration + + + include + #property-declaration + + + include + #indexer-declaration + + + include + #variable-initializer + + + include + #constructor-declaration + + + include + #destructor-declaration + + + include + #operator-declaration + + + include + #conversion-operator-declaration + + + include + #method-declaration + + + include + #attribute-section + + + include + #punctuation-semicolon + + + + interface-members + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #event-declaration + + + include + #property-declaration + + + include + #indexer-declaration + + + include + #method-declaration + + + include + #attribute-section + + + include + #punctuation-semicolon + + + + statement + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #while-statement + + + include + #do-statement + + + include + #for-statement + + + include + #foreach-statement + + + include + #if-statement + + + include + #else-part + + + include + #switch-statement + + + include + #goto-statement + + + include + #return-statement + + + include + #break-or-continue-statement + + + include + #throw-statement + + + include + #yield-statement + + + include + #try-statement + + + include + #checked-unchecked-statement + + + include + #lock-statement + + + include + #using-statement + + + include + #labeled-statement + + + include + #local-declaration + + + include + #block + + + include + #expression + + + include + #punctuation-semicolon + + + + expression + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #checked-unchecked-expression + + + include + #typeof-or-default-expression + + + include + #nameof-expression + + + include + #interpolated-string + + + include + #verbatim-interpolated-string + + + include + #this-or-base-expression + + + include + #conditional-operator + + + include + #expression-operators + + + include + #await-expression + + + include + #query-expression + + + include + #as-expression + + + include + #is-expression + + + include + #anonymous-method-expression + + + include + #object-creation-expression + + + include + #array-creation-expression + + + include + #anonymous-object-creation-expression + + + include + #member-access-expression + + + include + #invocation-expression + + + include + #element-access-expression + + + include + #cast-expression + + + include + #literal + + + include + #parenthesized-expression + + + include + #tuple-deconstruction-assignment + + + include + #initializer-expression + + + include + #identifier + + + + extern-alias-directive + + begin + \s*(extern)\b\s*(alias)\b\s*([_[:alpha:]][_[:alnum:]]*) + beginCaptures + + 1 + + name + keyword.other.extern.cs + + 2 + + name + keyword.other.alias.cs + + 3 + + name + variable.other.alias.cs + + + end + (?=;) + + using-directive + + patterns + + + begin + \b(using)\b\s+(static)\s+ + beginCaptures + + 1 + + name + keyword.other.using.cs + + 2 + + name + keyword.other.static.cs + + + end + (?=;) + patterns + + + include + #type + + + + + begin + \b(using)\s+(?=([_[:alpha:]][_[:alnum:]]*)\s*=) + beginCaptures + + 1 + + name + keyword.other.using.cs + + 2 + + name + entity.name.type.alias.cs + + + end + (?=;) + patterns + + + include + #comment + + + include + #type + + + include + #operator-assignment + + + + + begin + \b(using)\s* + beginCaptures + + 1 + + name + keyword.other.using.cs + + + end + (?=;) + patterns + + + include + #comment + + + name + entity.name.type.namespace.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #operator-assignment + + + + + + attribute-section + + begin + (\[)(assembly|module|field|event|method|param|property|return|type)?(\:)? + beginCaptures + + 1 + + name + punctuation.squarebracket.open.cs + + 2 + + name + keyword.other.attribute-specifier.cs + + 3 + + name + punctuation.separator.colon.cs + + + end + (\]) + endCaptures + + 1 + + name + punctuation.squarebracket.close.cs + + + patterns + + + include + #comment + + + include + #attribute + + + include + #punctuation-comma + + + + attribute + + patterns + + + include + #type-name + + + include + #attribute-arguments + + + + attribute-arguments + + begin + (\() + beginCaptures + + 1 + + name + punctuation.parenthesis.open.cs + + + end + (\)) + endCaptures + + 1 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #attribute-named-argument + + + include + #expression + + + include + #punctuation-comma + + + + attribute-named-argument + + begin + ([_[:alpha:]][_[:alnum:]]*)\s*(?==) + beginCaptures + + 1 + + name + entity.name.variable.property.cs + + + end + (?=(,|\))) + patterns + + + include + #operator-assignment + + + include + #expression + + + + namespace-declaration + + begin + \b(namespace)\s+ + beginCaptures + + 1 + + name + keyword.other.namespace.cs + + + end + (?<=\}) + patterns + + + include + #comment + + + name + entity.name.type.namespace.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #punctuation-accessor + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #declarations + + + include + #using-directive + + + include + #punctuation-semicolon + + + + + + storage-modifier + + name + storage.modifier.cs + match + (?<!\.)\b(new|public|protected|internal|private|abstract|virtual|override|sealed|static|partial|readonly|volatile|const|extern|async|unsafe)\b + + class-declaration + + begin + (?=\bclass\b) + end + (?<=\}) + patterns + + + begin + (?x) +\b(class)\b\s+ +([_[:alpha:]][_[:alnum:]]*)\s* + beginCaptures + + 1 + + name + keyword.other.class.cs + + 2 + + name + entity.name.type.class.cs + + + end + (?=\{) + patterns + + + include + #type-parameter-list + + + include + #base-types + + + include + #generic-constraints + + + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #class-or-struct-members + + + + + include + #preprocessor + + + include + #comment + + + + delegate-declaration + + begin + (?x) +(?:\b(delegate)\b)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* +(<([^<>]+)>)?\s* +(?=\() + beginCaptures + + 1 + + name + keyword.other.delegate.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.type.delegate.cs + + 8 + + patterns + + + include + #type-parameter-list + + + + + end + (?=;) + patterns + + + include + #comment + + + include + #parenthesized-parameter-list + + + include + #generic-constraints + + + + enum-declaration + + begin + (?=\benum\b) + end + (?<=\}) + patterns + + + begin + (?=enum) + end + (?=\{) + patterns + + + match + (enum)\s+([_[:alpha:]][_[:alnum:]]*) + captures + + 1 + + name + keyword.other.enum.cs + + 2 + + name + entity.name.type.enum.cs + + + + + begin + : + beginCaptures + + 0 + + name + punctuation.separator.colon.cs + + + end + (?=\{) + patterns + + + include + #type + + + + + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #preprocessor + + + include + #comment + + + include + #attribute-section + + + include + #punctuation-comma + + + begin + [_[:alpha:]][_[:alnum:]]* + beginCaptures + + 0 + + name + entity.name.variable.enum-member.cs + + + end + (?=(,|\})) + patterns + + + include + #comment + + + include + #variable-initializer + + + + + + + include + #preprocessor + + + include + #comment + + + + interface-declaration + + begin + (?=\binterface\b) + end + (?<=\}) + patterns + + + begin + (?x) +(interface)\b\s+ +([_[:alpha:]][_[:alnum:]]*) + beginCaptures + + 1 + + name + keyword.other.interface.cs + + 2 + + name + entity.name.type.interface.cs + + + end + (?=\{) + patterns + + + include + #type-parameter-list + + + include + #base-types + + + include + #generic-constraints + + + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #interface-members + + + + + include + #preprocessor + + + include + #comment + + + + struct-declaration + + begin + (?=\bstruct\b) + end + (?<=\}) + patterns + + + begin + (?x) +(struct)\b\s+ +([_[:alpha:]][_[:alnum:]]*) + beginCaptures + + 1 + + name + keyword.other.struct.cs + + 2 + + name + entity.name.type.struct.cs + + + end + (?=\{) + patterns + + + include + #type-parameter-list + + + include + #base-types + + + include + #generic-constraints + + + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #class-or-struct-members + + + + + include + #preprocessor + + + include + #comment + + + + type-parameter-list + + begin + \< + beginCaptures + + 0 + + name + punctuation.definition.typeparameters.begin.cs + + + end + \> + endCaptures + + 0 + + name + punctuation.definition.typeparameters.end.cs + + + patterns + + + match + \b(in|out)\b + captures + + 1 + + name + storage.modifier.cs + + + + + match + \b([_[:alpha:]][_[:alnum:]]*)\b + captures + + 1 + + name + entity.name.type.type-parameter.cs + + + + + include + #comment + + + include + #punctuation-comma + + + include + #attribute-section + + + + base-types + + begin + : + beginCaptures + + 0 + + name + punctuation.separator.colon.cs + + + end + (?=\{|where) + patterns + + + include + #type + + + include + #punctuation-comma + + + include + #preprocessor + + + + generic-constraints + + begin + (where)\s+([_[:alpha:]][_[:alnum:]]*)\s*(:) + beginCaptures + + 1 + + name + keyword.other.where.cs + + 2 + + name + storage.type.cs + + 3 + + name + punctuation.separator.colon.cs + + + end + (?=\{|where|;) + patterns + + + name + keyword.other.class.cs + match + \bclass\b + + + name + keyword.other.struct.cs + match + \bstruct\b + + + match + (new)\s*(\()\s*(\)) + captures + + 1 + + name + keyword.other.new.cs + + 2 + + name + punctuation.parenthesis.open.cs + + 3 + + name + punctuation.parenthesis.close.cs + + + + + include + #type + + + include + #punctuation-comma + + + include + #generic-constraints + + + + field-declaration + + begin + (?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* # first field name +(?!=>|==)(?=,|;|=|$) + beginCaptures + + 1 + + patterns + + + include + #type + + + + 6 + + name + entity.name.variable.field.cs + + + end + (?=;) + patterns + + + name + entity.name.variable.field.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #punctuation-comma + + + include + #comment + + + include + #variable-initializer + + + include + #class-or-struct-members + + + + property-declaration + + begin + (?x) +(?!.*\b(?:class|interface|struct|enum|event)\b)\s* +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<property-name>\g<identifier>)\s* +(?=\{|=>|$) + beginCaptures + + 1 + + patterns + + + include + #type + + + + 7 + + patterns + + + include + #type + + + include + #punctuation-accessor + + + + 8 + + name + entity.name.variable.property.cs + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #property-accessors + + + include + #expression-body + + + include + #variable-initializer + + + include + #class-or-struct-members + + + + indexer-declaration + + begin + (?x) +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<indexer-name>this)\s* +(?=\[) + beginCaptures + + 1 + + patterns + + + include + #type + + + + 7 + + patterns + + + include + #type + + + include + #punctuation-accessor + + + + 8 + + name + keyword.other.this.cs + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #bracketed-parameter-list + + + include + #property-accessors + + + include + #expression-body + + + include + #variable-initializer + + + + event-declaration + + begin + (?x) +\b(event)\b\s* +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(?<event-names>\g<identifier>(?:\s*,\s*\g<identifier>)*)\s* +(?=\{|;|$) + beginCaptures + + 1 + + name + keyword.other.event.cs + + 2 + + patterns + + + include + #type + + + + 8 + + patterns + + + include + #type + + + include + #punctuation-accessor + + + + 9 + + patterns + + + name + entity.name.variable.event.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #punctuation-comma + + + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #event-accessors + + + include + #punctuation-comma + + + + property-accessors + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + name + storage.modifier.cs + match + \b(private|protected|internal)\b + + + name + keyword.other.get.cs + match + \b(get)\b + + + name + keyword.other.set.cs + match + \b(set)\b + + + include + #attribute-section + + + include + #block + + + include + #punctuation-semicolon + + + + event-accessors + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + name + keyword.other.add.cs + match + \b(add)\b + + + name + keyword.other.remove.cs + match + \b(remove)\b + + + include + #attribute-section + + + include + #block + + + include + #punctuation-semicolon + + + + method-declaration + + begin + (?x) +(?<return-type> + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + )\s+ +) +(?<interface-name>\g<type-name>\s*\.\s*)? +(\g<identifier>)\s* +(<([^<>]+)>)?\s* +(?=\() + beginCaptures + + 1 + + patterns + + + include + #type + + + + 7 + + patterns + + + include + #type + + + include + #punctuation-accessor + + + + 8 + + name + entity.name.function.cs + + 9 + + patterns + + + include + #type-parameter-list + + + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #parenthesized-parameter-list + + + include + #generic-constraints + + + include + #expression-body + + + include + #block + + + + constructor-declaration + + begin + (?=[_[:alpha:]][_[:alnum:]]*\s*\() + end + (?<=\})|(?=;) + patterns + + + match + \b([_[:alpha:]][_[:alnum:]]*)\b + captures + + 1 + + name + entity.name.function.cs + + + + + begin + (:) + beginCaptures + + 1 + + name + punctuation.separator.colon.cs + + + end + (?=\{|=>) + patterns + + + include + #constructor-initializer + + + + + include + #parenthesized-parameter-list + + + include + #preprocessor + + + include + #comment + + + include + #expression-body + + + include + #block + + + + constructor-initializer + + begin + \b(?:(base)|(this))\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.other.base.cs + + 2 + + name + keyword.other.this.cs + + + end + (?<=\)) + patterns + + + include + #argument-list + + + + destructor-declaration + + begin + (~)([_[:alpha:]][_[:alnum:]]*)\s*(?=\() + beginCaptures + + 1 + + name + punctuation.tilde.cs + + 2 + + name + entity.name.function.cs + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #parenthesized-parameter-list + + + include + #expression-body + + + include + #block + + + + operator-declaration + + begin + (?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?<operator-keyword>(?:\b(?:operator)))\s* +(?<operator>(?:\+|-|\*|/|%|&|\||\^|\<\<|\>\>|==|!=|\>|\<|\>=|\<=|!|~|\+\+|--|true|false))\s* +(?=\() + beginCaptures + + 1 + + patterns + + + include + #type + + + + 6 + + name + keyword.other.operator-decl.cs + + 7 + + name + entity.name.function.cs + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #parenthesized-parameter-list + + + include + #expression-body + + + include + #block + + + + conversion-operator-declaration + + begin + (?x) +(?<explicit-or-implicit-keyword>(?:\b(?:explicit|implicit)))\s* +(?<operator-keyword>(?:\b(?:operator)))\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\() + beginCaptures + + 1 + + patterns + + + match + \b(explicit)\b + captures + + 1 + + name + keyword.other.explicit.cs + + + + + match + \b(implicit)\b + captures + + 1 + + name + keyword.other.implicit.cs + + + + + + 2 + + name + keyword.other.operator-decl.cs + + 3 + + patterns + + + include + #type + + + + + end + (?<=\})|(?=;) + patterns + + + include + #comment + + + include + #parenthesized-parameter-list + + + include + #expression-body + + + include + #block + + + + block + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #statement + + + + variable-initializer + + begin + (?<!=|!)(=)(?!=|>) + beginCaptures + + 1 + + name + keyword.operator.assignment.cs + + + end + (?=[,\)\];}]) + patterns + + + include + #expression + + + + expression-body + + begin + => + beginCaptures + + 0 + + name + keyword.operator.arrow.cs + + + end + (?=[,\);}]) + patterns + + + include + #expression + + + + goto-statement + + begin + (?<!\.)\b(goto)\b + beginCaptures + + 1 + + name + keyword.control.goto.cs + + + end + (?=;) + patterns + + + begin + \b(case)\b + beginCaptures + + 1 + + name + keyword.control.case.cs + + + end + (?=;) + patterns + + + include + #expression + + + + + match + \b(default)\b + captures + + 1 + + name + keyword.control.default.cs + + + + + name + entity.name.label.cs + match + [_[:alpha:]][_[:alnum:]]* + + + + return-statement + + begin + (?<!\.)\b(return)\b + beginCaptures + + 1 + + name + keyword.control.flow.return.cs + + + end + (?=;) + patterns + + + include + #expression + + + + break-or-continue-statement + + match + (?<!\.)\b(?:(break)|(continue))\b + captures + + 1 + + name + keyword.control.flow.break.cs + + 2 + + name + keyword.control.flow.continue.cs + + + + throw-statement + + begin + (?<!\.)\b(throw)\b + beginCaptures + + 1 + + name + keyword.control.flow.throw.cs + + + end + (?=;) + patterns + + + include + #expression + + + + yield-statement + + patterns + + + include + #yield-return-statement + + + include + #yield-break-statement + + + + yield-return-statement + + begin + (?<!\.)\b(yield)\b\s*\b(return)\b + beginCaptures + + 1 + + name + keyword.control.flow.yield.cs + + 2 + + name + keyword.control.flow.return.cs + + + end + (?=;) + patterns + + + include + #expression + + + + yield-break-statement + + match + (?<!\.)\b(yield)\b\s*\b(break)\b + captures + + 1 + + name + keyword.control.flow.yield.cs + + 2 + + name + keyword.control.flow.break.cs + + + + if-statement + + begin + (?<!\.)\b(if)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.control.conditional.if.cs + + + end + (?<=\})|(?=;) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + + include + #statement + + + + else-part + + begin + (?<!\.)\b(else)\b + beginCaptures + + 1 + + name + keyword.control.conditional.else.cs + + + end + (?<=\})|(?=;) + patterns + + + include + #statement + + + + switch-statement + + begin + (?<!\.)\b(switch)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.control.switch.cs + + + end + (?<=\}) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #switch-label + + + include + #statement + + + + + + switch-label + + patterns + + + begin + (?<!\.)\b(case)\b\s+ + beginCaptures + + 1 + + name + keyword.control.case.cs + + + end + : + endCaptures + + 0 + + name + punctuation.separator.colon.cs + + + patterns + + + include + #expression + + + + + match + (?<!\.)\b(default)\b\s*(:) + captures + + 1 + + name + keyword.control.default.cs + + 2 + + name + punctuation.separator.colon.cs + + + + + + do-statement + + begin + (?<!\.)\b(do)\b + beginCaptures + + 1 + + name + keyword.control.loop.do.cs + + + end + (?=;|}) + patterns + + + include + #statement + + + + while-statement + + begin + (?<!\.)\b(while)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.control.loop.while.cs + + + end + (?<=\})|(?=;) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + + include + #statement + + + + for-statement + + begin + (?<!\.)\b(for)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.control.loop.for.cs + + + end + (?<=\})|(?=;) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #local-variable-declaration + + + include + #expression + + + include + #punctuation-comma + + + include + #punctuation-semicolon + + + + + include + #statement + + + + foreach-statement + + begin + (?<!\.)\b(foreach)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.control.loop.foreach.cs + + + end + (?<=\})|(?=;) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + match + (?x) +(?: + (\bvar\b)| + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + ) +)\s+ +(\g<identifier>)\s+ +\b(in)\b + captures + + 1 + + name + keyword.other.var.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.local.cs + + 8 + + name + keyword.control.loop.in.cs + + + + + match + (?x) # match foreach (var (x, y) in ...) +(?:\b(var)\b\s*)? +(?<tuple>\((?:[^\(\)]|\g<tuple>)+\))\s+ +\b(in)\b + captures + + 1 + + name + keyword.other.var.cs + + 2 + + patterns + + + include + #tuple-declaration-deconstruction-element-list + + + + 3 + + name + keyword.control.loop.in.cs + + + + + include + #expression + + + + + include + #statement + + + + try-statement + + patterns + + + include + #try-block + + + include + #catch-clause + + + include + #finally-clause + + + + try-block + + begin + (?<!\.)\b(try)\b + beginCaptures + + 1 + + name + keyword.control.try.cs + + + end + (?<=\}) + patterns + + + include + #block + + + + finally-clause + + begin + (?<!\.)\b(finally)\b + beginCaptures + + 1 + + name + keyword.control.try.finally.cs + + + end + (?<=\}) + patterns + + + include + #block + + + + catch-clause + + begin + (?<!\.)\b(catch)\b + beginCaptures + + 1 + + name + keyword.control.try.catch.cs + + + end + (?<=\}) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + match + (?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?:\b(\g<identifier>)\b)? + captures + + 1 + + patterns + + + include + #type + + + + 6 + + name + entity.name.variable.local.cs + + + + + + + include + #when-clause + + + include + #block + + + + when-clause + + begin + (?<!\.)\b(when)\b\s*(\() + beginCaptures + + 1 + + name + keyword.control.try.when.cs + + 2 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + checked-unchecked-statement + + begin + (?<!\.)\b(?:(checked)|(unchecked))\b\s*(?!\() + beginCaptures + + 1 + + name + keyword.other.checked.cs + + 2 + + name + keyword.other.unchecked.cs + + + end + (?<=\}) + patterns + + + include + #block + + + + lock-statement + + begin + (?<!\.)\b(lock)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.other.lock.cs + + + end + (?<=\})|(?=;) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + + include + #statement + + + + using-statement + + begin + (?<!\.)\b(using)\b\s*(?=\() + beginCaptures + + 1 + + name + keyword.other.using.cs + + + end + (?=\;|}) + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #local-variable-declaration + + + include + #expression + + + + + include + #statement + + + + labeled-statement + + match + ([_[:alpha:]][_[:alnum:]]*)\s*(:) + captures + + 1 + + name + entity.name.label.cs + + 2 + + name + punctuation.separator.colon.cs + + + + local-declaration + + patterns + + + include + #local-constant-declaration + + + include + #local-variable-declaration + + + include + #local-tuple-var-deconstruction + + + + local-variable-declaration + + begin + (?x) +(?: + (\bvar\b)| + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + ) +)\s+ +(\g<identifier>)\s* +(?=,|;|=|\)) + beginCaptures + + 1 + + name + keyword.other.var.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.local.cs + + + end + (?=;|\)) + patterns + + + name + entity.name.variable.local.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #punctuation-comma + + + include + #comment + + + include + #variable-initializer + + + + local-constant-declaration + + begin + (?x) +(?<const-keyword>\b(?:const)\b)\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s+ +(\g<identifier>)\s* +(?=,|;|=) + beginCaptures + + 1 + + name + storage.modifier.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.local.cs + + + end + (?=;) + patterns + + + name + entity.name.variable.local.cs + match + [_[:alpha:]][_[:alnum:]]* + + + include + #punctuation-comma + + + include + #comment + + + include + #variable-initializer + + + + local-tuple-var-deconstruction + + begin + (?x) # e.g. var (x, y) = GetPoint(); +(?:\b(var)\b\s*) +(?<tuple>\((?:[^\(\)]|\g<tuple>)+\))\s* +(?=;|=|\)) + beginCaptures + + 1 + + name + keyword.other.var.cs + + 2 + + patterns + + + include + #tuple-declaration-deconstruction-element-list + + + + + end + (?=;|\)) + patterns + + + include + #comment + + + include + #variable-initializer + + + + tuple-deconstruction-assignment + + match + (?x) +(?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\))\s* +(?!=>|==)(?==) + captures + + 1 + + patterns + + + include + #tuple-deconstruction-element-list + + + + + + tuple-declaration-deconstruction-element-list + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #comment + + + include + #tuple-declaration-deconstruction-element-list + + + include + #declaration-expression + + + include + #punctuation-comma + + + match + (?x) # e.g. x +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(?=[,)]) + captures + + 1 + + name + entity.name.variable.tuple-element.cs + + + + + + tuple-deconstruction-element-list + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #comment + + + include + #tuple-deconstruction-element-list + + + include + #declaration-expression + + + include + #punctuation-comma + + + match + (?x) # e.g. x +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(?=[,)]) + captures + + 1 + + name + variable.other.readwrite.cs + + + + + + declaration-expression + + match + (?x) # e.g. int x OR var x +(?: + \b(var)\b| + (?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) + ) +)\s+ +\b(\g<identifier>)\b\s* +(?=[,)]) + captures + + 1 + + name + keyword.other.var.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.tuple-element.cs + + + + checked-unchecked-expression + + begin + (?<!\.)\b(?:(checked)|(unchecked))\b\s*(\() + beginCaptures + + 1 + + name + keyword.other.checked.cs + + 2 + + name + keyword.other.unchecked.cs + + 3 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + typeof-or-default-expression + + begin + (?<!\.)\b(?:(typeof)|(default))\b\s*(\() + beginCaptures + + 1 + + name + keyword.other.typeof.cs + + 2 + + name + keyword.other.default.cs + + 3 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #type + + + + nameof-expression + + begin + (?<!\.)\b(nameof)\b\s*(\() + beginCaptures + + 1 + + name + keyword.other.nameof.cs + + 2 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + interpolated-string + + name + string.quoted.double.cs + begin + \$" + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + (")|((?:[^\\\n])$) + endCaptures + + 1 + + name + punctuation.definition.string.end.cs + + 2 + + name + invalid.illegal.newline.cs + + + patterns + + + include + #string-character-escape + + + include + #interpolation + + + + verbatim-interpolated-string + + name + string.quoted.double.cs + begin + \$@" + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + "(?=[^"]) + endCaptures + + 0 + + name + punctuation.definition.string.end.cs + + + patterns + + + include + #verbatim-string-character-escape + + + include + #interpolation + + + + interpolation + + name + meta.interpolation.cs + begin + (?<=[^\{])((?:\{\{)*)(\{)(?=[^\{]) + beginCaptures + + 1 + + name + string.quoted.double.cs + + 2 + + name + punctuation.definition.interpolation.begin.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.definition.interpolation.end.cs + + + patterns + + + include + #expression + + + + literal + + patterns + + + include + #boolean-literal + + + include + #null-literal + + + include + #numeric-literal + + + include + #char-literal + + + include + #string-literal + + + include + #verbatim-string-literal + + + include + #tuple-literal + + + + boolean-literal + + patterns + + + name + constant.language.boolean.true.cs + match + (?<!\.)\btrue\b + + + name + constant.language.boolean.false.cs + match + (?<!\.)\bfalse\b + + + + null-literal + + name + constant.language.null.cs + match + (?<!\.)\bnull\b + + numeric-literal + + patterns + + + name + constant.numeric.hex.cs + match + \b0(x|X)[0-9a-fA-F_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b + + + name + constant.numeric.binary.cs + match + \b0(b|B)[01_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b + + + name + constant.numeric.decimal.cs + match + \b([0-9_]+)?\.[0-9_]+((e|E)[0-9]+)?(F|f|D|d|M|m)?\b + + + name + constant.numeric.decimal.cs + match + \b[0-9_]+(e|E)[0-9_]+(F|f|D|d|M|m)?\b + + + name + constant.numeric.decimal.cs + match + \b[0-9_]+(F|f|D|d|M|m)\b + + + name + constant.numeric.decimal.cs + match + \b[0-9_]+(U|u|L|l|UL|Ul|uL|ul|LU|Lu|lU|lu)?\b + + + + char-literal + + name + string.quoted.single.cs + begin + ' + beginCaptures + + 0 + + name + punctuation.definition.char.begin.cs + + + end + (\')|((?:[^\\\n])$) + endCaptures + + 1 + + name + punctuation.definition.char.end.cs + + 2 + + name + invalid.illegal.newline.cs + + + patterns + + + include + #string-character-escape + + + + string-literal + + name + string.quoted.double.cs + begin + (?<!@)" + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + (")|((?:[^\\\n])$) + endCaptures + + 1 + + name + punctuation.definition.string.end.cs + + 2 + + name + invalid.illegal.newline.cs + + + patterns + + + include + #string-character-escape + + + + string-character-escape + + name + constant.character.escape.cs + match + \\. + + verbatim-string-literal + + name + string.quoted.double.cs + begin + @" + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + "(?=[^"]) + endCaptures + + 0 + + name + punctuation.definition.string.end.cs + + + patterns + + + include + #verbatim-string-character-escape + + + + verbatim-string-character-escape + + name + constant.character.escape.cs + match + "" + + tuple-literal + + begin + (\()(?=.*[:,]) + beginCaptures + + 1 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #comment + + + include + #tuple-literal-element + + + include + #punctuation-comma + + + + tuple-literal-element + + begin + (?x) +(?:([_[:alpha:]][_[:alnum:]]*)\s*(:)\s*)? +(?![,)]) + beginCaptures + + 0 + + name + entity.name.variable.tuple-element.cs + + 1 + + name + punctuation.separator.colon.cs + + + end + (?=[,)]) + patterns + + + include + #expression + + + + expression-operators + + patterns + + + name + keyword.operator.assignment.compound.cs + match + \*=|/=|%=|\+=|-= + + + name + keyword.operator.assignment.compound.bitwise.cs + match + \&=|\^=|<<=|>>=|\|= + + + name + keyword.operator.bitwise.shift.cs + match + <<|>> + + + name + keyword.operator.comparison.cs + match + ==|!= + + + name + keyword.operator.relational.cs + match + <=|>=|<|> + + + name + keyword.operator.logical.cs + match + \!|&&|\|\| + + + name + keyword.operator.bitwise.cs + match + \&|~|\^|\| + + + name + keyword.operator.assignment.cs + match + \= + + + name + keyword.operator.decrement.cs + match + -- + + + name + keyword.operator.increment.cs + match + \+\+ + + + name + keyword.operator.arithmetic.cs + match + %|\*|/|-|\+ + + + name + keyword.operator.null-coalescing.cs + match + \?\? + + + + conditional-operator + + begin + (?<!\?)\?(?!\?|\.|\[) + beginCaptures + + 0 + + name + keyword.operator.conditional.question-mark.cs + + + end + : + endCaptures + + 0 + + name + keyword.operator.conditional.colon.cs + + + patterns + + + include + #expression + + + + await-expression + + name + keyword.other.await.cs + match + (?!\.)\b(await)\b + + parenthesized-expression + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #expression + + + + initializer-expression + + begin + \{ + beginCaptures + + 0 + + name + punctuation.curlybrace.open.cs + + + end + \} + endCaptures + + 0 + + name + punctuation.curlybrace.close.cs + + + patterns + + + include + #expression + + + include + #punctuation-comma + + + + identifier + + name + variable.other.readwrite.cs + match + [_[:alpha:]][_[:alnum:]]* + + cast-expression + + match + (?x) +(\()\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(\))(?=\s*[_[:alnum:]\(]) + captures + + 1 + + name + punctuation.parenthesis.open.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + punctuation.parenthesis.close.cs + + + + as-expression + + match + (?x) +(?<!\.)\b(as)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? + captures + + 1 + + name + keyword.other.as.cs + + 2 + + patterns + + + include + #type + + + + + + is-expression + + match + (?x) +(?<!\.)\b(is)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? + captures + + 1 + + name + keyword.other.is.cs + + 2 + + patterns + + + include + #type + + + + + + this-or-base-expression + + match + \b(?:(base)|(this))\b + captures + + 1 + + name + keyword.other.base.cs + + 2 + + name + keyword.other.this.cs + + + + invocation-expression + + begin + (?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(?:(\.)\s*)? # preceding dot? +([_[:alpha:]][_[:alnum:]]*)\s* # method name +(?<type-args>\s*<([^<>]|\g<type-args>)+>\s*)?\s* # type arguments +(?=\() # open paren of argument list + beginCaptures + + 1 + + name + keyword.operator.null-conditional.cs + + 2 + + name + punctuation.accessor.cs + + 3 + + name + entity.name.function.cs + + 4 + + patterns + + + include + #type-arguments + + + + + end + (?<=\)) + patterns + + + include + #argument-list + + + + element-access-expression + + begin + (?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(?:(\.)\s*)? # preceding dot? +([_[:alpha:]][_[:alnum:]]*)\s* # property name +(?:(\?)\s*)? # null-conditional operator? +(?=\[) # open bracket of argument list + beginCaptures + + 1 + + name + keyword.operator.null-conditional.cs + + 2 + + name + punctuation.accessor.cs + + 3 + + name + variable.other.object.property.cs + + 4 + + name + keyword.operator.null-conditional.cs + + + end + (?<=\]) + patterns + + + include + #bracketed-argument-list + + + + member-access-expression + + patterns + + + match + (?x) +(?:(\?)\s*)? # preceding null-conditional operator? +(\.)\s* # preceding dot +([_[:alpha:]][_[:alnum:]]*)\s* # property name +(?![_[:alnum:]]|\(|(\?)?\[|<) # next character is not alpha-numeric, nor a (, [, or <. Also, test for ?[ + captures + + 1 + + name + keyword.operator.null-conditional.cs + + 2 + + name + punctuation.accessor.cs + + 3 + + name + variable.other.object.property.cs + + + + + match + (?x) +(\.)?\s* +([_[:alpha:]][_[:alnum:]]*) +(?<type-params>\s*<([^<>]|\g<type-params>)+>\s*) +(?= + (\s*\?)? + \s*\.\s*[_[:alpha:]][_[:alnum:]]* +) + captures + + 1 + + name + punctuation.accessor.cs + + 2 + + name + variable.other.object.cs + + 3 + + patterns + + + include + #type-arguments + + + + + + + match + (?x) +([_[:alpha:]][_[:alnum:]]*) +(?= + (\s*\?)? + \s*\.\s*[_[:alpha:]][_[:alnum:]]* +) + captures + + 1 + + name + variable.other.object.cs + + + + + + object-creation-expression + + patterns + + + include + #object-creation-expression-with-parameters + + + include + #object-creation-expression-with-no-parameters + + + + object-creation-expression-with-parameters + + begin + (?x) +(new)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\() + beginCaptures + + 1 + + name + keyword.other.new.cs + + 2 + + patterns + + + include + #type + + + + + end + (?<=\)) + patterns + + + include + #argument-list + + + + object-creation-expression-with-no-parameters + + match + (?x) +(new)\s+ +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)\s* +(?=\{|$) + captures + + 1 + + name + keyword.other.new.cs + + 2 + + patterns + + + include + #type + + + + + + array-creation-expression + + begin + (?x) +\b(new)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)?\s* +(?=\[) + beginCaptures + + 1 + + name + keyword.other.new.cs + + 2 + + patterns + + + include + #type + + + + + end + (?<=\]) + patterns + + + include + #bracketed-argument-list + + + + anonymous-object-creation-expression + + begin + \b(new)\b\s*(?=\{|$) + beginCaptures + + 1 + + name + keyword.other.new.cs + + + end + (?=;|\)) + patterns + + + include + #initializer-expression + + + + bracketed-parameter-list + + begin + (?=(\[)) + beginCaptures + + 1 + + name + punctuation.squarebracket.open.cs + + + end + (?=(\])) + endCaptures + + 1 + + name + punctuation.squarebracket.close.cs + + + patterns + + + begin + (?<=\[) + end + (?=\]) + patterns + + + include + #comment + + + include + #attribute-section + + + name + storage.modifier.cs + match + \b(ref|params|out)\b + + + match + \s+([_[:alpha:]][_[:alnum:]]*)\s*(?=[=,\]]) + captures + + 1 + + name + entity.name.variable.parameter.cs + + + + + include + #variable-initializer + + + include + #type + + + include + #punctuation-comma + + + + + + parenthesized-parameter-list + + begin + (\() + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + (\)) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #comment + + + include + #attribute-section + + + name + storage.modifier.cs + match + \b(ref|params|out|this)\b + + + match + \b([_[:alpha:]][_[:alnum:]]*)\s*(?=[=,)]) + captures + + 1 + + name + entity.name.variable.parameter.cs + + + + + include + #variable-initializer + + + include + #type + + + include + #punctuation-comma + + + + argument-list + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #named-argument + + + include + #argument + + + include + #punctuation-comma + + + + bracketed-argument-list + + begin + \[ + beginCaptures + + 0 + + name + punctuation.squarebracket.open.cs + + + end + \] + endCaptures + + 0 + + name + punctuation.squarebracket.close.cs + + + patterns + + + include + #named-argument + + + include + #argument + + + include + #punctuation-comma + + + + named-argument + + begin + ([_[:alpha:]][_[:alnum:]]*)\s*(:) + beginCaptures + + 1 + + name + entity.name.variable.parameter.cs + + 2 + + name + punctuation.separator.colon.cs + + + end + (?=(,|\)|\])) + patterns + + + include + #expression + + + + argument + + patterns + + + name + storage.modifier.cs + match + \b(ref|out)\b + + + include + #expression + + + + query-expression + + begin + (?x) +\b(from)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +\b(in)\b\s* + beginCaptures + + 1 + + name + keyword.query.from.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.range-variable.cs + + 8 + + name + keyword.query.in.cs + + + end + (?=;|\)) + patterns + + + include + #query-body + + + include + #expression + + + + query-body + + patterns + + + include + #let-clause + + + include + #where-clause + + + include + #join-clause + + + include + #orderby-clause + + + include + #select-clause + + + include + #group-clause + + + + let-clause + + begin + (?x) +\b(let)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(=)\s* + beginCaptures + + 1 + + name + keyword.query.let.cs + + 2 + + name + entity.name.variable.range-variable.cs + + 3 + + name + keyword.operator.assignment.cs + + + end + (?=;|\)) + patterns + + + include + #query-body + + + include + #expression + + + + where-clause + + begin + (?x) +\b(where)\b\s* + beginCaptures + + 1 + + name + keyword.query.where.cs + + + end + (?=;|\)) + patterns + + + include + #query-body + + + include + #expression + + + + join-clause + + begin + (?x) +\b(join)\b\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +\b(in)\b\s* + beginCaptures + + 1 + + name + keyword.query.join.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.range-variable.cs + + 8 + + name + keyword.query.in.cs + + + end + (?=;|\)) + patterns + + + include + #join-on + + + include + #join-equals + + + include + #join-into + + + include + #query-body + + + include + #expression + + + + join-on + + match + \b(on)\b\s* + captures + + 1 + + name + keyword.query.on.cs + + + + join-equals + + match + \b(equals)\b\s* + captures + + 1 + + name + keyword.query.equals.cs + + + + join-into + + match + (?x) +\b(into)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s* + captures + + 1 + + name + keyword.query.into.cs + + 2 + + name + entity.name.variable.range-variable.cs + + + + orderby-clause + + begin + \b(orderby)\b\s* + beginCaptures + + 1 + + name + keyword.query.orderby.cs + + + end + (?=;|\)) + patterns + + + include + #ordering-direction + + + include + #query-body + + + include + #expression + + + include + #punctuation-comma + + + + ordering-direction + + match + \b(?:(ascending)|(descending))\b + captures + + 1 + + name + keyword.query.ascending.cs + + 2 + + name + keyword.query.descending.cs + + + + select-clause + + begin + \b(select)\b\s* + beginCaptures + + 1 + + name + keyword.query.select.cs + + + end + (?=;|\)) + patterns + + + include + #query-body + + + include + #expression + + + + group-clause + + begin + \b(group)\b\s* + beginCaptures + + 1 + + name + keyword.query.group.cs + + + end + (?=;|\)) + patterns + + + include + #group-by + + + include + #group-into + + + include + #query-body + + + include + #expression + + + + group-by + + match + \b(by)\b\s* + captures + + 1 + + name + keyword.query.by.cs + + + + group-into + + match + (?x) +\b(into)\b\s* +\b([_[:alpha:]][_[:alnum:]]*)\b\s* + captures + + 1 + + name + keyword.query.into.cs + + 2 + + name + entity.name.variable.range-variable.cs + + + + anonymous-method-expression + + patterns + + + begin + (?x) +(?:\b(async)\b\s*)? +\b([_[:alpha:]][_[:alnum:]]*)\b\s* +(=>) + beginCaptures + + 1 + + name + storage.modifier.cs + + 2 + + name + entity.name.variable.parameter.cs + + 3 + + name + keyword.operator.arrow.cs + + + end + (?=\)|;|}) + patterns + + + include + #block + + + include + #expression + + + + + begin + (?x) +(?:\b(async)\b\s*)? +(\(.*\))\s* +(=>) + beginCaptures + + 1 + + name + storage.modifier.cs + + 2 + + patterns + + + include + #lambda-parameter-list + + + + 3 + + name + keyword.operator.arrow.cs + + + end + (?=\)|;|}) + patterns + + + include + #block + + + include + #expression + + + + + begin + (?x) +(?:\b(async)\b\s*)? +(?:\b(delegate)\b\s*) + beginCaptures + + 1 + + name + storage.modifier.cs + + 2 + + name + keyword.other.delegate.cs + + + end + (?=\)|;|}) + patterns + + + include + #parenthesized-parameter-list + + + include + #block + + + include + #expression + + + + + + lambda-parameter-list + + begin + (\() + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + (\)) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #comment + + + include + #attribute-section + + + include + #lambda-parameter + + + include + #punctuation-comma + + + + lambda-parameter + + match + (?x) +(ref|out)?\s* +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +)? +\b(\g<identifier>)\b\s* +(?=[,)]) + captures + + 1 + + name + storage.modifier.cs + + 2 + + patterns + + + include + #type + + + + 7 + + name + entity.name.variable.parameter.cs + + + + type + + name + meta.type.cs + patterns + + + include + #comment + + + include + #tuple-type + + + include + #type-builtin + + + include + #type-name + + + include + #type-arguments + + + include + #type-array-suffix + + + include + #type-nullable-suffix + + + + tuple-type + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #tuple-element + + + include + #punctuation-comma + + + + tuple-element + + match + (?x) +(?<type-name> + (?: + (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\s*\:\:\s*)? # alias-qualification + (?<name-and-type-args> # identifier + type arguments (if any) + \g<identifier>\s* + (?<type-args>\s*<(?:[^<>]|\g<type-args>)+>\s*)? + ) + (?:\s*\.\s*\g<name-and-type-args>)* # Are there any more names being dotted into? + (?:\s*\*\s*)* # pointer suffix? + (?:\s*\?\s*)? # nullable suffix? + (?:\s*\[(?:\s*,\s*)*\]\s*)* # array suffix? + )| + (?<tuple>\s*\((?:[^\(\)]|\g<tuple>)+\)) +) +(?:\b(?<tuple-name>\g<identifier>)\b)? + captures + + 1 + + patterns + + + include + #type + + + + 6 + + name + entity.name.variable.tuple-element.cs + + + + type-builtin + + match + \b(bool|byte|char|decimal|double|float|int|long|object|sbyte|short|string|uint|ulong|ushort|void)\b + captures + + 1 + + name + keyword.type.cs + + + + type-name + + patterns + + + match + ([_[:alpha:]][_[:alnum:]]*)\s*(\:\:) + captures + + 1 + + name + entity.name.type.alias.cs + + 2 + + name + punctuation.separator.coloncolon.cs + + + + + match + ([_[:alpha:]][_[:alnum:]]*)\s*(\.) + captures + + 1 + + name + storage.type.cs + + 2 + + name + punctuation.accessor.cs + + + + + match + (\.)\s*([_[:alpha:]][_[:alnum:]]*) + captures + + 1 + + name + punctuation.accessor.cs + + 2 + + name + storage.type.cs + + + + + name + storage.type.cs + match + [_[:alpha:]][_[:alnum:]]* + + + + type-arguments + + begin + < + beginCaptures + + 0 + + name + punctuation.definition.typeparameters.begin.cs + + + end + > + endCaptures + + 0 + + name + punctuation.definition.typeparameters.end.cs + + + patterns + + + include + #comment + + + include + #type + + + include + #punctuation-comma + + + + type-array-suffix + + begin + \[ + beginCaptures + + 0 + + name + punctuation.squarebracket.open.cs + + + end + \] + endCaptures + + 0 + + name + punctuation.squarebracket.close.cs + + + patterns + + + include + #punctuation-comma + + + + type-nullable-suffix + + match + \? + captures + + 0 + + name + punctuation.separator.question-mark.cs + + + + operator-assignment + + name + keyword.operator.assignment.cs + match + (?<!=|!)(=)(?!=) + + punctuation-comma + + name + punctuation.separator.comma.cs + match + , + + punctuation-semicolon + + name + punctuation.terminator.statement.cs + match + ; + + punctuation-accessor + + name + punctuation.accessor.cs + match + \. + + preprocessor + + name + meta.preprocessor.cs + begin + ^\s*(\#)\s* + beginCaptures + + 1 + + name + punctuation.separator.hash.cs + + + end + (?<=$) + patterns + + + include + #comment + + + include + #preprocessor-define-or-undef + + + include + #preprocessor-if-or-elif + + + include + #preprocessor-else-or-endif + + + include + #preprocessor-warning-or-error + + + include + #preprocessor-region + + + include + #preprocessor-endregion + + + include + #preprocessor-line + + + include + #preprocessor-pragma-warning + + + include + #preprocessor-pragma-checksum + + + + preprocessor-define-or-undef + + match + \b(?:(define)|(undef))\b\s*\b([_[:alpha:]][_[:alnum:]]*)\b + captures + + 1 + + name + keyword.preprocessor.define.cs + + 2 + + name + keyword.preprocessor.undef.cs + + 3 + + name + entity.name.variable.preprocessor.symbol.cs + + + + preprocessor-if-or-elif + + begin + \b(?:(if)|(elif))\b + beginCaptures + + 1 + + name + keyword.preprocessor.if.cs + + 2 + + name + keyword.preprocessor.elif.cs + + + end + (?=$) + patterns + + + include + #comment + + + include + #preprocessor-expression + + + + preprocessor-else-or-endif + + match + \b(?:(else)|(endif))\b + captures + + 1 + + name + keyword.preprocessor.else.cs + + 2 + + name + keyword.preprocessor.endif.cs + + + + preprocessor-warning-or-error + + match + \b(?:(warning)|(error))\b\s*(.*)(?=$) + captures + + 1 + + name + keyword.preprocessor.warning.cs + + 2 + + name + keyword.preprocessor.error.cs + + 3 + + name + string.unquoted.preprocessor.message.cs + + + + preprocessor-region + + match + \b(region)\b\s*(.*)(?=$) + captures + + 1 + + name + keyword.preprocessor.region.cs + + 2 + + name + string.unquoted.preprocessor.message.cs + + + + preprocessor-endregion + + match + \b(endregion)\b + captures + + 1 + + name + keyword.preprocessor.endregion.cs + + + + preprocessor-line + + begin + \b(line)\b + beginCaptures + + 1 + + name + keyword.preprocessor.line.cs + + + end + (?=$) + patterns + + + match + \b(?:(default|hidden)) + captures + + 1 + + name + keyword.preprocessor.default.cs + + 2 + + name + keyword.preprocessor.hidden.cs + + + + + match + [0-9]+ + captures + + 0 + + name + constant.numeric.decimal.cs + + + + + match + \"[^"]*\" + captures + + 0 + + name + string.quoted.double.cs + + + + + + preprocessor-pragma-warning + + match + \b(pragma)\b\s*\b(warning)\b\s*\b(?:(disable)|(restore))\b(\s*[0-9]+(?:\s*,\s*[0-9]+)?)? + captures + + 1 + + name + keyword.preprocessor.pragma.cs + + 2 + + name + keyword.preprocessor.warning.cs + + 3 + + name + keyword.preprocessor.disable.cs + + 4 + + name + keyword.preprocessor.restore.cs + + 5 + + patterns + + + match + [0-9]+ + captures + + 0 + + name + constant.numeric.decimal.cs + + + + + include + #punctuation-comma + + + + + + preprocessor-pragma-checksum + + match + \b(pragma)\b\s*\b(checksum)\b\s*(\"[^"]*\")\s*(\"[^"]*\")\s*(\"[^"]*\") + captures + + 1 + + name + keyword.preprocessor.pragma.cs + + 2 + + name + keyword.preprocessor.checksum.cs + + 3 + + name + string.quoted.double.cs + + 4 + + name + string.quoted.double.cs + + 5 + + name + string.quoted.double.cs + + + + preprocessor-expression + + patterns + + + begin + \( + beginCaptures + + 0 + + name + punctuation.parenthesis.open.cs + + + end + \) + endCaptures + + 0 + + name + punctuation.parenthesis.close.cs + + + patterns + + + include + #preprocessor-expression + + + + + match + \b(?:(true)|(false)|([_[:alpha:]][_[:alnum:]]*))\b + captures + + 1 + + name + constant.language.boolean.true.cs + + 2 + + name + constant.language.boolean.false.cs + + 3 + + name + entity.name.variable.preprocessor.symbol.cs + + + + + match + (==|!=)|(\!|&&|\|\|) + captures + + 1 + + name + keyword.operator.comparison.cs + + 2 + + name + keyword.operator.logical.cs + + + + + + comment + + patterns + + + name + comment.block.cs + begin + /\* + beginCaptures + + 0 + + name + punctuation.definition.comment.cs + + + end + \*/ + endCaptures + + 0 + + name + punctuation.definition.comment.cs + + + + + begin + (^\s+)?(?=//) + beginCaptures + + 1 + + name + punctuation.whitespace.comment.leading.cs + + + end + (?=$) + patterns + + + name + comment.block.documentation.cs + begin + (?<!/)///(?!/) + beginCaptures + + 0 + + name + punctuation.definition.comment.cs + + + end + (?=$) + patterns + + + include + #xml-doc-comment + + + + + name + comment.line.double-slash.cs + begin + (?<!/)//(?!/) + beginCaptures + + 0 + + name + punctuation.definition.comment.cs + + + end + (?=$) + + + + + + xml-doc-comment + + patterns + + + include + #xml-comment + + + include + #xml-character-entity + + + include + #xml-cdata + + + include + #xml-tag + + + + xml-tag + + name + meta.tag.cs + begin + (?x) +(</?) +( + (?: + ([-_[:alnum:]]+) + (:) + )? + ([-_[:alnum:]]+) +) + beginCaptures + + 1 + + name + punctuation.definition.tag.cs + + 2 + + name + entity.name.tag.cs + + 3 + + name + entity.name.tag.namespace.cs + + 4 + + name + punctuation.separator.colon.cs + + 5 + + name + entity.name.tag.localname.cs + + + end + (/?>) + endCaptures + + 1 + + name + punctuation.definition.tag.cs + + + patterns + + + include + #xml-attribute + + + + xml-attribute + + patterns + + + match + (?x) +(?:^|\s+) +( + (?: + ([-_[:alnum:]]+) + (:) + )? + ([-_[:alnum:]]+) +) +(=) + captures + + 1 + + name + entity.other.attribute-name.cs + + 2 + + name + entity.other.attribute-name.namespace.cs + + 3 + + name + punctuation.separator.colon.cs + + 4 + + name + entity.other.attribute-name.localname.cs + + 5 + + name + punctuation.separator.equals.cs + + + + + include + #xml-string + + + + xml-cdata + + name + string.unquoted.cdata.cs + begin + <!\[CDATA\[ + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + \]\]> + endCaptures + + 0 + + name + punctuation.definition.string.end.cs + + + + xml-string + + patterns + + + name + string.quoted.single.cs + begin + \' + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + \' + endCaptures + + 0 + + name + punctuation.definition.string.end.cs + + + patterns + + + include + #xml-character-entity + + + + + name + string.quoted.double.cs + begin + \" + beginCaptures + + 0 + + name + punctuation.definition.string.begin.cs + + + end + \" + endCaptures + + 0 + + name + punctuation.definition.string.end.cs + + + patterns + + + include + #xml-character-entity + + + + + + xml-character-entity + + patterns + + + name + constant.character.entity.cs + match + (?x) +(&) +( + (?:[[:alpha:]:_][[:alnum:]:_.-]*)| + (?:\#[[:digit:]]+)| + (?:\#x[[:xdigit:]]+) +) +(;) + captures + + 1 + + name + punctuation.definition.constant.cs + + 3 + + name + punctuation.definition.constant.cs + + + + + name + invalid.illegal.bad-ampersand.cs + match + & + + + + xml-comment + + name + comment.block.cs + begin + <!-- + beginCaptures + + 0 + + name + punctuation.definition.comment.cs + + + end + --> + endCaptures + + 0 + + name + punctuation.definition.comment.cs + + + + + + \ No newline at end of file diff --git a/test/syntaxes/class.test.syntax.ts b/test/syntaxes/class.test.syntax.ts deleted file mode 100644 index ec967ce46a..0000000000 --- a/test/syntaxes/class.test.syntax.ts +++ /dev/null @@ -1,175 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function() { - should(); - }); - - describe("Class", function() { - it("class keyword and storage modifiers", function() { - -const input = ` -namespace TestNamespace -{ - public class PublicClass { } - - class DefaultClass { } - - internal class InternalClass { } - - static class DefaultStaticClass { } - - public static class PublicStaticClass { } - - sealed class DefaultSealedClass { } - - public sealed class PublicSealedClass { } - - public abstract class PublicAbstractClass { } - - abstract class DefaultAbstractClass { } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.ClassKeyword("class", 4, 24)); - tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 4, 30)); - - tokens.should.contain(Tokens.ClassKeyword("class", 6, 24)); - tokens.should.contain(Tokens.ClassIdentifier("DefaultClass", 6, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("internal", 8, 5)); - tokens.should.contain(Tokens.ClassKeyword("class", 8, 24)); - tokens.should.contain(Tokens.ClassIdentifier("InternalClass", 8, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("static", 10, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 10, 24)); - tokens.should.contain(Tokens.ClassIdentifier("DefaultStaticClass", 10, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 12, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("static", 12, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 12, 24)); - tokens.should.contain(Tokens.ClassIdentifier("PublicStaticClass", 12, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("sealed", 14, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 14, 24)); - tokens.should.contain(Tokens.ClassIdentifier("DefaultSealedClass", 14, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 16, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("sealed", 16, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 16, 24)); - tokens.should.contain(Tokens.ClassIdentifier("PublicSealedClass", 16, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 18, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("abstract", 18, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 18, 24)); - tokens.should.contain(Tokens.ClassIdentifier("PublicAbstractClass", 18, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("abstract", 20, 15)); - tokens.should.contain(Tokens.ClassKeyword("class", 20, 24)); - tokens.should.contain(Tokens.ClassIdentifier("DefaultAbstractClass", 20, 30)); - - }); - - it("generics in identifier", function () { - - const input = ` -namespace TestNamespace -{ - class Dictionary> { } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.ClassKeyword("class", 4, 5)); - - // OLD: tokens.should.contain(Tokens.ClassIdentifier("Dictionary>", 4, 11)); - tokens.should.contain(Tokens.ClassIdentifier("Dictionary", 4, 11)); - tokens.should.contain(Tokens.ClassIdentifier("T", 4, 22)); - tokens.should.contain(Tokens.ClassIdentifier("Dictionary", 4, 25)); - }); - - it("inheritance", function() { - -const input = ` -namespace TestNamespace -{ - class PublicClass : IInterface, IInterfaceTwo { } - class PublicClass : Root.IInterface, Something.IInterfaceTwo { } - class PublicClass : Dictionary>, IMap> { } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.ClassKeyword("class", 4, 5)); - tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 4, 11)); - tokens.should.contain(Tokens.Type("IInterface", 4, 28)); - tokens.should.contain(Tokens.Type("IInterfaceTwo", 4, 43)); - - tokens.should.contain(Tokens.ClassKeyword("class", 5, 5)); - tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 5, 11)); - tokens.should.contain(Tokens.Type("Root.IInterface", 5, 28)); - tokens.should.contain(Tokens.Type("Something.IInterfaceTwo", 5, 63)); - tokens.should.contain(Tokens.Type("Dictionary", 6, 28)); - tokens.should.contain(Tokens.Type("Dictionary", 6, 42)); - tokens.should.contain(Tokens.Type("IMap", 6, 71)); - tokens.should.contain(Tokens.Type("Dictionary", 6, 79)); - }); - - it("generic constraints", function() { - -const input = ` -namespace TestNamespace -{ - class PublicClass where T : ISomething { } - class PublicClass : Dictionary[]>, ISomething where T : ICar, new() where X : struct { } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.ClassKeyword("class", 4, 5)); - tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 4, 11)); - tokens.should.contain(Tokens.Keyword("where", 4, 26)); - tokens.should.contain(Tokens.Type("T", 4, 32)); - tokens.should.contain(Tokens.Type("ISomething", 4, 36)); - - tokens.should.contain(Tokens.ClassKeyword("class", 5, 5)); - tokens.should.contain(Tokens.ClassIdentifier("PublicClass", 5, 11)); - tokens.should.contain(Tokens.Type("Dictionary", 5, 31)); - tokens.should.contain(Tokens.Type("List[]", 5, 45)); - tokens.should.contain(Tokens.Type("ISomething", 5, 62)); - tokens.should.contain(Tokens.Keyword("where", 5, 73)); - tokens.should.contain(Tokens.Type("T", 5, 79)); - tokens.should.contain(Tokens.Type("ICar", 5, 83)); - tokens.should.contain(Tokens.Keyword("new", 5, 89)); - tokens.should.contain(Tokens.Keyword("where", 5, 95)); - tokens.should.contain(Tokens.Type("X", 5, 101)); - tokens.should.contain(Tokens.Keyword("struct", 5, 105)); - - }); - - it("nested class", function() { - -const input = ` -namespace TestNamespace -{ - class Klass - { - public class Nested - { - - } - } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.ClassKeyword("class", 4, 5)); - tokens.should.contain(Tokens.ClassIdentifier("Klass", 4, 11)); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 6, 9)); - tokens.should.contain(Tokens.ClassKeyword("class", 6, 16)); - tokens.should.contain(Tokens.ClassIdentifier("Nested", 6, 22)); - }); - }); -}); - - diff --git a/test/syntaxes/event.test.syntax.ts b/test/syntaxes/event.test.syntax.ts deleted file mode 100644 index 2d13aa042a..0000000000 --- a/test/syntaxes/event.test.syntax.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function() { - should(); - }); - - describe("Event", function() { - it("declaration", function() { - -const input = ` -public class Tester -{ - public event Type Event; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("event", 4, 12)); - tokens.should.contain(Tokens.Type("Type", 4, 18)); - tokens.should.contain(Tokens.EventIdentifier("Event", 4, 23)); - }); - - it("generic", function () { - - const input = ` -public class Tester -{ - public event EventHandler, Dictionary> Event; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("event", 4, 12)); - tokens.should.contain(Tokens.Type("EventHandler", 4, 18)); - tokens.should.contain(Tokens.Type("List", 4, 31)); - tokens.should.contain(Tokens.Type("Dictionary", 4, 40)); - tokens.should.contain(Tokens.EventIdentifier("Event", 4, 58)); - }); - }); -}); - - diff --git a/test/syntaxes/field.test.syntax.ts b/test/syntaxes/field.test.syntax.ts deleted file mode 100644 index 1b72f5be66..0000000000 --- a/test/syntaxes/field.test.syntax.ts +++ /dev/null @@ -1,136 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function() { - should(); - }); - - describe("Field", function() { - it("declaration", function() { - -const input = ` -public class Tester -{ - private List _field; - private List field; - private List field123; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5)); - tokens.should.contain(Tokens.Type("List", 4, 13)); - tokens.should.contain(Tokens.FieldIdentifier("_field", 4, 18)); - - tokens.should.contain(Tokens.FieldIdentifier("field", 5, 18)); - tokens.should.contain(Tokens.FieldIdentifier("field123", 6, 18)); - }); - - it("generic", function () { - - const input = ` -public class Tester -{ - private Dictionary< List, Dictionary> _field; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5)); - tokens.should.contain(Tokens.Type("Dictionary", 4, 13)); - tokens.should.contain(Tokens.Type("List", 4, 25)); - tokens.should.contain(Tokens.Type("Dictionary", 4, 34)); - tokens.should.contain(Tokens.FieldIdentifier("_field", 4, 52)); - }); - - - it("modifiers", function() { - -const input = ` -public class Tester -{ - private static readonly List _field; - readonly string _field2; - string _field3; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5)); - tokens.should.contain(Tokens.StorageModifierKeyword("static", 4, 13)); - tokens.should.contain(Tokens.StorageModifierKeyword("readonly", 4, 20)); - tokens.should.contain(Tokens.Type("List", 4, 29)); - tokens.should.contain(Tokens.FieldIdentifier("_field", 4, 34)); - - tokens.should.contain(Tokens.FieldIdentifier("_field2", 5, 21)); - - tokens.should.contain(Tokens.FieldIdentifier("_field3", 6, 12)); - }); - - it("types", function() { - -const input = ` -public class Tester -{ - string field123; - string[] field123; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.Type("string", 4, 5)); - tokens.should.contain(Tokens.FieldIdentifier("field123", 4, 12)); - - tokens.should.contain(Tokens.Type("string[]", 5, 5)); - tokens.should.contain(Tokens.FieldIdentifier("field123", 5, 14)); - }); - - it("assignment", function() { - -const input = ` -public class Tester -{ - private string field = "hello"; - const bool field = true; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5)); - tokens.should.contain(Tokens.Type("string", 4, 13)); - tokens.should.contain(Tokens.FieldIdentifier("field", 4, 20)); - tokens.should.contain(Tokens.StringDoubleQuoted("hello", 4, 29)); - - tokens.should.contain(Tokens.StorageModifierKeyword("const", 5, 5)); - tokens.should.contain(Tokens.Type("bool", 5, 13)); - tokens.should.contain(Tokens.FieldIdentifier("field", 5, 20)); - tokens.should.contain(Tokens.LanguageConstant("true", 5, 28)); - }); - - it("expression body", function() { - -const input = ` -public class Tester -{ - private string field => "hello"; - const bool field => true; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 5)); - tokens.should.contain(Tokens.Type("string", 4, 13)); - tokens.should.contain(Tokens.FieldIdentifier("field", 4, 20)); - tokens.should.contain(Tokens.StringDoubleQuoted("hello", 4, 30)); - - tokens.should.contain(Tokens.StorageModifierKeyword("const", 5, 5)); - tokens.should.contain(Tokens.Type("bool", 5, 13)); - tokens.should.contain(Tokens.FieldIdentifier("field", 5, 20)); - tokens.should.contain(Tokens.LanguageConstant("true", 5, 29)); - }); - }); -}); - - diff --git a/test/syntaxes/namespace.test.syntax.ts b/test/syntaxes/namespace.test.syntax.ts deleted file mode 100644 index c071f4381f..0000000000 --- a/test/syntaxes/namespace.test.syntax.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function () { - should(); - }); - - describe("Namespace", function() { - it("has a namespace keyword and a name", function() { - -const input = ` -namespace TestNamespace -{ -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.NamespaceKeyword("namespace", 2, 1)); - tokens.should.contain(Tokens.NamespaceIdentifier("TestNamespace", 2, 11)); - }); - - it("can be nested", function() { - -const input = ` -namespace TestNamespace -{ - namespace NestedNamespace { - - } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.NamespaceKeyword("namespace", 2, 1)); - tokens.should.contain(Tokens.NamespaceIdentifier("TestNamespace", 2, 11)); - - tokens.should.contain(Tokens.NamespaceKeyword("namespace", 4, 5)); - tokens.should.contain(Tokens.NamespaceIdentifier("NestedNamespace", 4, 15)); - }); - - it("can contain using statements", function() { - -const input = ` -using UsineOne; -using one = UsineOne.Something; - -namespace TestNamespace -{ - using UsingTwo; - using two = UsineOne.Something; - - namespace NestedNamespace - { - using UsingThree; - using three = UsineOne.Something; - } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.UsingKeyword("using", 2, 1)); - tokens.should.contain(Tokens.UsingKeyword("using", 3, 1)); - - tokens.should.contain(Tokens.NamespaceKeyword("namespace", 5, 1)); - tokens.should.contain(Tokens.NamespaceIdentifier("TestNamespace", 5, 11)); - - tokens.should.contain(Tokens.UsingKeyword("using", 7, 5)); - tokens.should.contain(Tokens.UsingKeyword("using", 8, 5)); - - tokens.should.contain(Tokens.NamespaceKeyword("namespace", 10, 5)); - tokens.should.contain(Tokens.NamespaceIdentifier("NestedNamespace", 10, 15)); - - tokens.should.contain(Tokens.UsingKeyword("using", 12, 9)); - tokens.should.contain(Tokens.UsingKeyword("using", 12, 9)); - }); - }); -}); - - diff --git a/test/syntaxes/property.test.syntax.ts b/test/syntaxes/property.test.syntax.ts deleted file mode 100644 index 1bc549f66d..0000000000 --- a/test/syntaxes/property.test.syntax.ts +++ /dev/null @@ -1,137 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function() { - should(); - }); - - describe("Property", function() { - it("declaration", function() { - -const input = ` -class Tester -{ - public IBooom Property - { - get { return null; } - set { something = value; } - } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("IBooom", 4, 12)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 19)); - tokens.should.contain(Tokens.Keyword("get", 6, 9)); - tokens.should.contain(Tokens.Keyword("set", 7, 9)); - }); - - it("declaration single line", function() { - -const input = ` -class Tester -{ - public IBooom Property { get { return null; } private set { something = value; } } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("IBooom", 4, 12)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 19)); - tokens.should.contain(Tokens.Keyword("get", 4, 30)); - tokens.should.contain(Tokens.StorageModifierKeyword("private", 4, 51)); - tokens.should.contain(Tokens.Keyword("set", 4, 59)); - }); - - - it("declaration without modifiers", function() { - -const input = ` -class Tester -{ - IBooom Property {get; set;} -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.Type("IBooom", 4, 5)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 12)); - }); - - it("auto-property single line", function() { - -const input = ` -class Tester -{ - public IBooom Property { get; set; } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("IBooom", 4, 12)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 19)); - tokens.should.contain(Tokens.Keyword("get", 4, 30)); - tokens.should.contain(Tokens.Keyword("set", 4, 35)); - }); - - it("auto-property", function() { - -const input = ` -class Tester -{ - public IBooom Property - { - get; - set; - } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("IBooom", 4, 12)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 19)); - tokens.should.contain(Tokens.Keyword("get", 6, 9)); - tokens.should.contain(Tokens.Keyword("set", 7, 9)); - }); - - it("generic auto-property", function() { - -const input = ` -class Tester -{ - public Dictionary[]> Property { get; set; } -}`; - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("Dictionary", 4, 12)); - tokens.should.contain(Tokens.Type("string", 4, 23)); - tokens.should.contain(Tokens.Type("List[]", 4, 31)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 42)); - tokens.should.contain(Tokens.Keyword("get", 4, 53)); - tokens.should.contain(Tokens.Keyword("set", 4, 58)); - }); - - it("auto-property initializer", function() { - -const input = ` -class Tester -{ - public Dictionary[]> Property { get; } = new Dictionary[]>(); -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StorageModifierKeyword("public", 4, 5)); - tokens.should.contain(Tokens.Type("Dictionary", 4, 12)); - tokens.should.contain(Tokens.Type("string", 4, 23)); - tokens.should.contain(Tokens.Type("List[]", 4, 31)); - tokens.should.contain(Tokens.PropertyIdentifier("Property", 4, 42)); - tokens.should.contain(Tokens.Keyword("get", 4, 53)); - tokens.should.contain(Tokens.StorageModifierKeyword("new", 4, 62)); - }); - }); -}); - - diff --git a/test/syntaxes/string.test.syntax.ts b/test/syntaxes/string.test.syntax.ts deleted file mode 100644 index c7b9873d1e..0000000000 --- a/test/syntaxes/string.test.syntax.ts +++ /dev/null @@ -1,123 +0,0 @@ -import { should } from 'chai'; -import { Tokens, Token } from './utils/tokenizer'; -import { TokenizerUtil } from'./utils/tokenizerUtil'; - -describe("Grammar", function() { - before(function() { - should(); - }); - - describe("String interpolated", function() { - it("non-verbatim", function() { - -const input = ` -public class Tester -{ - string test = $"hello {one} world {two}!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuoted("hello ", 4, 21)); - tokens.should.contain(Tokens.StringInterpolatedExpression("one", 4, 28)); - tokens.should.contain(Tokens.StringDoubleQuoted(" world ", 4, 32)); - tokens.should.contain(Tokens.StringInterpolatedExpression("two", 4, 40)); - tokens.should.contain(Tokens.StringDoubleQuoted("!", 4, 44)); - tokens.should.contain(Tokens.StringEnd('"', 4, 45)); - }); - - - it("non-verbatim without expressions single-line", function() { - -const input = ` -public class Tester -{ - string test = $"hello world!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuoted("hello world!", 4, 21)); - tokens.should.contain(Tokens.StringEnd('"', 4, 33)); - }); - - it("non-verbatim multi-line", function() { - -const input = ` -public class Tester -{ - string test = $"hello -world!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuoted("hello", 4, 21)); - tokens.should.not.contain(Tokens.StringDoubleQuoted("world!", 5, 1)); - tokens.should.not.contain(Tokens.StringEnd('"', 5, 7)); - }); - - - it("verbatim single-line", function() { - -const input = ` -public class Tester -{ - string test = $@"hello {one} world {two}!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$@"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim("hello ", 4, 22)); - tokens.should.contain(Tokens.StringInterpolatedExpression("one", 4, 29)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim(" world ", 4, 33)); - tokens.should.contain(Tokens.StringInterpolatedExpression("two", 4, 41)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim("!", 4, 45)); - tokens.should.contain(Tokens.StringEnd('"', 4, 46)); - }); - - - it("verbatim multi-line", function() { - -const input = ` -public class Tester -{ - string test = $@"hello {one} - world {two}!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$@"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim("hello ", 4, 22)); - tokens.should.contain(Tokens.StringInterpolatedExpression("one", 4, 29)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim(" world ", 5, 1)); - tokens.should.contain(Tokens.StringInterpolatedExpression("two", 5, 12)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim("!", 5, 16)); - tokens.should.contain(Tokens.StringEnd('"', 5, 17)); - }); - - it("verbatim multi-line without expressions", function() { - -const input = ` -public class Tester -{ - string test = $@"hello - world!"; -}`; - - let tokens: Token[] = TokenizerUtil.tokenize(input); - - tokens.should.contain(Tokens.StringStart('$@"', 4, 19)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim("hello", 4, 22)); - tokens.should.contain(Tokens.StringDoubleQuotedVerbatim(" world!", 5, 1)); - tokens.should.contain(Tokens.StringEnd('"', 5, 11)); - }); - }); -}); - - diff --git a/test/syntaxes/utils/tokenizer.ts b/test/syntaxes/utils/tokenizer.ts deleted file mode 100644 index e49d2e3bfd..0000000000 --- a/test/syntaxes/utils/tokenizer.ts +++ /dev/null @@ -1,108 +0,0 @@ -import {ITokenizeLineResult, Registry, IGrammar, StackElement} from 'vscode-textmate'; - -export class Tokenizer -{ - private _grammar : IGrammar; - - constructor(grammarFilePath: string) { - this._grammar = new Registry().loadGrammarFromPathSync(grammarFilePath); - } - - public tokenize(input: string): Token[] { - let tokens: Token[] = []; - - // ensure consistent line-endings irrelevant of OS - input = input.replace("\r\n","\n"); - - let previousStack : StackElement = null; - - const lines: string[] = input.split("\n"); - - for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) { - const line = lines[lineIndex]; - - let result: ITokenizeLineResult = this._grammar.tokenizeLine(line, previousStack); - previousStack = result.ruleStack; - - for (const token of result.tokens) { - const text = line.substring(token.startIndex, token.endIndex); - const type : string = token.scopes[token.scopes.length - 1]; - tokens.push(new Token(text, type, lineIndex+1, token.startIndex + 1)); - } - } - - return tokens; - } -} - -export class Token { - constructor(text: string, type: string, line?: number, column?: number) { - this.text = text; - this.type = type; - this.column = column; - this.line = line; - } - - public text: string; - public type: string; - public line: number; - public column: number; -} - -export namespace Tokens { - - function createToken(text: string, type: string, line?: number, column?: number) : Token { - return new Token(text, type, line, column); - } - - export const NamespaceKeyword = (text: string, line?: number, column?: number) => - createToken(text, "keyword.other.namespace.cs", line, column); - - export const NamespaceIdentifier = (text: string, line?: number, column?: number) => - createToken(text, "entity.name.type.namespace.cs", line, column); - - export const UsingKeyword = (text: string, line?: number, column?: number) => - createToken(text, "keyword.other.using.cs", line, column); - - export const ClassKeyword = (text: string, line?: number, column?: number) => - createToken(text, "storage.modifier.cs", line, column); - - export const ClassIdentifier = (text: string, line?: number, column?: number) => - createToken(text, "storage.type.cs", line, column); - - export const StorageModifierKeyword = (text: string, line?: number, column?: number) => - createToken(text, "storage.modifier.cs", line, column); - - export const Type = (text: string, line?: number, column?: number) => - createToken(text, "storage.type.cs", line, column); - - export const Keyword = (text: string, line?: number, column?: number) => - createToken(text, "keyword.other.cs", line, column); - - export const FieldIdentifier = (text: string, line?: number, column?: number) => - createToken(text, "entity.name.variable.cs", line, column); - - export const StringDoubleQuoted = (text: string, line?: number, column?: number) => - createToken(text, "string.quoted.double.cs", line, column); - - export const StringDoubleQuotedVerbatim = (text: string, line?: number, column?: number) => - createToken(text, "string.quoted.double.literal.cs", line, column); - - export const EventIdentifier = (text: string, line?: number, column?: number) => - createToken(text, "entity.name.variable.cs", line, column); - - export const LanguageConstant = (text: string, line?: number, column?: number) => - createToken(text, "constant.language.cs", line, column); - - export const PropertyIdentifier = (text: string, line?: number, column?: number) => - createToken(text, "entity.name.function.cs", line, column); - - export const StringInterpolatedExpression = (text: string, line?: number, column?: number) => - createToken(text, "meta.interpolated.expression.cs", line, column); - - export const StringStart = (text: string, line?: number, column?: number) => - createToken(text, "punctuation.definition.string.begin.cs", line, column); - - export const StringEnd = (text: string, line?: number, column?: number) => - createToken(text, "punctuation.definition.string.end.cs", line, column); -} diff --git a/test/syntaxes/utils/tokenizerUtil.ts b/test/syntaxes/utils/tokenizerUtil.ts deleted file mode 100644 index 2bb010b035..0000000000 --- a/test/syntaxes/utils/tokenizerUtil.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { Tokenizer, Token } from './tokenizer'; - -export class TokenizerUtil -{ - private static _tokenizer: Tokenizer = new Tokenizer("syntaxes/csharp.json"); - - public static tokenize(input: string): Token[] { - return TokenizerUtil._tokenizer.tokenize(input); - } -} diff --git a/tsconfig.json b/tsconfig.json index cbe85ef3af..ba759a3c07 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,6 +11,7 @@ }, "exclude": [ "node_modules", + "syntaxes", ".vscode-test" ] } \ No newline at end of file diff --git a/typings/vscode-tasks.d.ts b/typings/vscode-tasks.d.ts index 25c76eaf61..a4a4245f7d 100644 --- a/typings/vscode-tasks.d.ts +++ b/typings/vscode-tasks.d.ts @@ -45,6 +45,13 @@ declare module "vscode-tasks" { */ isShellCommand?: boolean; + /** + * Specifies whether a global command is watching the filesystem. A task.json + * file can either contain a global isWatching property or a tasks property + * but not both. + */ + isWatching?: boolean; + /** * The command options used when the command is executed. Can be omitted. */ @@ -79,7 +86,7 @@ declare module "vscode-tasks" { * prefix (e.g. /t: for msbuild). This property can be used to control such * a prefix. */ - taskSelector?:string; + taskSelector?: string; /** * The problem matcher to be used if a global command is executed (e.g. no tasks @@ -110,7 +117,7 @@ declare module "vscode-tasks" { * The environment of the executed program or shell. If omitted * the parent process' environment is used. */ - env?: { [key:string]:string; }; + env?: { [key: string]: string; }; } /** @@ -132,13 +139,18 @@ declare module "vscode-tasks" { /** * Whether this task maps to the default build command. */ - isBuildCommand?:boolean; + isBuildCommand?: boolean; /** * Whether this task maps to the default test command. */ isTestCommand?: boolean; + /** + * Whether the executed command is kept alive and is watching the file system. + */ + isWatching?: boolean; + /** * Controls whether the output view of the running tasks is brought to front or not. * See BaseTaskConfiguration#showOutput for details. @@ -209,6 +221,35 @@ declare module "vscode-tasks" { * problems spread over multiple lines. */ pattern?: string | ProblemPattern | ProblemPattern[]; + + /** + * Additional information used to detect when a background task (like a watching task in Gulp) + * is active. + */ + watching?: WatchingMatcher; + } + + /** + * A description to track the start and end of a watching task. + */ + export interface WatchingMatcher { + + /** + * If set to true the watcher is in active mode when the task + * starts. This is equals of issuing a line that matches the + * beginPattern. + */ + activeOnStart?: boolean; + + /** + * If matched in the output the start of a watching task is signaled. + */ + beginsPattern?: string; + + /** + * If matched in the output the end of a watching task is signaled. + */ + endsPattern?: string; } export interface ProblemPattern { @@ -221,9 +262,8 @@ declare module "vscode-tasks" { /** * The match group index of the filename. - * If omitted 1 is used. */ - file?: number; + file: number; /** * The match group index of the problems's location. Valid location @@ -234,15 +274,12 @@ declare module "vscode-tasks" { /** * The match group index of the problem's line in the source file. - * - * Defaults to 2. + * Can only be omitted if location is specified. */ line?: number; /** * The match group index of the problem's column in the source file. - * - * Defaults to 3. */ column?: number; @@ -276,10 +313,9 @@ declare module "vscode-tasks" { code?: number; /** - * The match group index of the message. If omitted it defaults - * to 4 if location is specified. Otherwise it defaults to 5. + * The match group index of the message. Defaults to 0. */ - message?: number; + message: number; /** * Specifies if the last pattern in a multi line problem matcher should diff --git a/typings/vscode-textmate/vscode-textmate.d.ts b/typings/vscode-textmate/vscode-textmate.d.ts deleted file mode 100644 index 6a16e2dc7b..0000000000 --- a/typings/vscode-textmate/vscode-textmate.d.ts +++ /dev/null @@ -1,80 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -declare module "vscode-textmate" { - -/** - * A registry helper that can locate grammar file paths given scope names. - */ -export interface IGrammarLocator { - getFilePath(scopeName:string): string; - getInjections?(scopeName:string): string[]; -} - -/** - * The registry that will hold all grammars. - */ -export class Registry { - - constructor(locator?:IGrammarLocator, useExperimentalParser?:boolean); - - /** - * Load the grammar for `scopeName` and all referenced included grammars asynchronously. - */ - public loadGrammar(scopeName:string, callback:(err:any, grammar:IGrammar)=>void): void; - - /** - * Load the grammar at `path` synchronously. - */ - public loadGrammarFromPathSync(path:string): IGrammar; - - /** - * Get the grammar for `scopeName`. The grammar must first be created via `loadGrammar` or `loadGrammarFromPathSync`. - */ - public grammarForScopeName(scopeName:string): IGrammar; -} - -export interface IGrammarInfo { - fileTypes: string[]; - name: string; - scopeName: string; - firstLineMatch: string; -} - -/** - * A grammar - */ -export interface IGrammar { - /** - * Tokenize `lineText` using previous line state `prevState`. - */ - tokenizeLine(lineText: string, prevState: StackElement): ITokenizeLineResult; -} - -export interface ITokenizeLineResult { - tokens: IToken[]; - /** - * The `prevState` to be passed on to the next line tokenization. - */ - ruleStack: StackElement; -} - -export interface IToken { - startIndex: number; - endIndex: number; - scopes: string[]; -} - -/** - * Should not be used by consumers, as its shape might change at any time. - */ -export interface StackElement { - _stackElementBrand: void; - _parent: StackElement; - - equals(other:StackElement): boolean; -} - -} \ No newline at end of file