diff --git a/CHANGELOG.md b/CHANGELOG.md index cabea91d1a..13c53836bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,48 @@ +## 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)) +* There currently is no completion support for package references in csproj files. ([#1156](https://github.com/OmniSharp/omnisharp-vscode/issues/1156)) + +## 1.8.0 _(Not Yet Released)_ + +#### Go to Implementation + +* Added support for "Go to Implementation" and "Peek Implementation" introduced in Visual Studio Code 1.9. ([#37](https://github.com/OmniSharp/omnisharp-vscode/issues/37)) _(Contributed by [@ivanz](https://github.com/ivanz))_ + +#### Scripting + +* C# scripts (.csx files) now allow multiple `#load` directives, and `#r` and `#load` directives update live. ([omnisharp-roslyn#760](https://github.com/OmniSharp/omnisharp-roslyn/pull/760)) _(Contributed by [@filipw](https://github.com/filipw))_ +* .csx files can now be discovered as valid launch targets using the project selector at the bottom-right of the status bar. ([#1247](https://github.com/OmniSharp/omnisharp-vscode/pull/1247)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Assembly references will now unify properly for C# scripts. ([omnisharp-roslyn#764](https://github.com/OmniSharp/omnisharp-roslyn/pull/764)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Unsafe code is now allowed in C# scripts. ([omnisharp-roslyn#781](https://github.com/OmniSharp/omnisharp-roslyn/pull/781)) _(Contributed by [@filipw](https://github.com/filipw))_ +* C# scripting now ignores duplicated CorLibrary types, which can manifest in certain edge scenarios. ([omnisharp-roslyn#784](https://github.com/OmniSharp/omnisharp-roslyn/pull/784)) _(Contributed by [@filipw](https://github.com/filipw))_ + +#### Debugger + +The 1.8 release makes a major change to how the debugger works under the hood. This new architecture simplifies how the debugger is tied to VS Code. We hope that this will make it easier to bring .NET debugging features to VS Code. We also expect it to improve debugger launch performance. + +Changes: + +* The module load messages in the output window are now more detailed and hopefully less confusing. ([#837](https://github.com/OmniSharp/omnisharp-vscode/issues/837)) +* Programs can now be launched into VS Code's integrated terminal. ([documentation](https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger.md#console-terminal-window)) +* VS Code recently introduced [column breakpoint support](https://code.visualstudio.com/updates/v1_10#_column-breakpoints) and they are now enabled for C#. +* React to the VS Code change to use `${command:` instead of `${command.`. ([#1275](https://github.com/OmniSharp/omnisharp-vscode/issues/1275)) +* Fix a problem with browser launch support that could lead to debugger session's being aborted when the browser is started. ([#1274](https://github.com/OmniSharp/omnisharp-vscode/issues/1274)) +* Remote debugging breaking changes: as part of our new architecture, there are a few breaking changes to the way remote debugging works. + + * vsdbg vs. clrdbg: As part of the new architecture, clrdbg has been replaced with a new executable named vsdbg. As such, the script to download vsdbg has changed to http://aka.ms/getvsdbgsh. Run `curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -v latest -l ~/vsdbg` to download. See the [wiki](https://github.com/OmniSharp/omnisharp-vscode/wiki/Attaching-to-remote-processes) for more information. + * Pseudo-tty's are no longer supported: previously we were a little more tolerant of pseudo-tty's transforming the input/output from the remote debugger. We are currently not as tolerant. If you are using `ssh` or `plink` as a pipe program, pass `-T` to fix this. If you have another transport and you are no longer able to connect, let us know and we can fix this for a future release. + * `debuggerPath` is now required - previously the `debuggerPath` property of `pipeTransport` was recomended but not required. As part of this change we are now requiring it. + +#### Other Updates and Fixes + +* Find All References now properly highlights locations of found references. ([#428](https://github.com/OmniSharp/omnisharp-vscode/issues/428)) +* Assembly references will now unify properly for project.json projects. ([#1221](https://github.com/OmniSharp/omnisharp-vscode/issues/1221)) +* Code Actions (i.e. refactorings and fixes) now respect the formatting options that are set when a project is opened. ([omnisharp-roslyn#759](https://github.com/OmniSharp/omnisharp-roslyn/issues/759)) _(Contributed by [@filipw](https://github.com/filipw))_ +* Completion support for package references in project.json files has been restored. ([#1236](https://github.com/OmniSharp/omnisharp-vscode/pull/1236)) +* The C# TextMate grammar used for syntax highlighting has been removed because it is now part of Visual Studio Code itself. ([#1206](https://github.com/OmniSharp/omnisharp-vscode/issues/1206)) _(Many thanks to [@aeschli](https://github.com/aeschli))_ + ## 1.7.0 (February 8, 2017) #### Syntax Hightlighting @@ -5,7 +50,7 @@ * 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 +#### 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)) @@ -15,30 +60,30 @@ * 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 +#### 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 +#### 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 +#### 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 +#### 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 +#### 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))_ @@ -50,11 +95,6 @@ * 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)) @@ -83,7 +123,7 @@ * Brings support for running all supported distros on top of Linux Kernel >= 4.6 * Enable debugger support for Arch Linux ([#564](https://github.com/OmniSharp/omnisharp-vscode/issues/564)) * Improve debugger install errors for macOS without openSSL symlinks ([#986](https://github.com/OmniSharp/omnisharp-vscode/pull/986)), and x86 Windows ([#998](https://github.com/OmniSharp/omnisharp-vscode/pull/998)). -* Improve debugger performance using precompiled debugger binaries ([#896](https://github.com/OmniSharp/omnisharp-vscode/issues/896))([#971](https://github.com/OmniSharp/omnisharp-vscode/issues/971)). +* Improve debugger performance using precompiled debugger binaries ([#896](https://github.com/OmniSharp/omnisharp-vscode/issues/896))([#971](https://github.com/OmniSharp/omnisharp-vscode/issues/971)). #### Syntax Highlighting @@ -91,7 +131,7 @@ * Fix for field declarations. ([#757](https://github.com/OmniSharp/omnisharp-vscode/issues/757)) * Fix for generic types with multiple type parameters. ([#960](https://github.com/OmniSharp/omnisharp-vscode/issues/960)) * Proper support for interpolated strings (verbatim and non-verbatim). ([#852](https://github.com/OmniSharp/omnisharp-vscode/issues/852)) - * Fix for multi-line properties. ([#854](https://github.com/OmniSharp/omnisharp-vscode/issues/854)) + * Fix for multi-line properties. ([#854](https://github.com/OmniSharp/omnisharp-vscode/issues/854)) * Fixes for events, nested type references (e.g. `Root.IInterface`), variable declarations, nested classes, and fields spanning multiple lines #### Hover Tooltips @@ -117,7 +157,7 @@ * Ensure diagnostics are cleared in files when they are no longer needed. ([#858](https://github.com/OmniSharp/omnisharp-vscode/issues/858)) * Enqueue requests for diagnostics in visible editors when the extension starts up. ([#843](https://github.com/OmniSharp/omnisharp-vscode/issues/843)) * Provide fallback URLs for debugger downloads. ([#930](https://github.com/OmniSharp/omnisharp-vscode/issues/930)) -* Properly require .NET Framework 4.6 in the OmniSharp.exe.config file to ensure that the user is displayed a dialog on Windows machines that don't have .NET Framework 4.6 installed. ([#937](https://github.com/OmniSharp/omnisharp-vscode/issues/937)) +* Properly require .NET Framework 4.6 in the OmniSharp.exe.config file to ensure that the user is displayed a dialog on Windows machines that don't have .NET Framework 4.6 installed. ([#937](https://github.com/OmniSharp/omnisharp-vscode/issues/937)) * Fix issue with installing on non-English installations of Windows. ([#938](https://github.com/OmniSharp/omnisharp-vscode/issues/938)) * Display platform information when acquiring runtime dependencies. ([#948](https://github.com/OmniSharp/omnisharp-vscode/issues/948)) @@ -165,7 +205,7 @@ Several new settings have been added: #### Performance -* Major improvements have been made to editor performance. The communication with the OmniSharp server has been rewritten to allow long-running operations (such as gathering all errors and warnings) to queue while high priority operations (such as text buffer changes) run serially. ([#902](https://github.com/OmniSharp/omnisharp-vscode/pull/902)) _(Thanks to [@david-driscoll](https://github.com/david-driscoll) for his help with this change!)_ +* Major improvements have been made to editor performance. The communication with the OmniSharp server has been rewritten to allow long-running operations (such as gathering all errors and warnings) to queue while high priority operations (such as text buffer changes) run serially. ([#902](https://github.com/OmniSharp/omnisharp-vscode/pull/902)) _(Thanks to [@david-driscoll](https://github.com/david-driscoll) for his help with this change!)_ #### Other Improvements @@ -225,7 +265,7 @@ There have been several fixes to the colorizer grammar resulting in much smoothe * Support for Unity and Mono development on macOS and Linux has been restored! This release brings back support for the Mono version of OmniSharp, which is used to provide *much* better support for .csproj/.sln projects. Please note that Mono version 4.0.1 or newer is required. * Generation of tasks.json and launch.json files can now properly handle nested projects. [#170](https://github.com/OmniSharp/omnisharp-vscode/issues/170) -* New UI that makes it easy to select a process ID when attaching the debugger to another process. Note: If you have an existing launch.json file, you can re-generate it by deleting the file, closing your workspace in Visual Studio Code and opening it again. Or, you can open the launch.json file and change the `processId` value to `"${command.pickProcess}"`. +* New UI that makes it easy to select a process ID when attaching the debugger to another process. Note: If you have an existing launch.json file, you can re-generate it by deleting the file, closing your workspace in Visual Studio Code and opening it again. Or, you can open the launch.json file and change the `processId` value to `"${command:pickProcess}"`. * Support for debugging in .cshtml files. To enable this, add a `sourceFileMap` entry to your launch.json with the following content: `"sourceFileMap": { "/Views": "${workspaceRoot}/Views" }` * Support for conditional breakpoints * New support for changing variable values in the debugger! To try this, just right-click on the variable name and select 'Set Value'. Note: To properly support this feature, we've changed the display of variable type names in the debugger to a shortened form. The full type name can be viewed by hovering over the name with the mouse. diff --git a/README.md b/README.md index 1e78a97c4a..1d00cf2e4a 100644 --- a/README.md +++ b/README.md @@ -18,15 +18,15 @@ The C# extension is powered by [OmniSharp](https://github.com/OmniSharp/omnishar * [Documentation](https://code.visualstudio.com/docs/languages/csharp) * [Video Tutorial compiling with .NET Core](https://channel9.msdn.com/Blogs/dotnet/Get-started-with-VS-Code-using-CSharp-and-NET-Core) -### What's New in 1.7.0 +### What's New in 1.8.0 -* A brand new TextMate grammar written from scratch that provides much more robust C# syntax highlighting -* Better support for .NET Core .csproj projects, including .NET Core projects created with the latest [Visual Studio 2017 RC](https://www.visualstudio.com/vs/visual-studio-2017-rc/). -* Support for restoring NuGet packages in .NET Core .csproj projects. -* Improved code action support, including fixes like "Move Type to File" and "Generate Type". +* Added support for "Go to Implementation" and "Peek Implementation" +* Improvements to C# scripting support +* New architecture for the debugger +* Several breaking changes to remote debugging (see changelog for details). * Lot's more! -See our [change log](https://github.com/OmniSharp/omnisharp-vscode/blob/v1.7.0/CHANGELOG.md) for all of the updates. +See our [change log](https://github.com/OmniSharp/omnisharp-vscode/blob/v1.8.0/CHANGELOG.md) for all of the updates. ### Supported Operating Systems for Debugging diff --git a/csharp.configuration.json b/csharp.configuration.json deleted file mode 100644 index 8707c381f6..0000000000 --- a/csharp.configuration.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "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 802ee1dad9..5841129fde 100644 --- a/debugger.md +++ b/debugger.md @@ -27,9 +27,9 @@ Install the .NET Core command line tools (CLI) by following the installation par **OSX:** .NET Core requires openSSL to work. Don't forget this! Execute: `brew install openssl` ##### 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. +Open the command palette in VS Code (press 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 a recent version. 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 (press 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. @@ -39,7 +39,7 @@ The first time that C# code is opened in VS Code, the extension will download th The following steps have to executed for every project. ##### 1: Get a project -You can start from scratch by creating an empty project with `dotnet new`: +You can start from scratch by creating an empty project with `dotnet new`. Begin by opening the terminal in Visual Studio Code (`View->Integrated Terminal`) and type these commands: cd ~ mkdir MyApplication @@ -47,13 +47,13 @@ You can start from scratch by creating an empty project with `dotnet new`: dotnet new dotnet restore -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. +If you want a web project (ASP.NET project) use `dotnet new -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. +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. ##### 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. +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`. * Tasks.json is used to configure what command line command is executed to build your project, and launch.json configures the type of debugger you want to use, and what program should be run under that debugger. * Launch.json configures VS Code to run the build task from tasks.json so that your program is automatically up-to-date each time you go to debug it. @@ -62,15 +62,15 @@ If you open the folder containing your project.json, the C# extension can automa ![Info: Required assets to build and debug are missing from your project. Add them? Yes | Close](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/info-bar-add-required-assets.png) -Clicking 'Yes' on this prompt should add these resources. +Clicking `Yes` on this prompt should add these resources. **Creating configuration files manually** If your code has multiple projects or you would rather generate these files by hand, here is how -- -**.vscode/tasks.json**: Start with [this example](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/ExampleCode/tasks.json) which configures VS Code to launch 'dotnet build'. Update the 'cwd' property if your project isn't in the root of the open folder. If you don't want to build from VS Code at all, you can skip this file. If you do this, you will need to comment out the 'preLaunchTask' from .vscode/launch.json when you create it. +**.vscode/tasks.json**: Start with [this example](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/ExampleCode/tasks.json) which configures VS Code to launch `dotnet build`. Update the `cwd` property if your project isn't in the root of the open folder. If you don't want to build from VS Code at all, you can skip this file. If you do this, you will need to comment out the `preLaunchTask` from .vscode/launch.json when you create it. -**.vscode/launch.json**: When you want to start debugging, press the debugger play button (or hit F5) as you would normally do. VS Code will provide a list of templates to select from. Pick ".NET Core" from this list and the edit the 'program' property to indicate the path to the application dll or .NET Core host executable to launch. For example: +**.vscode/launch.json**: When you want to start debugging, press the debugger play button (or press F5) as you would normally do. VS Code will provide a list of templates to select from. Pick ".NET Core" from this list and the edit the `program` property to indicate the path to the application dll or .NET Core host executable to launch. For example: "configurations": [ { @@ -78,14 +78,14 @@ 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: 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. +Your project is now all set. Set a breakpoint or two where you want to stop, click the debugger play button (or press F5) and you are off. ###Debugging Code compiled on another computer 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. +* **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 @@ -117,10 +117,14 @@ Environment variables may be passed to your program using this schema: "myVariableName":"theValueGoesHere" } -#####External console (terminal) window -The target process can optionally launch into a separate console window. You will want this if your console app takes console input (ex: Console.ReadLine). This can be enabled with: +#####Console (terminal) window +By default, processes are launched with their console output (stdout/stderr) going to the VS Code Debugger Console. This is useful for executables that take their input from the network, files, etc. But this does NOT work for applications that want to read from the console (ex: `Console.ReadLine`). For these applications, use a setting such as the following: - "externalConsole": true + "console": "integratedTerminal" + +When this is set to `integratedTerminal` the target process will run inside [VS Code's integrated terminal](https://code.visualstudio.com/docs/editor/integrated-terminal). Click the 'Terminal' tab in the tab group beneath the editor to interact with your application. + +When this is set to `externalTerminal` the target process will run in a separate terminal. ##### Stepping into properties and operators The debugger steps over properties and operators in managed code by default. In most cases, this provides a better debugging experience. To change this and enable stepping into properties or operators add: @@ -132,12 +136,8 @@ The C# debugger supports attaching to processes. To do this, switch to the Debug ![Debug launch configuration drop down](https://raw.githubusercontent.com/wiki/OmniSharp/omnisharp-vscode/images/debug-launch-configurations.png) -Select the '.NET Core Attach' configuration. Clicking the play button (or pressing F5) will then try to attach. In launch.json, if `processId` is set to `"${command.pickProcess}"` this will provide UI to select which process to attach to. - -#### Docker Support - -Using Visual Studio Code and the C# extension it is also possible to debug your code running in a [Docker container](https://en.wikipedia.org/wiki/Docker_(software)). To do so, follow instructions to install and run [yo docker](https://github.com/Microsoft/generator-docker#generator-docker). This will add files to your project to build a container, and it will add a new debug launch configuration which will invoke a container build, and then debug your app in the container. +Select the '.NET Core Attach' configuration. Clicking the play button (or pressing F5) will then try to attach. In launch.json, if `processId` is set to `"${command:pickProcess}"` this will provide UI to select which process to attach to. #### Remote Debugging -In addition to Docker, it is also possible to setup the debugger to remotely attach or launch using other transports (ex: SSH). See [Attaching to remote processes](https://github.com/OmniSharp/omnisharp-vscode/wiki/Attaching-to-remote-processes) in the wiki for more information. +The debugger supports remotely launching or attaching to processes. See [Attaching to remote processes](https://github.com/OmniSharp/omnisharp-vscode/wiki/Attaching-to-remote-processes) in the wiki for more information. diff --git a/package.json b/package.json index c421b07a88..f5f802bac7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.7.0", + "version": "1.8.0-beta3", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", @@ -33,9 +33,11 @@ "fs-extra": "^1.0.0", "http-proxy-agent": "^1.0.0", "https-proxy-agent": "^1.0.0", + "jsonc-parser": "^0.3.0", "lodash.debounce": "^4.0.8", "mkdirp": "^0.5.1", "open": "*", + "request-light": "^0.2.0", "semver": "*", "tmp": "0.0.28", "vscode-debugprotocol": "^1.6.1", @@ -61,7 +63,7 @@ "tslint-microsoft-contrib": "^2.0.12", "typescript": "^2.0.3", "vsce": "^1.7.0", - "vscode": "^1.0.0" + "vscode": "^1.0.3" }, "runtimeDependencies": [ { @@ -117,7 +119,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.9-beta25.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.11.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -128,7 +130,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.9-beta25.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.11.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -139,7 +141,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.9-beta25.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.11.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", @@ -148,8 +150,8 @@ }, { "description": ".NET Core Debugger (Windows / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "win7-x64" @@ -157,150 +159,150 @@ }, { "description": ".NET Core Debugger (macOS / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-osx.10.11-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-osx.10.11-x64.zip", "installPath": ".debugger", "runtimeIds": [ "osx.10.11-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (CentOS / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-centos.7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-centos.7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "centos.7-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Debian / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-debian.8-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-debian.8-x64.zip", "installPath": ".debugger", "runtimeIds": [ "debian.8-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Fedora 23 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-fedora.23-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-fedora.23-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.23-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Fedora 24 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-fedora.24-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-fedora.24-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.24-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (OpenSUSE 13 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-opensuse.13.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-opensuse.13.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.13.2-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (OpenSUSE 42 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-opensuse.42.1-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-opensuse.42.1-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.42.1-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (RHEL / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-rhel.7.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-rhel.7.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "rhel.7-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Ubuntu 14.04 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.14.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.14.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.14.04-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Ubuntu 16.04 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.16.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.16.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.04-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] }, { "description": ".NET Core Debugger (Ubuntu 16.10 / x64)", - "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", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.16.10-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-8-3/coreclr-debug-ubuntu.16.10-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.10-x64" ], "binaries": [ - "./OpenDebugAD7", - "./clrdbg" + "./vsdbg-ui", + "./vsdbg" ] } ], "engines": { - "vscode": "^1.5.0" + "vscode": "^1.10.1" }, "activationEvents": [ "onLanguage:csharp", @@ -314,20 +316,6 @@ "workspaceContains:project.json" ], "contributes": { - "languages": [ - { - "id": "csharp", - "extensions": [ - ".cs", - ".csx" - ], - "aliases": [ - "C#", - "csharp" - ], - "configuration": "./csharp.configuration.json" - } - ], "configuration": { "title": "C# configuration", "properties": { @@ -389,13 +377,6 @@ } } }, - "grammars": [ - { - "language": "csharp", - "scopeName": "source.cs", - "path": "./syntaxes/csharp.tmLanguage" - } - ], "jsonValidation": [ { "fileMatch": "project.json", @@ -616,9 +597,24 @@ "description": "Environment variables passed to the program.", "default": {} }, + "console": { + "type": "string", + "enum": [ + "internalConsole", + "integratedTerminal", + "externalTerminal" + ], + "enumDescriptions": [ + "Output to the VS Code Debug Console. This doesn't support reading console input (ex:Console.ReadLine)", + "VS Code's integrated terminal", + "External terminal that can be configured via user settings" + ], + "description": "Where to launch the debug target.", + "default": "internalConsole" + }, "externalConsole": { "type": "boolean", - "description": "If 'true' the debugger should launch the target application into a new external console.", + "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", "default": false }, "sourceFileMap": { @@ -680,26 +676,24 @@ "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", "default": false }, - "trace": { + "browserStdOut": { "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the output window.", - "default": false - }, - "traceResponse": { - "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the output window.", - "default": false + "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", + "default": true } } }, "pipeTransport": { - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg).", + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg).", "type": "object", + "required": [ + "debuggerPath" + ], "default": { "pipeCwd": "${workspaceRoot}", "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", "pipeArgs": [], - "debuggerPath": "enter the path for the debugger on the target machine, for example ~/clrdbg/clrdbg" + "debuggerPath": "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" }, "properties": { "pipeCwd": { @@ -723,7 +717,7 @@ "debuggerPath": { "type": "string", "description": "The full path to the debugger on the target machine.", - "default": "enter the path for the debugger on the target machine, for example ~/clrdbg/clrdbg" + "default": "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" }, "pipeEnv": { "type": "object", @@ -861,12 +855,12 @@ "anyOf": [ { "type": "string", - "description": "The process id to attach to. Use \"${command.pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", - "default": "${command.pickProcess}" + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "default": "${command:pickProcess}" }, { "type": "integer", - "description": "The process id to attach to. Use \"${command.pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", "default": 0 } ] @@ -930,26 +924,24 @@ "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", "default": false }, - "trace": { + "browserStdOut": { "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the output window.", - "default": false - }, - "traceResponse": { - "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the output window.", - "default": false + "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", + "default": true } } }, "pipeTransport": { - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg).", + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg).", "type": "object", + "required": [ + "debuggerPath" + ], "default": { "pipeCwd": "${workspaceRoot}", "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", "pipeArgs": [], - "debuggerPath": "enter the path for the debugger on the target machine, for example ~/clrdbg/clrdbg" + "debuggerPath": "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" }, "properties": { "pipeCwd": { @@ -973,7 +965,7 @@ "debuggerPath": { "type": "string", "description": "The full path to the debugger on the target machine.", - "default": "enter the path for the debugger on the target machine, for example ~/clrdbg/clrdbg" + "default": "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" }, "pipeEnv": { "type": "object", @@ -1109,7 +1101,7 @@ "args": [], "cwd": "${workspaceRoot}", "stopAtEntry": false, - "externalConsole": false + "console": "internalConsole" }, { "name": ".NET Core Launch (web)", @@ -1145,7 +1137,7 @@ "name": ".NET Core Attach", "type": "coreclr", "request": "attach", - "processId": "${command.pickProcess}" + "processId": "${command:pickProcess}" } ] } diff --git a/src/assets.ts b/src/assets.ts index fc84f874b3..e3beb5b88a 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -27,7 +27,7 @@ interface ConsoleLaunchConfiguration extends DebugConfiguration { cwd: string; stopAtEntry: boolean; env?: any; - externalConsole?: boolean; + console?: string; } interface CommandLine { @@ -179,6 +179,21 @@ export class AssetGenerator { return result; } + private computeWorkingDirectory() : string { + if (!this.hasProject) { + // If there's no target project data, use a placeholder for the path. + return '${workspaceRoot}'; + } + + let result = '${workspaceRoot}'; + + if (this.projectPath) { + result = path.join(result, path.relative(this.rootPath, this.projectPath)); + } + + return result; + } + private createLaunchConfiguration(): ConsoleLaunchConfiguration { return { name: '.NET Core Launch (console)', @@ -187,8 +202,8 @@ export class AssetGenerator { preLaunchTask: 'build', program: this.computeProgramPath(), args: [], - cwd: '${workspaceRoot}', - externalConsole: false, + cwd: this.computeWorkingDirectory(), + console: "internalConsole", stopAtEntry: false, internalConsoleOptions: "openOnSessionStart" }; @@ -202,7 +217,7 @@ export class AssetGenerator { preLaunchTask: 'build', program: this.computeProgramPath(), args: [], - cwd: '${workspaceRoot}', + cwd: this.computeWorkingDirectory(), stopAtEntry: false, internalConsoleOptions: "openOnSessionStart", launchBrowser: { @@ -233,7 +248,7 @@ export class AssetGenerator { name: '.NET Core Attach', type: 'coreclr', request: 'attach', - processId: "${command.pickProcess}" + processId: "${command:pickProcess}" }; } diff --git a/src/coreclr-debug/activate.ts b/src/coreclr-debug/activate.ts index bbf5e2fd6d..e897330ba2 100644 --- a/src/coreclr-debug/activate.ts +++ b/src/coreclr-debug/activate.ts @@ -98,10 +98,18 @@ function showDotnetToolsWarning(message: string) : void goToSettingsMessage, getDotNetMessage).then(value => { if (value === getDotNetMessage) { let open = require('open'); - open('https://www.microsoft.com/net/core'); + let dotnetcoreURL = 'https://www.microsoft.com/net/core'; + + // Windows redirects https://www.microsoft.com/net/core to https://www.microsoft.com/net/core#windowsvs2015 + if (process.platform == "win32") + { + dotnetcoreURL = dotnetcoreURL + '#windowscmd'; + } + + open(dotnetcoreURL); } else if (value === goToSettingsMessage) { vscode.commands.executeCommand('workbench.action.openGlobalSettings'); } }); } -} \ No newline at end of file +} diff --git a/src/coreclr-debug/install.ts b/src/coreclr-debug/install.ts index a20c77c085..494f932283 100644 --- a/src/coreclr-debug/install.ts +++ b/src/coreclr-debug/install.ts @@ -73,7 +73,7 @@ export class DebugInstaller { delete manifestObject.contributes.debuggers[0].runtime; delete manifestObject.contributes.debuggers[0].program; - let programString = './.debugger/OpenDebugAD7'; + let programString = './.debugger/vsdbg-ui'; manifestObject.contributes.debuggers[0].windows = { program: programString + '.exe' }; manifestObject.contributes.debuggers[0].osx = { program: programString }; manifestObject.contributes.debuggers[0].linux = { program: programString }; diff --git a/src/coreclr-debug/proxy.ts b/src/coreclr-debug/proxy.ts index 9bc143a0ff..7893c1ca52 100644 --- a/src/coreclr-debug/proxy.ts +++ b/src/coreclr-debug/proxy.ts @@ -50,7 +50,7 @@ function sendDownloadingNotStartedMessage() { // When installation of the debugger components finishes, the extension manifest is rewritten so that this proxy is no longer called // If the debugger components have not finished downloading, the proxy displays an error message to the user // If the debugger components have finished downloading, the manifest has been rewritten but has not been reloaded. -// This proxy will still be called and launch OpenDebugAD7 as a child process. +// This proxy will still be called and launch vsdbg-ui as a child process. // During subsequent code sessions, the rewritten manifest will be loaded and this proxy will no longer be called. function proxy() { let extensionPath = path.resolve(__dirname, '../../../'); @@ -107,11 +107,11 @@ function proxy() { // debugger has finished install and manifest has been rewritten, kick off our debugger process new Promise((resolve, reject) => { - let processPath = path.join(util.debugAdapterDir(), "OpenDebugAD7" + CoreClrDebugUtil.getPlatformExeExtension()); + let processPath = path.join(util.debugAdapterDir(), "vsdbg-ui" + CoreClrDebugUtil.getPlatformExeExtension()); let args = process.argv.slice(2); // do not explicitly set a current working dir - // this seems to match what code does when OpenDebugAD7 is launched directly from the manifest + // this seems to match what code does when vsdbg-ui is launched directly from the manifest const child = child_process.spawn(processPath, args); // If we don't exit cleanly from the child process, log the error. diff --git a/src/features/implementationProvider.ts b/src/features/implementationProvider.ts new file mode 100644 index 0000000000..75c1261acd --- /dev/null +++ b/src/features/implementationProvider.ts @@ -0,0 +1,26 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import AbstractSupport from './abstractProvider'; +import { FindImplementationsRequest } from '../omnisharp/protocol'; +import * as serverUtils from '../omnisharp/utils'; +import { createRequest, toLocation } from '../omnisharp/typeConvertion'; +import { TextDocument, Position, CancellationToken, ImplementationProvider, ProviderResult, Definition } from 'vscode'; + +export default class CSharpImplementationProvider extends AbstractSupport implements ImplementationProvider { + public provideImplementation(document: TextDocument, position: Position, token: CancellationToken): ProviderResult { + const request = createRequest(document, position); + + return serverUtils.findImplementations(this._server, request, token).then(response => { + if (!response || !response.QuickFixes) { + return; + } + + return response.QuickFixes.map(fix => toLocation(fix)); + }); + } +} diff --git a/src/features/json/jsonContributions.ts b/src/features/json/jsonContributions.ts new file mode 100644 index 0000000000..055549c761 --- /dev/null +++ b/src/features/json/jsonContributions.ts @@ -0,0 +1,164 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { Location, getLocation, createScanner, SyntaxKind } from 'jsonc-parser'; +import { ProjectJSONContribution } from './projectJSONContribution'; +import { configure as configureXHR, xhr } from 'request-light'; + +import { + CompletionItem, CompletionItemProvider, CompletionList, TextDocument, Position, Hover, HoverProvider, + CancellationToken, Range, TextEdit, MarkedString, DocumentSelector, languages, workspace, Disposable +} from 'vscode'; + +export interface ISuggestionsCollector { + add(suggestion: CompletionItem): void; + error(message: string): void; + log(message: string): void; + setAsIncomplete(): void; +} + +export interface IJSONContribution { + getDocumentSelector(): DocumentSelector; + getInfoContribution(fileName: string, location: Location): Thenable; + collectPropertySuggestions(fileName: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable; + collectValueSuggestions(fileName: string, location: Location, result: ISuggestionsCollector): Thenable; + collectDefaultSuggestions(fileName: string, result: ISuggestionsCollector): Thenable; + resolveSuggestion?(item: CompletionItem): Thenable; +} + +export function addJSONProviders(): Disposable { + let subscriptions: Disposable[] = []; + + // configure the XHR library with the latest proxy settings + function configureHttpRequest() { + let httpSettings = workspace.getConfiguration('http'); + configureXHR(httpSettings.get('proxy'), httpSettings.get('proxyStrictSSL')); + } + + configureHttpRequest(); + subscriptions.push(workspace.onDidChangeConfiguration(e => configureHttpRequest())); + + // register completion and hove providers for JSON setting file(s) + let contributions = [new ProjectJSONContribution(xhr)]; + contributions.forEach(contribution => { + let selector = contribution.getDocumentSelector(); + subscriptions.push(languages.registerCompletionItemProvider(selector, new JSONCompletionItemProvider(contribution))); + subscriptions.push(languages.registerHoverProvider(selector, new JSONHoverProvider(contribution))); + }); + + return Disposable.from(...subscriptions); +} + +export class JSONHoverProvider implements HoverProvider { + + constructor(private jsonContribution: IJSONContribution) { + } + + public provideHover(document: TextDocument, position: Position, token: CancellationToken): Thenable { + let offset = document.offsetAt(position); + let location = getLocation(document.getText(), offset); + let node = location.previousNode; + if (node && node.offset <= offset && offset <= node.offset + node.length) { + let promise = this.jsonContribution.getInfoContribution(document.fileName, location); + if (promise) { + return promise.then(htmlContent => { + let range = new Range(document.positionAt(node.offset), document.positionAt(node.offset + node.length)); + let result: Hover = { + contents: htmlContent, + range: range + }; + return result; + }); + } + } + return null; + } +} + +export class JSONCompletionItemProvider implements CompletionItemProvider { + + constructor(private jsonContribution: IJSONContribution) { + } + + public resolveCompletionItem(item: CompletionItem, token: CancellationToken): Thenable { + if (this.jsonContribution.resolveSuggestion) { + let resolver = this.jsonContribution.resolveSuggestion(item); + if (resolver) { + return resolver; + } + } + return Promise.resolve(item); + } + + public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): Thenable { + let currentWord = this.getCurrentWord(document, position); + let overwriteRange = null; + let items: CompletionItem[] = []; + let isIncomplete = false; + + let offset = document.offsetAt(position); + let location = getLocation(document.getText(), offset); + + let node = location.previousNode; + if (node && node.offset <= offset && offset <= node.offset + node.length && (node.type === 'property' || node.type === 'string' || node.type === 'number' || node.type === 'boolean' || node.type === 'null')) { + overwriteRange = new Range(document.positionAt(node.offset), document.positionAt(node.offset + node.length)); + } else { + overwriteRange = new Range(document.positionAt(offset - currentWord.length), position); + } + + let proposed: { [key: string]: boolean } = {}; + let collector: ISuggestionsCollector = { + add: (suggestion: CompletionItem) => { + if (!proposed[suggestion.label]) { + proposed[suggestion.label] = true; + if (overwriteRange) { + suggestion.textEdit = TextEdit.replace(overwriteRange, suggestion.insertText); + } + + items.push(suggestion); + } + }, + setAsIncomplete: () => isIncomplete = true, + error: (message: string) => console.error(message), + log: (message: string) => console.log(message) + }; + + let collectPromise: Thenable = null; + + if (location.isAtPropertyKey) { + let addValue = !location.previousNode || !location.previousNode.columnOffset && (offset == (location.previousNode.offset + location.previousNode.length)); + let scanner = createScanner(document.getText(), true); + scanner.setPosition(offset); + scanner.scan(); + let isLast = scanner.getToken() === SyntaxKind.CloseBraceToken || scanner.getToken() === SyntaxKind.EOF; + collectPromise = this.jsonContribution.collectPropertySuggestions(document.fileName, location, currentWord, addValue, isLast, collector); + } else { + if (location.path.length === 0) { + collectPromise = this.jsonContribution.collectDefaultSuggestions(document.fileName, collector); + } else { + collectPromise = this.jsonContribution.collectValueSuggestions(document.fileName, location, collector); + } + } + if (collectPromise) { + return collectPromise.then(() => { + if (items.length > 0) { + return new CompletionList(items, isIncomplete); + } + return null; + }); + } + return null; + } + + private getCurrentWord(document: TextDocument, position: Position) { + let i = position.character - 1; + let text = document.lineAt(position.line).text; + while (i >= 0 && ' \t\n\r\v":{[,'.indexOf(text.charAt(i)) === -1) { + i--; + } + return text.substring(i + 1, position.character); + } +} \ No newline at end of file diff --git a/src/features/json/projectJSONContribution.ts b/src/features/json/projectJSONContribution.ts new file mode 100644 index 0000000000..5d69bbcb41 --- /dev/null +++ b/src/features/json/projectJSONContribution.ts @@ -0,0 +1,235 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +'use strict'; + +import { MarkedString, CompletionItemKind, CompletionItem, DocumentSelector } from 'vscode'; +import { XHRRequest, XHRResponse, getErrorStatusDescription } from 'request-light'; +import { IJSONContribution, ISuggestionsCollector } from './jsonContributions'; +import { Location } from 'jsonc-parser'; + +import * as nls from 'vscode-nls'; +const localize = nls.loadMessageBundle(); + +const FEED_INDEX_URL = 'https://api.nuget.org/v3/index.json'; +const LIMIT = 30; + +interface NugetServices { + 'SearchQueryService'?: string; + 'SearchAutocompleteService'?: string; + 'PackageBaseAddress/3.0.0'?: string; + [key: string]: string; +} + +export class ProjectJSONContribution implements IJSONContribution { + + private nugetIndexPromise: Thenable; + + public constructor(private requestService: XHRRequest) { + } + + public getDocumentSelector(): DocumentSelector { + return [{ language: 'json', pattern: '**/project.json' }]; + } + + private getNugetIndex(): Thenable { + if (!this.nugetIndexPromise) { + this.nugetIndexPromise = this.makeJSONRequest(FEED_INDEX_URL).then(indexContent => { + let services: NugetServices = {}; + if (indexContent && Array.isArray(indexContent.resources)) { + let resources = indexContent.resources; + for (let i = resources.length - 1; i >= 0; i--) { + let type = resources[i]['@type']; + let id = resources[i]['@id']; + if (type && id) { + services[type] = id; + } + } + } + return services; + }); + } + return this.nugetIndexPromise; + } + + private getNugetService(serviceType: string): Thenable { + return this.getNugetIndex().then(services => { + let serviceURL = services[serviceType]; + if (!serviceURL) { + return Promise.reject(localize('json.nugget.error.missingservice', 'NuGet index document is missing service {0}', serviceType)); + } + return serviceURL; + }); + } + + private makeJSONRequest(url: string): Thenable { + return this.requestService({ + url: url + }).then(success => { + if (success.status === 200) { + try { + return JSON.parse(success.responseText); + } catch (e) { + return Promise.reject(localize('json.nugget.error.invalidformat', '{0} is not a valid JSON document', url)); + } + } + return Promise.reject(localize('json.nugget.error.indexaccess', 'Request to {0} failed: {1}', url, success.responseText)); + }, (error: XHRResponse) => { + return Promise.reject(localize('json.nugget.error.access', 'Request to {0} failed: {1}', url, getErrorStatusDescription(error.status))); + }); + } + + public collectPropertySuggestions(resource: string, location: Location, currentWord: string, addValue: boolean, isLast: boolean, result: ISuggestionsCollector): Thenable { + if ((location.matches(['dependencies']) || location.matches(['frameworks', '*', 'dependencies']) || location.matches(['frameworks', '*', 'frameworkAssemblies']))) { + + return this.getNugetService('SearchAutocompleteService').then(service => { + let queryUrl: string; + if (currentWord.length > 0) { + queryUrl = service + '?q=' + encodeURIComponent(currentWord) + '&take=' + LIMIT; + } else { + queryUrl = service + '?take=' + LIMIT; + } + return this.makeJSONRequest(queryUrl).then(resultObj => { + if (Array.isArray(resultObj.data)) { + let results = resultObj.data; + for (let i = 0; i < results.length; i++) { + let name = results[i]; + let insertText = JSON.stringify(name); + if (addValue) { + insertText += ': "{{}}"'; + if (!isLast) { + insertText += ','; + } + } + let proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Property; + proposal.insertText = insertText; + result.add(proposal); + } + if (results.length === LIMIT) { + result.setAsIncomplete(); + } + } + }, error => { + result.error(error); + }); + }, error => { + result.error(error); + }); + }; + return null; + } + + public collectValueSuggestions(resource: string, location: Location, result: ISuggestionsCollector): Thenable { + if ((location.matches(['dependencies', '*']) || location.matches(['frameworks', '*', 'dependencies', '*']) || location.matches(['frameworks', '*', 'frameworkAssemblies', '*']))) { + return this.getNugetService('PackageBaseAddress/3.0.0').then(service => { + let currentKey = location.path[location.path.length - 1]; + if (typeof currentKey === 'string') { + let queryUrl = service + currentKey + '/index.json'; + return this.makeJSONRequest(queryUrl).then(obj => { + if (Array.isArray(obj.versions)) { + let results = obj.versions; + for (let i = 0; i < results.length; i++) { + let curr = results[i]; + let name = JSON.stringify(curr); + let proposal = new CompletionItem(name); + proposal.kind = CompletionItemKind.Class; + proposal.insertText = name; + proposal.documentation = ''; + result.add(proposal); + } + if (results.length === LIMIT) { + result.setAsIncomplete(); + } + } + }, error => { + result.error(error); + }); + } + }, error => { + result.error(error); + }); + } + return null; + } + + public collectDefaultSuggestions(resource: string, result: ISuggestionsCollector): Thenable { + let defaultValue = { + 'version': '{{1.0.0-*}}', + 'dependencies': {}, + 'frameworks': { + 'dnx451': {}, + 'dnxcore50': {} + } + }; + let proposal = new CompletionItem(localize('json.project.default', 'Default project.json')); + proposal.kind = CompletionItemKind.Module; + proposal.insertText = JSON.stringify(defaultValue, null, '\t'); + result.add(proposal); + return null; + } + + public resolveSuggestion(item: CompletionItem): Thenable { + if (item.kind === CompletionItemKind.Property) { + let pack = item.label; + return this.getInfo(pack).then(info => { + if (info.description) { + item.documentation = info.description; + } + if (info.version) { + item.detail = info.version; + item.insertText = (item.insertText).replace(/\{\{\}\}/, '{{' + info.version + '}}'); + } + return item; + }); + } + return null; + } + + private getInfo(pack: string): Thenable<{ description?: string; version?: string }> { + return this.getNugetService('SearchQueryService').then(service => { + let queryUrl = service + '?q=' + encodeURIComponent(pack) + '&take=' + 5; + return this.makeJSONRequest(queryUrl).then(resultObj => { + if (Array.isArray(resultObj.data)) { + let results = resultObj.data; + let info: { description?: string; version?: string } = {}; + for (let i = 0; i < results.length; i++) { + let res = results[i]; + if (res.id === pack) { + info.description = res.description; + info.version = localize('json.nugget.version.hover', 'Latest version: {0}', res.version); + } + } + return info; + } + return null; + }, (error) => { + return null; + }); + }, (error) => { + return null; + }); + } + + + public getInfoContribution(resource: string, location: Location): Thenable { + if ((location.matches(['dependencies', '*']) || location.matches(['frameworks', '*', 'dependencies', '*']) || location.matches(['frameworks', '*', 'frameworkAssemblies', '*']))) { + let pack = location.path[location.path.length - 1]; + if (typeof pack === 'string') { + return this.getInfo(pack).then(info => { + let htmlContent: MarkedString[] = []; + htmlContent.push(localize('json.nugget.package.hover', '{0}', pack)); + if (info.description) { + htmlContent.push(info.description); + } + if (info.version) { + htmlContent.push(info.version); + } + return htmlContent; + }); + } + } + return null; + } +} \ No newline at end of file diff --git a/src/features/status.ts b/src/features/status.ts index 718a31dc22..6f072b9908 100644 --- a/src/features/status.ts +++ b/src/features/status.ts @@ -26,7 +26,8 @@ let defaultSelector: vscode.DocumentSelector = [ 'csharp', // c#-files OR { pattern: '**/project.json' }, // project.json-files OR { pattern: '**/*.sln' }, // any solution file OR - { pattern: '**/*.csproj' } // an csproj file + { pattern: '**/*.csproj' }, // an csproj file + { pattern: '**/*.csx' } // C# script ]; class Status { diff --git a/src/main.ts b/src/main.ts index e7c6fd093a..5d67777820 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import * as util from './common'; import { Logger } from './logger'; import { PackageManager, Status, PackageError } from './packages'; import { PlatformInformation } from './platform'; +import { addJSONProviders } from './features/json/jsonContributions'; let _channel: vscode.OutputChannel = null; @@ -34,6 +35,9 @@ export function activate(context: vscode.ExtensionContext): any { // activate language services OmniSharp.activate(context, reporter); + // register JSON completion & hover providers for project.json + context.subscriptions.push(addJSONProviders()); + // activate coreclr-debug coreclrdebug.activate(context, reporter, logger, _channel); }); @@ -129,7 +133,7 @@ function installRuntimeDependencies(extension: vscode.Extension, logger: Lo } if (error.pkg) { - telemetryProps['error.packageUrl'] = error.pkg.url; + telemetryProps['error.packageUrl'] = error.pkg.url; } } else { @@ -145,7 +149,7 @@ function installRuntimeDependencies(extension: vscode.Extension, logger: Lo telemetryProps['platform.architecture'] = platformInfo.architecture; telemetryProps['platform.platform'] = platformInfo.platform; telemetryProps['platform.runtimeId'] = platformInfo.runtimeId; - if (platformInfo.distribution) { + if (platformInfo.distribution) { telemetryProps['platform.distribution'] = platformInfo.distribution.toString(); } diff --git a/src/omnisharp/extension.ts b/src/omnisharp/extension.ts index 3c2deb33a2..7bd76385fb 100644 --- a/src/omnisharp/extension.ts +++ b/src/omnisharp/extension.ts @@ -7,6 +7,7 @@ import * as vscode from 'vscode'; import TelemetryReporter from 'vscode-extension-telemetry'; import DefinitionProvider from '../features/definitionProvider'; +import ImplementationProvider from '../features/implementationProvider'; import CodeLensProvider from '../features/codeLensProvider'; import DefinitionMetadataDocumentProvider from '../features/definitionMetadataDocumentProvider'; import DocumentHighlightProvider from '../features/documentHighlightProvider'; @@ -47,6 +48,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe localDisposables.push(definitionMetadataDocumentProvider); localDisposables.push(vscode.languages.registerDefinitionProvider(documentSelector, new DefinitionProvider(server, definitionMetadataDocumentProvider))); + localDisposables.push(vscode.languages.registerImplementationProvider(documentSelector, new ImplementationProvider(server))); localDisposables.push(vscode.languages.registerCodeLensProvider(documentSelector, new CodeLensProvider(server))); localDisposables.push(vscode.languages.registerDocumentHighlightProvider(documentSelector, new DocumentHighlightProvider(server))); localDisposables.push(vscode.languages.registerDocumentSymbolProvider(documentSelector, new DocumentSymbolProvider(server))); diff --git a/src/omnisharp/launcher.ts b/src/omnisharp/launcher.ts index e1bebc9747..670299bd98 100644 --- a/src/omnisharp/launcher.ts +++ b/src/omnisharp/launcher.ts @@ -16,7 +16,8 @@ import { Options } from './options'; export enum LaunchTargetKind { Solution, ProjectJson, - Folder + Folder, + Csx } /** @@ -44,7 +45,7 @@ export function findLaunchTargets(): Thenable { const options = Options.Read(); return vscode.workspace.findFiles( - /*include*/ '{**/*.sln,**/*.csproj,**/project.json}', + /*include*/ '{**/*.sln,**/*.csproj,**/project.json,**/*.csx}', /*exclude*/ '{**/node_modules/**,**/.git/**,**/bower_components/**}', /*maxResults*/ options.maxProjectResults) .then(resources => { @@ -72,7 +73,8 @@ function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] { hasCsProjFiles = false, hasSlnFile = false, hasProjectJson = false, - hasProjectJsonAtRoot = false; + hasProjectJsonAtRoot = false, + hasCSX = false; hasCsProjFiles = resources.some(isCSharpProject); @@ -104,6 +106,11 @@ function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] { kind: LaunchTargetKind.ProjectJson }); } + + // Discover if there is any CSX file + if (!hasCSX && isCsx(resource)) { + hasCSX = true; + } }); // Add the root folder under the following circumstances: @@ -119,6 +126,17 @@ function select(resources: vscode.Uri[], rootPath: string): LaunchTarget[] { }); } + // if we noticed any CSX file(s), add a single CSX-specific target pointing at the root folder + if (hasCSX) { + targets.push({ + label: "CSX", + description: path.basename(rootPath), + target: rootPath, + directory: rootPath, + kind: LaunchTargetKind.Csx + }); + } + return targets.sort((a, b) => a.directory.localeCompare(b.directory)); } @@ -134,6 +152,10 @@ function isProjectJson(resource: vscode.Uri): boolean { return /\project.json$/i.test(resource.fsPath); } +function isCsx(resource: vscode.Uri): boolean { + return /\.csx$/i.test(resource.fsPath); +} + export interface LaunchResult { process: ChildProcess; command: string; diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 4fb8865bfd..0e33cfe64c 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -21,6 +21,7 @@ export module Requests { export const FormatRange = '/formatRange'; export const GetCodeActions = '/getcodeactions'; export const GoToDefinition = '/gotoDefinition'; + export const FindImplementations = '/findimplementations'; export const Projects = '/projects'; export const RemoveFromProject = '/removefromproject'; export const Rename = '/rename'; @@ -70,6 +71,10 @@ export interface GoToDefinitionRequest extends Request WantMetadata?: boolean; } +export interface FindImplementationsRequest extends Request +{ +} + export interface LinePositionSpanTextChange { NewText: string; StartLine: number; diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index 80174e7f42..e8c8f9f67f 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -350,11 +350,11 @@ export class OmniSharpServer { public autoStart(preferredPath: string): Thenable { return findLaunchTargets().then(launchTargets => { // If there aren't any potential launch targets, we create file watcher and try to - // start the server again once a *.sln, *.csproj or project.json file is created. + // start the server again once a *.sln, *.csproj, project.json or CSX file is created. if (launchTargets.length === 0) { return new Promise((resolve, reject) => { // 1st watch for files - let watcher = vscode.workspace.createFileSystemWatcher('{**/*.sln,**/*.csproj,**/project.json}', + let watcher = vscode.workspace.createFileSystemWatcher('{**/*.sln,**/*.csproj,**/project.json,**/*.csx}', /*ignoreCreateEvents*/ false, /*ignoreChangeEvents*/ true, /*ignoreDeleteEvents*/ true); diff --git a/src/omnisharp/typeConvertion.ts b/src/omnisharp/typeConvertion.ts index ea576cb93d..520afbd974 100644 --- a/src/omnisharp/typeConvertion.ts +++ b/src/omnisharp/typeConvertion.ts @@ -4,25 +4,35 @@ *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as proto from './protocol'; +import * as protocol from './protocol'; import * as vscode from 'vscode'; -export function toLocation(location: proto.ResourceLocation): vscode.Location { - let {FileName, Line, Column} = location; - return new vscode.Location(vscode.Uri.file(FileName), new vscode.Position(Line - 1, Column - 1)); +export function toLocation(location: protocol.ResourceLocation | protocol.QuickFix): vscode.Location { + const fileName = vscode.Uri.file(location.FileName); + const position = new vscode.Position(location.Line - 1, location.Column - 1); + + const endLine = (location).EndLine; + const endColumn = (location).EndColumn; + + if (endLine !== undefined && endColumn !== undefined) { + const endPosition = new vscode.Position(endLine - 1, endColumn - 1); + return new vscode.Location(fileName, new vscode.Range(position, endPosition)); + } + + return new vscode.Location(fileName, position); } -export function toRange(rangeLike: { Line: number; Column: number; EndLine: number; EndColumn: number;}): vscode.Range { +export function toRange(rangeLike: { Line: number; Column: number; EndLine: number; EndColumn: number; }): vscode.Range { let {Line, Column, EndLine, EndColumn} = rangeLike; return new vscode.Range(Line - 1, Column - 1, EndLine - 1, EndColumn - 1); } -export function toRange2(rangeLike: { StartLine: number; StartColumn: number; EndLine: number; EndColumn: number;}): vscode.Range { +export function toRange2(rangeLike: { StartLine: number; StartColumn: number; EndLine: number; EndColumn: number; }): vscode.Range { let {StartLine, StartColumn, EndLine, EndColumn} = rangeLike; return new vscode.Range(StartLine - 1, StartColumn - 1, EndLine - 1, EndColumn - 1); } -export function createRequest(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer: boolean = false): T { +export function createRequest(document: vscode.TextDocument, where: vscode.Position | vscode.Range, includeBuffer: boolean = false): T { let Line: number, Column: number; @@ -34,7 +44,7 @@ export function createRequest(document: vscode.TextDocu Column = where.start.character + 1; } - let request: proto.Request = { + let request: protocol.Request = { Filename: document.fileName, Buffer: includeBuffer ? document.getText() : undefined, Line, @@ -44,7 +54,7 @@ export function createRequest(document: vscode.TextDocu return request; } -export function toDocumentSymbol(bucket: vscode.SymbolInformation[], node: proto.Node, containerLabel?: string): void { +export function toDocumentSymbol(bucket: vscode.SymbolInformation[], node: protocol.Node, containerLabel?: string): void { let ret = new vscode.SymbolInformation(node.Location.Text, kinds[node.Kind], toRange(node.Location), diff --git a/src/omnisharp/utils.ts b/src/omnisharp/utils.ts index 9470154fba..3506ce7694 100644 --- a/src/omnisharp/utils.ts +++ b/src/omnisharp/utils.ts @@ -25,6 +25,10 @@ export function filesChanged(server: OmniSharpServer, requests: protocol.Request return server.makeRequest(protocol.Requests.FilesChanged, requests); } +export function findImplementations(server: OmniSharpServer, request: protocol.FindImplementationsRequest, token: vscode.CancellationToken) { + return server.makeRequest(protocol.Requests.FindImplementations, request); +} + export function findSymbols(server: OmniSharpServer, request: protocol.FindSymbolsRequest, token: vscode.CancellationToken) { return server.makeRequest(protocol.Requests.FindSymbols, request, token); } diff --git a/src/platform.ts b/src/platform.ts index f19289f1c1..d7a774bf48 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -266,6 +266,7 @@ export class PlatformInformation { switch (distributionName) { case 'Zorin OS': + case 'zorin': // ID changed in 12.1 if (distributionVersion === "12") { return ubuntu_16_04; } diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index 62f52c114a..68a8a3ed62 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -44,12 +44,13 @@ }, "PipeTransport": { "type": "object", - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg).", + "required": ["debuggerPath"], + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg).", "default": { "pipeCwd": "${workspaceRoot}", "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'", "pipeArgs": [], - "debuggerPath" : "enter the path for the debugger on the target machine, for example ~/clrdbg/clrdbg" + "debuggerPath" : "enter the path for the debugger on the target machine, for example ~/vsdbg/vsdbg" }, "properties": { "pipeCwd": { @@ -73,7 +74,7 @@ "debuggerPath" : { "type" : "string", "description" : "The full path to the debugger on the target machine.", - "default" : "~/clrdbg/clrdbg" + "default" : "~/vsdbg/vsdbg" }, "pipeEnv": { "type": "object", @@ -138,15 +139,10 @@ "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", "default": false }, - "trace": { + "browserStdOut": { "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command tracing should be logged to the output window.", - "default": false - }, - "traceResponse": { - "type": "boolean", - "description": "Optional flag to determine whether diagnostic adapter command and response tracing should be logged to the output window.", - "default": false + "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", + "default": true } } }, @@ -273,9 +269,20 @@ "description": "Environment variables passed to the program.", "default": {} }, + "console": { + "type": "string", + "enum": [ "internalConsole", "integratedTerminal", "externalTerminal" ], + "enumDescriptions": [ + "Output to the VS Code Debug Console. This doesn't support reading console input (ex:Console.ReadLine)", + "VS Code's integrated terminal", + "External terminal that can be configured via user settings" + ], + "description": "Where to launch the debug target.", + "default": "internalConsole" + }, "externalConsole": { "type": "boolean", - "description": "If 'true' the debugger should launch the target application into a new external console.", + "description": "Attribute 'externalConsole' is deprecated, use 'console' instead.", "default": false }, "sourceFileMap": { @@ -317,7 +324,7 @@ }, "pipeTransport": { "$ref": "#/definitions/PipeTransport", - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg)." + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." } } }, @@ -334,12 +341,12 @@ "anyOf": [ { "type": "string", - "description": "The process id to attach to. Use \"${command.pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", - "default": "${command.pickProcess}" + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "default": "${command:pickProcess}" }, { "type": "integer", - "description": "The process id to attach to. Use \"${command.pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", + "description": "The process id to attach to. Use \"${command:pickProcesss}\" to get a list of running processes to attach to. If 'processId' used, 'processName' should not be used.", "default": 0 } ] @@ -383,7 +390,7 @@ }, "pipeTransport": { "$ref": "#/definitions/PipeTransport", - "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg)." + "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (vsdbg)." } } } diff --git a/syntaxes/csharp.tmLanguage b/syntaxes/csharp.tmLanguage deleted file mode 100644 index 97bc5501ea..0000000000 --- a/syntaxes/csharp.tmLanguage +++ /dev/null @@ -1,6792 +0,0 @@ - - - - - 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