From dba15ac40c581c1a1f9d3fc8554939cbb950bb90 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Mon, 24 Apr 2017 17:12:14 -0700 Subject: [PATCH 01/31] Updating args schema to allow strings (#1419) * Updating args schema to allow strings Also including process picker tests. * Fixing PR issues * Fixing PR issues 2 * Removing splitting arguments * Updating blobs --- package.json | 444 +++++++++++++++++++++++++--------- src/common.ts | 56 +---- src/features/dotnetTest.ts | 4 +- src/features/processPicker.ts | 194 +++++++++------ src/tools/OptionsSchema.json | 81 +++++-- test/common.test.ts | 46 +--- test/processPicker.test.ts | 233 ++++++++++++++++++ 7 files changed, 742 insertions(+), 316 deletions(-) create mode 100644 test/processPicker.test.ts diff --git a/package.json b/package.json index 7b1da0a4ff..8874e61aad 100644 --- a/package.json +++ b/package.json @@ -157,8 +157,8 @@ }, { "description": ".NET Core Debugger (Windows / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-win7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-win7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "win7-x64" @@ -167,8 +167,8 @@ }, { "description": ".NET Core Debugger (macOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-osx.10.11-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-osx.10.11-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-osx.10.11-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-osx.10.11-x64.zip", "installPath": ".debugger", "runtimeIds": [ "osx.10.11-x64" @@ -181,8 +181,8 @@ }, { "description": ".NET Core Debugger (CentOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-centos.7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-centos.7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-centos.7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-centos.7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "centos.7-x64" @@ -195,8 +195,8 @@ }, { "description": ".NET Core Debugger (Debian / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-debian.8-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-debian.8-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-debian.8-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-debian.8-x64.zip", "installPath": ".debugger", "runtimeIds": [ "debian.8-x64" @@ -209,8 +209,8 @@ }, { "description": ".NET Core Debugger (Fedora 23 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-fedora.23-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-fedora.23-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-fedora.23-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-fedora.23-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.23-x64" @@ -223,8 +223,8 @@ }, { "description": ".NET Core Debugger (Fedora 24 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-fedora.24-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-fedora.24-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-fedora.24-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-fedora.24-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.24-x64" @@ -237,8 +237,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 13 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-opensuse.13.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-opensuse.13.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.13.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.13.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.13.2-x64" @@ -251,8 +251,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 42 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-opensuse.42.1-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-opensuse.42.1-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.42.1-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.42.1-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.42.1-x64" @@ -265,8 +265,8 @@ }, { "description": ".NET Core Debugger (RHEL / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-rhel.7.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-rhel.7.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-rhel.7.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-rhel.7.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "rhel.7-x64" @@ -279,8 +279,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 14.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.14.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.14.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.14.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.14.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.14.04-x64" @@ -293,8 +293,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.16.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.16.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.04-x64" @@ -307,8 +307,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.10 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.16.10-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-9-2/coreclr-debug-ubuntu.16.10-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.10-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.10-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.10-x64" @@ -529,12 +529,21 @@ "default": "${workspaceRoot}" }, "args": { - "type": "array", - "description": "Command line arguments passed to the program.", - "items": { - "type": "string" - }, - "default": [] + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ] }, "stopAtEntry": { "type": "boolean", @@ -565,8 +574,21 @@ "default": true }, "args": { - "type": "string", - "description": "The arguments to pass to the command to open the browser. Use ${auto-detect-url} to automatically use the address the server is listening to", + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ], "default": "${auto-detect-url}" }, "osx": { @@ -747,11 +769,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "debuggerPath": { @@ -792,11 +824,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -834,11 +876,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -876,11 +928,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1015,11 +1077,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "debuggerPath": { @@ -1060,11 +1132,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1102,11 +1184,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1144,11 +1236,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1355,12 +1457,21 @@ "default": "${workspaceRoot}" }, "args": { - "type": "array", - "description": "Command line arguments passed to the program.", - "items": { - "type": "string" - }, - "default": [] + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ] }, "stopAtEntry": { "type": "boolean", @@ -1391,8 +1502,21 @@ "default": true }, "args": { - "type": "string", - "description": "The arguments to pass to the command to open the browser. Use ${auto-detect-url} to automatically use the address the server is listening to", + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ], "default": "${auto-detect-url}" }, "osx": { @@ -1573,11 +1697,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "debuggerPath": { @@ -1618,11 +1752,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1660,11 +1804,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1702,11 +1856,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1841,11 +2005,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "debuggerPath": { @@ -1886,11 +2060,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1928,11 +2112,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { @@ -1970,11 +2164,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ], "default": [] }, "quoteArgs": { diff --git a/src/common.ts b/src/common.ts index 58b1ced8b4..b539099558 100644 --- a/src/common.ts +++ b/src/common.ts @@ -135,58 +135,4 @@ export function deleteInstallFile(type: InstallFileType): Promise { export function convertNativePathToPosix(pathString: string): string { let parts = pathString.split(path.sep); return parts.join(path.posix.sep); -} - -/** - * Splits a string of command line arguments into a string array. This function - * handles double-quoted arguments, but it is tailored toward the needs of the - * text returned by VSTest, and is not generally useful as a command line parser. - * @param commandLineString Text of command line arguments - */ -export function splitCommandLineArgs(commandLineString: string): string[] { - let result = []; - let start = -1; - let index = 0; - let inQuotes = false; - - while (index < commandLineString.length) { - let ch = commandLineString[index]; - - // Are we starting a new word? - if (start === -1 && ch !== ' ' && ch !== '"') { - start = index; - } - - // is next character quote? - if (ch === '"') { - // Are we already in a quoted argument? If so, push the argument to the result list. - // If not, start a new quoted argument. - if (inQuotes) { - let arg = start >= 0 - ? commandLineString.substring(start, index) - : ""; - result.push(arg); - start = -1; - inQuotes = false; - } - else { - inQuotes = true; - } - } - - if (!inQuotes && start >= 0 && ch === ' ') { - let arg = commandLineString.substring(start, index); - result.push(arg); - start = -1; - } - - index++; - } - - if (start >= 0) { - let arg = commandLineString.substring(start, commandLineString.length); - result.push(arg); - } - - return result; -} +} \ No newline at end of file diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index aea373f4ea..85311d6588 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -70,9 +70,7 @@ export function runDotnetTest(testMethod: string, fileName: string, testFramewor }); } -function createLaunchConfiguration(program: string, argsString: string, cwd: string, debuggerEventsPipeName: string) { - let args = utils.splitCommandLineArgs(argsString); - +function createLaunchConfiguration(program: string, args: string, cwd: string, debuggerEventsPipeName: string) { return { // NOTE: uncomment this for vsdbg developement // debugServer: 4711, diff --git a/src/features/processPicker.ts b/src/features/processPicker.ts index b7c4737ce0..77429ffc61 100644 --- a/src/features/processPicker.ts +++ b/src/features/processPicker.ts @@ -39,10 +39,19 @@ export class AttachPicker { } } +interface IPipeTransportOptions { + pipeProgram: string; + pipeArgs: string | string[]; + quoteArgs: boolean; +} + export class RemoteAttachPicker { public static get commColumnTitle() { return Array(PsOutputParser.secondColumnCharacters).join("a"); } public static get linuxPsCommand() { return `ps -axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args=`; } public static get osxPsCommand() { return `ps -axww -o pid=,comm=${RemoteAttachPicker.commColumnTitle},args= -c`; } + public static get debuggerCommand() { return "${debuggerCommand}"; }; + public static get scriptShellCmd() { return "sh -s"; }; + private static _channel: vscode.OutputChannel = null; @@ -75,6 +84,112 @@ export class RemoteAttachPicker { }); } + // Note: osPlatform is passed as an argument for testing. + public static getPipeTransportOptions(pipeTransport: any, osPlatform: string): IPipeTransportOptions { + let pipeProgram: string = pipeTransport.pipeProgram; + let pipeArgs: string[] | string = pipeTransport.pipeArgs; + let quoteArgs: boolean = pipeTransport.quoteArgs != null ? pipeTransport.quoteArgs : true; // default value is true + let platformSpecificPipeTransportOptions: IPipeTransportOptions = this.getPlatformSpecificPipeTransportOptions(pipeTransport, osPlatform); + + if (platformSpecificPipeTransportOptions) { + pipeProgram = platformSpecificPipeTransportOptions.pipeProgram || pipeProgram; + pipeArgs = platformSpecificPipeTransportOptions.pipeArgs || pipeArgs; + quoteArgs = platformSpecificPipeTransportOptions.quoteArgs != null ? platformSpecificPipeTransportOptions.quoteArgs : quoteArgs; + } + + return { + pipeProgram: pipeProgram, + pipeArgs: pipeArgs, + quoteArgs: quoteArgs + }; + } + + // If the current process is on a current operating system and a specific pipe transport + // is included, then use that specific pipe transport configuration. + // + // Note: osPlatform is passed as an argument for testing. + private static getPlatformSpecificPipeTransportOptions(config: any, osPlatform: string): IPipeTransportOptions { + if (osPlatform === "darwin" && config.osx) { + return config.osx; + } else if (osPlatform === "linux" && config.linux) { + return config.linux; + } else if (osPlatform === "win32" && config.windows) { + return config.windows; + } + + return null; + } + + // Creates a pipe command string based on the type of pipe args. + private static createPipeCmd(pipeProgram: string, pipeArgs: string | string[], quoteArgs: boolean): Promise { + return this.ValidateAndFixPipeProgram(pipeProgram).then(fixedPipeProgram => { + if (typeof pipeArgs === "string") { + return Promise.resolve(this.createPipeCmdFromString(fixedPipeProgram, pipeArgs, quoteArgs)); + } + else if (pipeArgs instanceof Array) { + return Promise.resolve(this.createPipeCmdFromArray(fixedPipeProgram, pipeArgs, quoteArgs)); + } else { + // Invalid args type + return Promise.reject(new Error("pipeArgs must be a string or a string array type")); + } + }); + } + + public static createPipeCmdFromString(pipeProgram: string, pipeArgs: string, quoteArgs: boolean): string { + // Quote program if quoteArgs is true. + let pipeCmd: string = this.quoteArg(pipeProgram); + + // If ${debuggerCommand} exists in pipeArgs, replace. No quoting is applied to the command here. + if (pipeArgs.indexOf(this.debuggerCommand) >= 0) { + pipeCmd = pipeCmd.concat(" ", pipeArgs.replace(/\$\{debuggerCommand\}/g, this.scriptShellCmd)); + } + // Add ${debuggerCommand} to the end of the args. Quote if quoteArgs is true. + else { + pipeCmd = pipeCmd.concat(" ", pipeArgs.concat(" ", this.quoteArg(this.scriptShellCmd, quoteArgs))); + } + + return pipeCmd; + } + + public static createPipeCmdFromArray(pipeProgram: string, pipeArgs: string[], quoteArgs: boolean): string { + let pipeCmdList: string[] = []; + // Add pipeProgram to the start. Quoting is handeled later. + pipeCmdList.push(pipeProgram); + + // If ${debuggerCommand} exists, replace it. + if (pipeArgs.filter(arg => arg.indexOf(this.debuggerCommand) >= 0).length > 0) { + for (let arg of pipeArgs) { + while (arg.indexOf(this.debuggerCommand) >= 0) { + arg = arg.replace(this.debuggerCommand, RemoteAttachPicker.scriptShellCmd); + } + + pipeCmdList.push(arg); + } + } + // Add ${debuggerCommand} to the end of the arguments. + else { + pipeCmdList = pipeCmdList.concat(pipeArgs); + pipeCmdList.push(this.scriptShellCmd); + } + + // Quote if enabled. + return quoteArgs ? this.createArgumentList(pipeCmdList) : pipeCmdList.join(' '); + } + + // Quote the arg if the flag is enabled and there is a space. + public static quoteArg(arg: string, quoteArg: boolean = true): string { + if (quoteArg && arg.includes(' ')) { + return `"${arg}"`; + } + + return arg; + } + + // Converts an array of string arguments to a string version. Always quotes any arguments with spaces. + public static createArgumentList(args: string[]): string { + return args.map(arg => this.quoteArg(arg)).join(" "); + } + public static ShowAttachEntries(args: any): Promise { // Create remote attach output channel for errors. if (!RemoteAttachPicker._channel) { @@ -97,87 +212,22 @@ export class RemoteAttachPicker { return Promise.reject(new Error("Configuration \"" + name + "\" in launch.json does not have a " + "pipeTransport argument with debuggerPath for pickRemoteProcess. Use pickProcess for local attach.")); } else { - let pipeProgram: string = args.pipeTransport.pipeProgram; - let pipeArgs: string[] = args.pipeTransport.pipeArgs; - let quoteArgs: boolean = args.pipeTransport.quoteArgs != null ? args.pipeTransport.quoteArgs : true; // default value is true - let platformSpecificPipeTransportOptions: any = RemoteAttachPicker.getPlatformSpecificPipeTransportOptions(args); - - if (platformSpecificPipeTransportOptions) { - pipeProgram = platformSpecificPipeTransportOptions.pipeProgram || pipeProgram; - pipeArgs = platformSpecificPipeTransportOptions.pipeArgs || pipeArgs; - quoteArgs = platformSpecificPipeTransportOptions.pipeTransport.quoteArgs != null ? platformSpecificPipeTransportOptions.pipeTransport.quoteArgs : quoteArgs; - } + let pipeTransport = this.getPipeTransportOptions(args.pipeTransport, os.platform()); - return RemoteAttachPicker.ValidateAndFixPipeProgram(pipeProgram).then(pipeProgram => { - let pipeCmdList: string[] = []; - let scriptShellCmd: string = "sh -s"; - pipeCmdList.push(pipeProgram); - - const debuggerCommandString: string = "${debuggerCommand}"; - - if (pipeArgs.filter(arg => arg.indexOf(debuggerCommandString) >= 0).length > 0) { - for (let arg of pipeArgs) { - while (arg.indexOf("${debuggerCommand}") >= 0) { - arg = arg.replace("${debuggerCommand}", scriptShellCmd); - } - - pipeCmdList.push(arg); - } - } - else { - pipeCmdList = pipeCmdList.concat(pipeArgs); - pipeCmdList.push(scriptShellCmd); - } - - let pipeCmd: string = quoteArgs ? this.createArgumentList(pipeCmdList) : pipeCmdList.join(' '); - - return RemoteAttachPicker.getRemoteOSAndProcesses(pipeCmd).then(processes => { + return RemoteAttachPicker.createPipeCmd(pipeTransport.pipeProgram, pipeTransport.pipeArgs, pipeTransport.quoteArgs) + .then(pipeCmd => RemoteAttachPicker.getRemoteOSAndProcesses(pipeCmd)) + .then(processes => { let attachPickOptions: vscode.QuickPickOptions = { matchOnDescription: true, matchOnDetail: true, placeHolder: "Select the process to attach to" }; - return vscode.window.showQuickPick(processes, attachPickOptions).then(item => { - return item ? item.id : Promise.reject(new Error("Could not find a process id to attach.")); - }); - }); - }); + return vscode.window.showQuickPick(processes, attachPickOptions); + }) + .then(item => { return item ? item.id : Promise.reject(new Error("Could not find a process id to attach.")); }); } } - private static createArgumentList(args: string[]): string { - let ret = ""; - - for (let arg of args) { - if (ret) { - ret += " "; - } - - if (arg.includes(' ')) { - ret += `"${arg}"`; - } - else { - ret += `${arg}`; - } - } - - return ret; - } - - private static getPlatformSpecificPipeTransportOptions(config) { - const osPlatform = os.platform(); - - if (osPlatform == "darwin" && config.pipeTransport.osx) { - return config.pipeTransport.osx; - } else if (osPlatform == "linux" && config.pipeTransport.linux) { - return config.pipeTransport.linux; - } else if (osPlatform == "win32" && config.pipeTransport.windows) { - return config.pipeTransport.windows; - } - - return null; - } - public static getRemoteOSAndProcesses(pipeCmd: string): Promise { const scriptPath = path.join(getExtensionPath(), 'scripts', 'remoteProcessPickerScript'); diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index ea916a757a..a85301a39e 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -25,12 +25,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, - "default": [] + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ] }, "quoteArgs": { "type": "boolean", @@ -69,12 +78,21 @@ "default": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'" }, "pipeArgs": { - "type": "array", - "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", - "items": { - "type": "string" - }, - "default": [] + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the pipe program. Token ${debuggerCommand} in pipeArgs will get replaced by the full debugger command, this token can be specified inline with other arguments. If ${debuggerCommand} isn’t used in any argument, the full debugger command will be instead be added to the end of the argument list.", + "default": "" + } + ] }, "debuggerPath" : { "type" : "string", @@ -195,9 +213,21 @@ "default": true }, "args": { - "type": "string", - "description": "The arguments to pass to the command to open the browser. Use ${auto-detect-url} to automatically use the address the server is listening to", - "default": "${auto-detect-url}" + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ] }, "osx": { "$ref": "#/definitions/LaunchBrowserPlatformOptions", @@ -241,12 +271,21 @@ "default": "${workspaceRoot}" }, "args": { - "type": "array", - "description": "Command line arguments passed to the program.", - "items": { - "type": "string" - }, - "default": [] + "anyOf": [ + { + "type": "array", + "description": "Command line arguments passed to the program.", + "items": { + "type": "string" + }, + "default": [] + }, + { + "type": "string", + "description": "Stringified version of command line arguments passed to the program.", + "default": "" + } + ] }, "stopAtEntry": { "type": "boolean", diff --git a/test/common.test.ts b/test/common.test.ts index 0624f7581e..cf90b15fe0 100644 --- a/test/common.test.ts +++ b/test/common.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { should } from 'chai'; -import { buildPromiseChain, splitCommandLineArgs, safeLength, sum } from '../src/common'; +import { buildPromiseChain, safeLength, sum } from '../src/common'; suite("Common", () => { suiteSetup(() => should()); @@ -25,50 +25,6 @@ suite("Common", () => { }); }); - suite("splitCommandLineArgs", () => { - test("single argument", () => { - let result = splitCommandLineArgs("hello"); - - result.should.deep.equal(["hello"]); - }); - - test("two arguments", () => { - let result = splitCommandLineArgs("hello world"); - - result.should.deep.equal(["hello", "world"]); - }); - - test("single quoted argument", () => { - let result = splitCommandLineArgs("\"hello world\""); - - result.should.deep.equal(["hello world"]); - }); - - test("two argument, one quoted", () => { - let result = splitCommandLineArgs("hello \"world\""); - - result.should.deep.equal(["hello", "world"]); - }); - - test("many quoted arguments", () => { - let result = splitCommandLineArgs("\"a\" \"b\" \"c\" \"d\" \"e\""); - - result.should.deep.equal(["a", "b", "c", "d", "e"]); - }); - - test("many arguments, some quoted, some not", () => { - let result = splitCommandLineArgs("\"a\" b \"c\" d \"e\""); - - result.should.deep.equal(["a", "b", "c", "d", "e"]); - }); - - test("many arguments, some quoted, some not (inverted)", () => { - let result = splitCommandLineArgs("a \"b\" c \"d\" e"); - - result.should.deep.equal(["a", "b", "c", "d", "e"]); - }); - }); - suite("safeLength", () => { test("return 0 for empty array", () => { let array = []; diff --git a/test/processPicker.test.ts b/test/processPicker.test.ts new file mode 100644 index 0000000000..63ad82f8f5 --- /dev/null +++ b/test/processPicker.test.ts @@ -0,0 +1,233 @@ +import { should } from 'chai'; +import { RemoteAttachPicker } from '../src/features/processPicker'; + +suite("Remote Process Picker: Validate quoting arguments.", () => { + suiteSetup(() => should()); + test("Argument with no spaces", () => { + let nonQuotedArg = RemoteAttachPicker.quoteArg("C:\\Users\\nospace\\program.exe"); + + nonQuotedArg.should.deep.equal("C:\\Users\\nospace\\program.exe"); + }); + + test("Argument with spaces", () => { + let nonQuotedArg = RemoteAttachPicker.quoteArg("C:\\Users\\s p a c e\\program.exe"); + + nonQuotedArg.should.deep.equal("\"C:\\Users\\s p a c e\\program.exe\""); + }); + + test("Argument with spaces with no quotes", () => { + let nonQuotedArg = RemoteAttachPicker.quoteArg("C:\\Users\\s p a c e\\program.exe", false); + + nonQuotedArg.should.deep.equal("C:\\Users\\s p a c e\\program.exe"); + }); + + test("WSL with array arguments and quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithArrayArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c \"" + RemoteAttachPicker.scriptShellCmd + "\""); + }); + + test("WSL with array arguments and no quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithArrayArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, false); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c " + RemoteAttachPicker.scriptShellCmd); + }); + + test("WSL with array arguments + debugger command and quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithArrayArgsAndDebuggerCommand(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c \"" + RemoteAttachPicker.scriptShellCmd + "\" -- ignored"); + }); + + test("WSL with array arguments + debugger command and no quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithArrayArgsAndDebuggerCommand(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, false); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c " + RemoteAttachPicker.scriptShellCmd + " -- ignored"); + }); + + test("WSL with string arguments and quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithStringArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c \"" + RemoteAttachPicker.scriptShellCmd + "\""); + }); + + test("WSL with string arguments and no quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithStringArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString(pipeTransport.pipeProgram, pipeTransport.pipeArgs, false); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c " + RemoteAttachPicker.scriptShellCmd); + }); + + test("WSL with string arguments + debugger command and quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithStringArgsAndDebuggerCommand(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c " + RemoteAttachPicker.scriptShellCmd + " -- ignored"); + }); + + test("WSL with string arguments + debugger command and no quote args", () => { + let pipeTransport = GetWindowsWSLLaunchJSONWithStringArgsAndDebuggerCommand(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString(pipeTransport.pipeProgram, pipeTransport.pipeArgs, false); + + pipeCmd.should.deep.equal("C:\\System32\\bash.exe -c " + RemoteAttachPicker.scriptShellCmd + " -- ignored"); + }); + + test("Windows Docker with string args, debuggerCommand", () => { + let pipeTransport = GetWindowsDockerLaunchJSONWithStringArgsAndDebuggerCommand(); + + // quoteArgs flag should be ignored + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString(pipeTransport.pipeProgram, pipeTransport.pipeArgs, pipeTransport.quoteArgs); + + pipeCmd.should.deep.equal("docker -i exec 1234567 " + RemoteAttachPicker.scriptShellCmd); + }); + + test("Windows Docker with array args", () => { + let pipeTransport = GetWindowsDockerLaunchJSONWithArrayArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, pipeTransport.quoteArgs); + + pipeCmd.should.deep.equal("docker -i exec 1234567 " + RemoteAttachPicker.scriptShellCmd); + + }); + + test("Windows Docker with array args with quotes", () => { + let pipeTransport = GetWindowsDockerLaunchJSONWithArrayArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal("docker -i exec 1234567 \"" + RemoteAttachPicker.scriptShellCmd + "\""); + + }); + + test("Linux dotnet with array args and spaces", () => { + let pipeTransport = GetLinuxLaunchJSONWithArrayArgs(); + + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray(pipeTransport.pipeProgram, pipeTransport.pipeArgs, true); + + pipeCmd.should.deep.equal(`/usr/bin/shared/dotnet bin/framework/myprogram.dll \"argument with spaces\" \"${RemoteAttachPicker.scriptShellCmd}\"`); + }); + + test("Multiple ${debuggerCommand} in string args", () => { + let pipeCmd = RemoteAttachPicker.createPipeCmdFromString("program.exe", "".concat(RemoteAttachPicker.debuggerCommand, " ", RemoteAttachPicker.debuggerCommand, " ", RemoteAttachPicker.debuggerCommand), true); + + pipeCmd.should.deep.equal("program.exe " + RemoteAttachPicker.scriptShellCmd + " " + RemoteAttachPicker.scriptShellCmd + " " + RemoteAttachPicker.scriptShellCmd); + }); + + test("Multiple ${debuggerCommand} in array args", () => { + let pipeCmd = RemoteAttachPicker.createPipeCmdFromArray("program.exe", [RemoteAttachPicker.debuggerCommand, RemoteAttachPicker.debuggerCommand, RemoteAttachPicker.debuggerCommand], true); + + pipeCmd.should.deep.equal("program.exe \"" + RemoteAttachPicker.scriptShellCmd + "\" \"" + RemoteAttachPicker.scriptShellCmd + "\" \"" + RemoteAttachPicker.scriptShellCmd + "\""); + }); + + test("OS Specific Configurations", () => { + let launch = GetOSSpecificJSON(); + + let pipeTransport = RemoteAttachPicker.getPipeTransportOptions(launch, "win32"); + + pipeTransport.pipeProgram.should.deep.equal("Windows pipeProgram"); + pipeTransport.pipeArgs.should.deep.equal("windows"); + + pipeTransport = RemoteAttachPicker.getPipeTransportOptions(launch, "darwin"); + + pipeTransport.pipeProgram.should.deep.equal("OSX pipeProgram"); + pipeTransport.pipeArgs.should.deep.equal(["osx"]); + + pipeTransport = RemoteAttachPicker.getPipeTransportOptions(launch, "linux"); + + pipeTransport.pipeProgram.should.deep.equal("Linux pipeProgram"); + // Linux pipeTransport does not have args defined, should use the one defined in pipeTransport. + pipeTransport.pipeArgs.should.deep.equal([]); + + }); +}); + +function GetWindowsWSLLaunchJSONWithArrayArgs() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "C:\\System32\\bash.exe", + pipeArgs: ["-c"] + } +} + +function GetWindowsWSLLaunchJSONWithArrayArgsAndDebuggerCommand() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "C:\\System32\\bash.exe", + pipeArgs: ["-c", "${debuggerCommand}", "--", "ignored"] + } +} + +function GetWindowsWSLLaunchJSONWithStringArgs() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "C:\\System32\\bash.exe", + pipeArgs: "-c" + } +} + +function GetWindowsWSLLaunchJSONWithStringArgsAndDebuggerCommand() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "C:\\System32\\bash.exe", + pipeArgs: "-c ${debuggerCommand} -- ignored" + } +} + +function GetWindowsDockerLaunchJSONWithArrayArgs() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "docker", + pipeArgs: ["-i", "exec", "1234567"], + quoteArgs: false + } +}; + +function GetWindowsDockerLaunchJSONWithStringArgsAndDebuggerCommand() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "docker", + pipeArgs: "-i exec 1234567 ${debuggerCommand}", + quoteArgs: false + } +} + +function GetLinuxLaunchJSONWithArrayArgs() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "/usr/bin/shared/dotnet", + pipeArgs: ["bin/framework/myprogram.dll", "argument with spaces"], + quoteArg: true + } +} + +function GetOSSpecificJSON() { + return { + pipeCwd: "${workspaceRoot}", + pipeProgram: "pipeProgram", + pipeArgs: [], + windows: { + pipeProgram: "Windows pipeProgram", + pipeArgs: "windows" + }, + osx: { + pipeProgram: "OSX pipeProgram", + pipeArgs: ["osx"] + }, + linux: { + pipeProgram: "Linux pipeProgram", + } + } +} \ No newline at end of file From ae18b199dd6f4f51072419a7adb6b46dad66e0b9 Mon Sep 17 00:00:00 2001 From: Lian Hoy Lee Date: Thu, 27 Apr 2017 14:00:36 +1200 Subject: [PATCH 02/31] Allow suppression of hidden messages to be configurable with a default to supress (#1429) --- package.json | 5 +++++ src/features/diagnosticsProvider.ts | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 8874e61aad..ca4e0bf667 100644 --- a/package.json +++ b/package.json @@ -364,6 +364,11 @@ "default": false, "description": "Suppress the notification window to perform a 'dotnet restore' when dependencies can't be resolved." }, + "csharp.suppressHiddenMessages": { + "type": "boolean", + "default": true, + "description": "Suppress hidden messages from being shown." + }, "omnisharp.path": { "type": [ "string", diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index ad108b00fa..8221156337 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -195,7 +195,7 @@ class DiagnosticsProvider extends AbstractSupport { let quickFixes = value.QuickFixes.filter(DiagnosticsProvider._shouldInclude); - // Easy case: If there are no diagnostics in the file, we can clear it quickly. + // Easy case: If there are no diagnostics in the file, we can clear it quickly. if (quickFixes.length === 0) { if (this._diagnostics.has(document.uri)) { this._diagnostics.delete(document.uri); @@ -273,7 +273,12 @@ class DiagnosticsProvider extends AbstractSupport { } private static _shouldInclude(quickFix: protocol.QuickFix): boolean { - return quickFix.LogLevel.toLowerCase() !== 'hidden'; + const config = vscode.workspace.getConfiguration('csharp'); + if (config.get('suppressHiddenMessages', true)) { + return quickFix.LogLevel.toLowerCase() !== 'hidden'; + } else { + return true; + } } // --- data converter From c1d7d121ed8fb4a9f4bea4b2b75005af6840bb4b Mon Sep 17 00:00:00 2001 From: Lian Hoy Lee Date: Fri, 28 Apr 2017 08:24:24 +1200 Subject: [PATCH 03/31] fix setting name and description for clarity (#1429) --- package.json | 4 ++-- src/features/diagnosticsProvider.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index ca4e0bf667..3eefbf1869 100644 --- a/package.json +++ b/package.json @@ -364,10 +364,10 @@ "default": false, "description": "Suppress the notification window to perform a 'dotnet restore' when dependencies can't be resolved." }, - "csharp.suppressHiddenMessages": { + "csharp.suppressHiddenDiagnostics": { "type": "boolean", "default": true, - "description": "Suppress hidden messages from being shown." + "description": "Suppress 'hidden' diagnostics (such as 'unnecessary using directives') from appearing in the editor or the Problems pane." }, "omnisharp.path": { "type": [ diff --git a/src/features/diagnosticsProvider.ts b/src/features/diagnosticsProvider.ts index 8221156337..1cc3ae9cd3 100644 --- a/src/features/diagnosticsProvider.ts +++ b/src/features/diagnosticsProvider.ts @@ -274,7 +274,7 @@ class DiagnosticsProvider extends AbstractSupport { private static _shouldInclude(quickFix: protocol.QuickFix): boolean { const config = vscode.workspace.getConfiguration('csharp'); - if (config.get('suppressHiddenMessages', true)) { + if (config.get('suppressHiddenDiagnostics', true)) { return quickFix.LogLevel.toLowerCase() !== 'hidden'; } else { return true; From dabe988710aaa6eaf46cf2e62d6f6bb3a893afe7 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 27 Apr 2017 13:24:33 -0700 Subject: [PATCH 04/31] Add summary line after test run --- src/features/dotnetTest.ts | 24 +++++++++++++++++++----- src/omnisharp/protocol.ts | 11 ++++++++++- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 85311d6588..4d5a777c85 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -55,13 +55,27 @@ export function runDotnetTest(testMethod: string, fileName: string, testFramewor serverUtils.runTest(server, request) .then(response => { - if (response.Pass) { - output.appendLine('Test passed \n'); - } - else { - output.appendLine('Test failed \n'); + const totalTests = response.Results.length; + + let totalPassed = 0, totalFailed = 0, totalSkipped = 0; + for (let result of response.Results) { + switch (result.Outcome) { + case protocol.V2.TestOutcomes.Failed: + totalFailed += 1; + break; + case protocol.V2.TestOutcomes.Passed: + totalPassed += 1; + break; + case protocol.V2.TestOutcomes.Skipped: + totalSkipped += 1; + break; + } } + output.appendLine(''); + output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`); + output.appendLine(''); + disposable.dispose(); }, reason => { diff --git a/src/omnisharp/protocol.ts b/src/omnisharp/protocol.ts index 2e03c51d34..86a7019461 100644 --- a/src/omnisharp/protocol.ts +++ b/src/omnisharp/protocol.ts @@ -538,7 +538,15 @@ export namespace V2 { TestFrameworkName: string; } - export interface DotNetResult { + export module TestOutcomes { + export const None = 'none'; + export const Passed = 'passed'; + export const Failed = 'failed'; + export const Skipped = 'skipped'; + export const NotFound = 'notfound'; + } + + export interface DotNetTestResult { MethodName: string; Outcome: string; ErrorMessage: string; @@ -548,6 +556,7 @@ export namespace V2 { export interface RunTestResponse { Failure: string; Pass: boolean; + Results: DotNetTestResult[]; } export interface TestMessageEvent { From 1917df1f0189cf05f9cdd88f32743ebb48e02f39 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 27 Apr 2017 14:14:51 -0700 Subject: [PATCH 05/31] Update changelog --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc9f93c9da..e460c4f14d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,27 @@ * 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.10.0 _(Not Yet Released)_ + +#### Unit Testing + +* Add support for NUnit Test Adapter. ([#1434](https://github.com/OmniSharp/omnisharp-vscode/issues/1434), PR: [omnisharp-roslyn#834](https://github.com/OmniSharp/omnisharp-roslyn/pull/834)) +* Tests that define display names are now run properly. ([#1426](https://github.com/OmniSharp/omnisharp-vscode/issues/1426), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) +* Tests with similar names are no longer incorrectly run together when one of them is clicked. ([#1432](https://github.com/OmniSharp/omnisharp-vscode/issues/1432), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) +* Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PR: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436)) + +#### Project System + +* Project references to projects located outside of the current workspace directory are now loaded and processed. ([#963](https://github.com/OmniSharp/omnisharp-vscode/issues/963), PR: [omnisharp-roslyn#832](https://github.com/OmniSharp/omnisharp-vscode/issues/963)) + +#### Scripting + +* Support Metadata as Source for Go To Definition in CSX files. ([omnisharp-roslyn#755](https://github.com/OmniSharp/omnisharp-roslyn/issues/755), PR: ([omnisharp-roslyn#829](https://github.com/OmniSharp/omnisharp-roslyn/pull/829)) _(Contributed by [@filipw](https://github.com/filipw))_ + +#### Other Updates and Fixes + +* New `csharp.suppressHiddenDiagnostics` setting that can be set to true to display hidden diagnostics, such as 'unnecessary using directive'. ([#1429](https://github.com/OmniSharp/omnisharp-vscode/issues/1429), PR: [#1435](https://github.com/OmniSharp/omnisharp-vscode/pull/1435)) _(Contributed by [@cruz82](https://github.com/cruz82))_ + ## 1.9.0 (April 20, 2017) #### Unit Testing From 9bbf2aa20babc43cd309895ab77a7d9891bff0d5 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 27 Apr 2017 16:30:54 -0700 Subject: [PATCH 06/31] Update OmniSharp to 1.6.0 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 3eefbf1869..bafa56b6fd 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.14.0.2.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.16.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -135,7 +135,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.14.0.2.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.16.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -147,7 +147,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.14.0.2.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.16.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", From 1a08faac71bb79ab51d117b7f6d039c6edb60f89 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 27 Apr 2017 16:31:22 -0700 Subject: [PATCH 07/31] 1.9.0 -> 1.10.0-beta1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index bafa56b6fd..95ca7a21f8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.9.0", + "version": "1.10.0-beta1", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", From 9a1b1a5e46ebf5fde1bb36a45905b6fe04f0019b Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Thu, 27 Apr 2017 16:35:47 -0700 Subject: [PATCH 08/31] Removing cwd to be required. (#1427) If unspecified it will use the program path. --- package.json | 8 +++----- src/tools/OptionsSchema.json | 3 +-- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index 3eefbf1869..0a9eb14570 100644 --- a/package.json +++ b/package.json @@ -519,8 +519,7 @@ "launch": { "type": "object", "required": [ - "program", - "cwd" + "program" ], "properties": { "program": { @@ -1447,8 +1446,7 @@ "launch": { "type": "object", "required": [ - "program", - "cwd" + "program" ], "properties": { "program": { @@ -2209,4 +2207,4 @@ } ] } -} +} \ No newline at end of file diff --git a/src/tools/OptionsSchema.json b/src/tools/OptionsSchema.json index a85301a39e..012d5fade9 100644 --- a/src/tools/OptionsSchema.json +++ b/src/tools/OptionsSchema.json @@ -256,8 +256,7 @@ "LaunchOptions": { "type": "object", "required": [ - "program", - "cwd" + "program" ], "properties": { "program": { From e2693440902f2019b0141c917a3ec0b42206b4b7 Mon Sep 17 00:00:00 2001 From: Gregg Miskelly Date: Tue, 2 May 2017 09:44:50 -0700 Subject: [PATCH 09/31] Add support for passing debug options when unit test debugging (#1446) * Add support for passing debug options when unit test debugging Recently there have been a few cases where I wanted to have folks enable debugging options when debugging unit tests, but we didn't have any way of providing them. This checkin fixes that. * Code review feedback --- CHANGELOG.md | 1 + package.json | 78 ++++++++++++++++++++++++++++++++++++++ src/features/dotnetTest.ts | 33 ++++++++++------ src/tools/README.md | 8 +++- 4 files changed, 106 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e460c4f14d..87ed3aeb54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Tests that define display names are now run properly. ([#1426](https://github.com/OmniSharp/omnisharp-vscode/issues/1426), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) * Tests with similar names are no longer incorrectly run together when one of them is clicked. ([#1432](https://github.com/OmniSharp/omnisharp-vscode/issues/1432), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) * Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PR: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436)) +* Added `csharp.unitTestDebugingOptions` setting to pass launch.json-style debug options (example: `justMyCode`) when unit test debugging. #### Project System diff --git a/package.json b/package.json index eb06f4a973..0b3ce7571a 100644 --- a/package.json +++ b/package.json @@ -359,6 +359,84 @@ ], "description": "If the current Linux distribution is not recognized, this option can be used to tell the debugger what version can be used. After changing this option, close VS Code, remove the debugger folder (~/.vscode/extensions/ms-vscode.csharp-/.debugger) if it has already downloaded, and restart VS Code." }, + "csharp.unitTestDebugingOptions": { + "type": "object", + "description": "Options to use with the debugger when launching for unit test debugging. Any launch.json option is valid here.", + "default": {}, + "properties": { + "sourceFileMap": { + "type": "object", + "description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'", + "additionalProperties": { + "type": "string" + }, + "default": { + "": "" + } + }, + "justMyCode": { + "type": "boolean", + "description": "Optional flag to only show user code.", + "default": true + }, + "symbolPath": { + "type": "array", + "description": "Array of directories to use to search for .pdb files. These directories will be searched in addition to the default locations -- next to the module and the path where the pdb was originally dropped to. Example: '[ \"/Volumes/symbols\" ]", + "items": { + "type": "string" + }, + "default": [] + }, + "requireExactSource": { + "type": "boolean", + "description": "Optional flag to require current source code to match the pdb.", + "default": true + }, + "enableStepFiltering": { + "type": "boolean", + "description": "Optional flag to enable stepping over Properties and Operators.", + "default": true + }, + "debugServer": { + "type": "number", + "description": "For debug extension development only: if a port is specified VS Code tries to connect to a debug adapter running in server mode", + "default": 4711 + }, + "logging": { + "description": "Optional flags to determine what types of messages should be logged to the output window.", + "type": "object", + "required": [], + "default": {}, + "properties": { + "exceptions": { + "type": "boolean", + "description": "Optional flag to determine whether exception messages should be logged to the output window.", + "default": true + }, + "moduleLoad": { + "type": "boolean", + "description": "Optional flag to determine whether module load events should be logged to the output window.", + "default": true + }, + "programOutput": { + "type": "boolean", + "description": "Optional flag to determine whether program output should be logged to the output window when not using an external console.", + "default": true + }, + "engineLogging": { + "type": "boolean", + "description": "Optional flag to determine whether diagnostic engine logs should be logged to the output window.", + "default": false + }, + "browserStdOut": { + "type": "boolean", + "description": "Optional flag to determine if stdout text from the launching the web browser should be logged to the output window.", + "default": true + } + } + } + } + }, "csharp.suppressDotnetRestoreNotification": { "type": "boolean", "default": false, diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 4d5a777c85..947c123500 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -85,18 +85,27 @@ export function runDotnetTest(testMethod: string, fileName: string, testFramewor } function createLaunchConfiguration(program: string, args: string, cwd: string, debuggerEventsPipeName: string) { - return { - // NOTE: uncomment this for vsdbg developement - // debugServer: 4711, - name: ".NET Test Launch", - type: "coreclr", - request: "launch", - debuggerEventsPipeName: debuggerEventsPipeName, - program, - args, - cwd, - stopAtEntry: true - }; + let debugOptions = vscode.workspace.getConfiguration('csharp').get('unitTestDebugingOptions'); + + // Get the initial set of options from the workspace setting + let result:any; + if (typeof debugOptions === "object") { + // clone the options object to avoid changing it + result = JSON.parse(JSON.stringify(debugOptions)); + } else { + result = {}; + } + + // Now fill in the rest of the options + result.name = ".NET Test Launch"; + result.type = "coreclr"; + result.request = "launch"; + result.debuggerEventsPipeName = debuggerEventsPipeName; + result.program = program; + result.args = args; + result.cwd = cwd; + + return result; } function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener): Promise { diff --git a/src/tools/README.md b/src/tools/README.md index bab72413f2..0e1a6b06fa 100644 --- a/src/tools/README.md +++ b/src/tools/README.md @@ -5,8 +5,12 @@ OptionsSchema.json defines the type for Launch/Attach options. If there are any modifications to the OptionsSchema.json file. Please run `gulp generateOptionsSchema` at the repo root. This will call GenerateOptionsSchema and update the package.json file. -**NOTE:** *Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes will be -replaced by this generator* +### Important notes: + +1. Any manual changes to package.json's object.contributes.debuggers[0].configurationAttributes will be +replaced by this generator. +2. This does **NOT** update the schema for csharp.unitTestDebugingOptions. So if the schema change is something valuable in unit test debugging, consider updating that section of package.json (look for `"csharp.unitTestDebugingOptions"`). The schema will work even if this step is omitted, but users will not get IntelliSense help when editing the new option if this step is skipped. + If there is any other type of options added in the future, you will need to modify the GenerateOptionsSchema function to have it appear in package.json. It only adds launch and attach. From 2abd3b28b106f851779e880bdb9bfd75700bf91e Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 4 May 2017 08:59:16 -0700 Subject: [PATCH 10/31] v1.10.0-beta1 -> v1.10.0-beta2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0b3ce7571a..bf42580a82 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.10.0-beta1", + "version": "1.10.0-beta2", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", From 38a759227eb0867cae6adcc70e8be433226bad73 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 4 May 2017 09:31:29 -0700 Subject: [PATCH 11/31] Update changelog for 1.10.0-beta2 --- CHANGELOG.md | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87ed3aeb54..a9588629b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,22 +5,32 @@ ## 1.10.0 _(Not Yet Released)_ -#### Unit Testing +#### Completion List -* Add support for NUnit Test Adapter. ([#1434](https://github.com/OmniSharp/omnisharp-vscode/issues/1434), PR: [omnisharp-roslyn#834](https://github.com/OmniSharp/omnisharp-roslyn/pull/834)) -* Tests that define display names are now run properly. ([#1426](https://github.com/OmniSharp/omnisharp-vscode/issues/1426), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) -* Tests with similar names are no longer incorrectly run together when one of them is clicked. ([#1432](https://github.com/OmniSharp/omnisharp-vscode/issues/1432), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) -* Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PR: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436)) -* Added `csharp.unitTestDebugingOptions` setting to pass launch.json-style debug options (example: `justMyCode`) when unit test debugging. +* Several improvements to the completion list! _(All contributed by [@filipw](https://github.com/filipw) with PR [omnisharp-roslyn#840](https://github.com/OmniSharp/omnisharp-roslyn/pull/840))_ + * Attributes are completed properly without the 'Attribute' suffix. ([#393](https://github.com/OmniSharp/omnisharp-vscode/issues/393)) + * Named parameters now appear in the completion list. ([#652](https://github.com/OmniSharp/omnisharp-vscode/issues/652)) + * Object initializer members now appear in the completion list. ([#260](https://github.com/OmniSharp/omnisharp-vscode/issues/260)) + * Completion appears within XML doc comment CREFs. + * Initial support for completion on 'override' and 'partial' keywords. ([#1044](https://github.com/OmniSharp/omnisharp-vscode/issues/1044)) #### Project System * Project references to projects located outside of the current workspace directory are now loaded and processed. ([#963](https://github.com/OmniSharp/omnisharp-vscode/issues/963), PR: [omnisharp-roslyn#832](https://github.com/OmniSharp/omnisharp-vscode/issues/963)) +* OmniSharp now loads .NET Core projects using the SDKs included with the .NET Core SDK appropriate for that project, if they're installed on the machine. ([#1438](https://github.com/OmniSharp/omnisharp-vscode/issues/1438), [omnisharp-roslyn#765](https://github.com/OmniSharp/omnisharp-roslyn/issues/765), PR: [omnisharp-roslyn#847](https://github.com/OmniSharp/omnisharp-roslyn/pull/847)) #### Scripting * Support Metadata as Source for Go To Definition in CSX files. ([omnisharp-roslyn#755](https://github.com/OmniSharp/omnisharp-roslyn/issues/755), PR: ([omnisharp-roslyn#829](https://github.com/OmniSharp/omnisharp-roslyn/pull/829)) _(Contributed by [@filipw](https://github.com/filipw))_ +#### Unit Testing + +* Add support for NUnit Test Adapter. ([#1434](https://github.com/OmniSharp/omnisharp-vscode/issues/1434), PR: [omnisharp-roslyn#834](https://github.com/OmniSharp/omnisharp-roslyn/pull/834)) +* Tests that define display names are now run properly. ([#1426](https://github.com/OmniSharp/omnisharp-vscode/issues/1426), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) +* Tests with similar names are no longer incorrectly run together when one of them is clicked. ([#1432](https://github.com/OmniSharp/omnisharp-vscode/issues/1432), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) +* Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PR: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436)) +* Added `csharp.unitTestDebugingOptions` setting to pass launch.json-style debug options (example: `justMyCode`) when unit test debugging. + #### Other Updates and Fixes * New `csharp.suppressHiddenDiagnostics` setting that can be set to true to display hidden diagnostics, such as 'unnecessary using directive'. ([#1429](https://github.com/OmniSharp/omnisharp-vscode/issues/1429), PR: [#1435](https://github.com/OmniSharp/omnisharp-vscode/pull/1435)) _(Contributed by [@cruz82](https://github.com/cruz82))_ From 01aa52e197d37e6832006376bf8da96eb1bb5591 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 3 May 2017 10:22:15 -0700 Subject: [PATCH 12/31] Clean up CompletionItemProvider a bit and tweak regex used on completion text to avoid removing parentheses --- src/features/completionItemProvider.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index 855c66963d..060cece633 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -28,9 +28,9 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp req.WantKind = true; req.WantReturnType = true; - return serverUtils.autoComplete(this._server, req).then(values => { + return serverUtils.autoComplete(this._server, req).then(responses => { - if (!values) { + if (!responses) { return; } @@ -39,11 +39,16 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp // transform AutoCompleteResponse to CompletionItem and // group by code snippet - for (let value of values) { - let completion = new CompletionItem(value.CompletionText.replace(/\(|\)|<|>/g, '')); - completion.detail = value.ReturnType ? `${value.ReturnType} ${value.DisplayText}` : value.DisplayText; - completion.documentation = extractSummaryText(value.Description); - completion.kind = _kinds[value.Kind] || CompletionItemKind.Property; + for (let response of responses) { + let completion = new CompletionItem(response.DisplayText); + + completion.detail = response.ReturnType + ? `${response.ReturnType} ${response.DisplayText}` + : response.DisplayText; + + completion.documentation = extractSummaryText(response.Description); + completion.kind = _kinds[response.Kind] || CompletionItemKind.Property; + completion.insertText = response.CompletionText.replace(/<>/g, ''); let array = completions[completion.label]; if (!array) { From 8e398251d1de6f2234557847e4542793a01faaa0 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 4 May 2017 09:52:09 -0700 Subject: [PATCH 13/31] Update to OmniSharp 1.17.0 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index bf42580a82..62aa73b694 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.16.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.17.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -135,7 +135,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.16.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.17.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -147,7 +147,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.16.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.17.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", From 6ca8acd05147b2f3216964b4cb8e4452131f8441 Mon Sep 17 00:00:00 2001 From: Shaun Luttin Date: Fri, 5 May 2017 20:25:40 -0700 Subject: [PATCH 14/31] Delete corrupt iterindex snippet --- snippets/csharp.json | 50 -------------------------------------------- 1 file changed, 50 deletions(-) diff --git a/snippets/csharp.json b/snippets/csharp.json index 9f31803fe0..bdae38a6eb 100644 --- a/snippets/csharp.json +++ b/snippets/csharp.json @@ -251,56 +251,6 @@ ], "description": "Simple iterator" }, - - "Named iterator/indexer pair using a nested class": { - - "prefix": "iterindex", - "body": [ - "public ${Name}Iterator ${Name}", - "{", - " get", - " {", - " return new ${Name}Iterator(this);", - " }", - "}", - "", - "public class ${Name}Iterator", - "{", - " readonly ${ClassName} outer;", - " ", - " internal ${Name}Iterator(${ClassName} outer)", - " {", - " this.outer = outer;", - " }", - " ", - " // TODO: provide an appropriate implementation here", - " public int Length { get { return 1; } }", - " ", - " public ${ElementType} this[int index]", - " {", - " get", - " {", - " //", - " // TODO: implement indexer here", - " //", - " // you have full access to ${ClassName} privates", - " //", - " ${throw new System.NotImplementedException();}", - " return default(${ElementType});", - " }", - " }", - " ", - " public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()", - " {", - " for (int i = 0; i < this.Length; i++)", - " {", - " yield return this[i];", - " }", - " }", - "}" - ], - "description": "Named iterator/indexer pair using a nested class" - }, "Lock statement": { From 6e0b22e3e13fa6a0b499b4debac5b5fd4a182b9f Mon Sep 17 00:00:00 2001 From: Shaun Luttin Date: Fri, 5 May 2017 20:52:59 -0700 Subject: [PATCH 15/31] Replace tabs with spaces --- snippets/csharp.json | 1046 ++++++++++++++++++++++-------------------- 1 file changed, 548 insertions(+), 498 deletions(-) diff --git a/snippets/csharp.json b/snippets/csharp.json index bdae38a6eb..92fb47652f 100644 --- a/snippets/csharp.json +++ b/snippets/csharp.json @@ -1,503 +1,553 @@ { - "Attribute using recommended pattern": { - - "prefix": "attribute", - "body": [ - "[System.AttributeUsage(System.AttributeTargets.${All}, Inherited = ${false}, AllowMultiple = ${true})]", - "sealed class ${My}Attribute : System.Attribute", - "{", - " // See the attribute guidelines at", - " // http://go.microsoft.com/fwlink/?LinkId=85236", - " readonly string positionalString;", - " ", - " // This is a positional argument", - " public ${My}Attribute (string positionalString)", - " {", - " this.positionalString = positionalString;", - " ", - " // TODO: Implement code here", - " ${throw new System.NotImplementedException();}", - " }", - " ", - " public string PositionalString", - " {", - " get { return positionalString; }", - " }", - " ", - " // This is a named argument", - " public int NamedInt { get; set; }", - "}" - ], - "description": "Attribute using recommended pattern" - }, - - "Checked block": { - - "prefix": "checked", - "body": [ - "checked", - "{", - " $0", - "}" - ], - "description": "Checked block" - }, - - "Class": { - - "prefix": "class", - "body": [ - "class ${Name}", - "{", - " $0", - "}" - ], - "description": "Class" - }, - - "Console.WriteLine": { - - "prefix": "cw", - "body": [ - "System.Console.WriteLine($0);" - ], - "description": "Console.WriteLine" - }, - - "do...while loop": { - - "prefix": "do", - "body": [ - "do", - "{", - " $0", - "} while (${true});" - ], - "description": "do...while loop" - }, - - "Else statement": { - - "prefix": "else", - "body": [ - "else", - "{", - " $0", - "}" - ], - "description": "Else statement" - }, - - "Enum": { - - "prefix": "enum", - "body": [ - "enum ${Name}", - "{", - " $0", - "}" - ], - "description": "Enum" - }, - - "Implementing Equals() according to guidelines": { - - "prefix": "equals", - "body": [ - "// override object.Equals", - "public override bool Equals (object obj)", - "{", - " //", - " // See the full list of guidelines at", - " // http://go.microsoft.com/fwlink/?LinkID=85237", - " // and also the guidance for operator== at", - " // http://go.microsoft.com/fwlink/?LinkId=85238", - " //", - " ", - " if (obj == null || GetType() != obj.GetType())", - " {", - " return false;", - " }", - " ", - " // TODO: write your implementation of Equals() here", - " ${1:throw new System.NotImplementedException();}", - " return base.Equals (obj);", - "}", - "", - "// override object.GetHashCode", - "public override int GetHashCode()", - "{", - " // TODO: write your implementation of GetHashCode() here", - " ${2:throw new System.NotImplementedException();}", - " return base.GetHashCode();", - "}" - ], - "description": "Implementing Equals() according to guidelines" - }, - - "Exception": { - - "prefix": "exception", - "body": [ - "[System.Serializable]", - "public class ${My}Exception : ${System.Exception}", - "{", - " public ${My}Exception() { }", - " public ${My}Exception( string message ) : base( message ) { }", - " public ${My}Exception( string message, System.Exception inner ) : base( message, inner ) { }", - " protected ${My}Exception(", - " System.Runtime.Serialization.SerializationInfo info,", - " System.Runtime.Serialization.StreamingContext context ) : base( info, context ) { }", - "}" - ], - "description": "Exception" - }, - - "Foreach statement": { - - "prefix": "foreach", - "body": [ - "foreach (${var} ${item} in ${collection})", - "{", - " $0", - "}" - ], - "description": "Foreach statement" - }, - - "Reverse for loop": { - - "prefix": "forr", - "body": [ - "for (int ${i} = ${length} - 1; ${i} >= 0 ; ${i}--)", - "{", - " $0", - "}" - ], - "description": "Reverse for loop" - }, - - "for loop": { - - "prefix": "for", - "body": [ - "for (int ${i} = 0; ${i} < ${length}; ${i}++)", - "{", - " $0", - "}" - ], - "description": "for loop" - }, - - "if statement": { - - "prefix": "if", - "body": [ - "if (${true})", - "{", - " $0", - "}" - ], - "description": "if statement" - }, - - "Indexer": { - - "prefix": "indexer", - "body": [ - "${public} ${object} this[${int} index]", - "{", - " get { $0 }", - " set { $1 }", - "}" - ], - "description": "Indexer" - }, - - "Interface": { - - "prefix": "interface", - "body": [ - "interface I${Name}", - "{", - " $0", - "}" - ], - "description": "Interface" - }, - - "Safely invoking an event": { - - "prefix": "invoke", - "body": [ - "${EventHandler} temp = ${MyEvent};", - "if (temp != null)", - "{", - " temp($0);", - "}" - ], - "description": "Safely invoking an event" - }, - - "Simple iterator": { - - "prefix": "iterator", - "body": [ - "public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()", - "{", - " $0throw new System.NotImplementedException();", - " yield return default(${ElementType});", - "}" - ], - "description": "Simple iterator" - }, - - "Lock statement": { - - "prefix": "lock", - "body": [ - "lock (${this})", - "{", - " $0", - "}" - ], - "description": "Lock statement" - }, - - "MessageBox.Show": { - - "prefix": "mbox", - "body": [ - "System.Windows.Forms.MessageBox.Show(\"${Text}\");$0" - ], - "description": "MessageBox.Show" - }, - - "Namespace": { - - "prefix": "namespace", - "body": [ - "namespace ${Name}", - "{", - " $0", - "}" - ], - "description": "Namespace" - }, - - "#if": { - - "prefix": "ifd", - "body": [ - "#if ${true}", - " $0", - "#endif" - ], - "description": "#if" - }, - - "#region": { - - "prefix": "region", - "body": [ - "#region ${Name}", - " $0", - "#endregion" - ], - "description": "#region" - }, - - "Property and backing field": { - - "prefix": "propfull", - "body": [ - "private ${int} ${myVar};", - - "public ${int} ${MyProperty}", - "{", - " get { return ${myVar};}", - " set { ${myVar} = value;}", - "}", - "$0" - ], - "description": "Property and backing field" - }, - - "propg": { - - "prefix": "propg", - "body": [ - "public ${int} ${MyProperty} { get; private set; }$0" - ], - "description": "An automatically implemented property with a 'get' accessor and a private 'set' accessor. C# 3.0 or higher" - }, - - "prop": { - - "prefix": "prop", - "body": [ - "public ${int} ${MyProperty} { get; set; }$0" - ], - "description": "An automatically implemented property. C# 3.0 or higher" - }, - - "sim": { - - "prefix": "sim", - "body": [ - "static int Main(string[] args)", - "{", - " $0", - " return 0;", - "}" - ], - "description": "int Main()" - }, - - "Struct": { - - "prefix": "struct", - "body": [ - "struct ${Name}", - "{", - " $0", - "}" - ], - "description": "Struct" - }, - - "svm": { - - "prefix": "svm", - "body": [ - "static void Main(string[] args)", - "{", - " $0", - "}" - ], - "description": "void Main()" - }, - - "Switch statement": { - - "prefix": "switch", - "body": [ - "switch (${switch_on})", - "{", - " $0", - " default:", - "}" - ], - "description": "Switch statement" - }, - - "Try finally": { - - "prefix": "tryf", - "body": [ - "try", - "{", - " ${_}", - "}", - "finally", - "{", - " $0", - "}" - ], - "description": "Try finally" - }, - - "Try catch": { - - "prefix": "try", - "body": [ - "try", - "{", - " ${_}", - "}", - "catch (${System.Exception})", - "{", - " $0", - " throw;", - "}" - ], - "description": "Try catch" - }, - - "Unchecked block": { - - "prefix": "unchecked", - "body": [ - "unchecked", - "{", - " $0", - "}" - ], - "description": "Unchecked block" - }, - - "Unsafe statement": { - - "prefix": "unsafe", - "body": [ - "unsafe", - "{", - " $0", - "}" - ], - "description": "Unsafe statement" - }, - - "Using statement": { - - "prefix": "using", - "body": [ - "using(${resource})", - "{", - " $0", - "}" - ], - "description": "Using statement" - }, - - "While loop": { - - "prefix": "while", - "body": [ - "while (${true})", - "{", - " $0", - "}" - ], - "description": "While loop" - }, - - "constructor": { - - "prefix": "ctor", - "body": [ - "${1:public} ${2:ClassName}(${3:Parameters})", - "{", - " ${0}", - "}" - ], - "description": "constructor" - }, + "Attribute using recommended pattern": { + + "prefix": "attribute", + "body": [ + "[System.AttributeUsage(System.AttributeTargets.${All}, Inherited = ${false}, AllowMultiple = ${true})]", + "sealed class ${My}Attribute : System.Attribute", + "{", + " // See the attribute guidelines at", + " // http://go.microsoft.com/fwlink/?LinkId=85236", + " readonly string positionalString;", + " ", + " // This is a positional argument", + " public ${My}Attribute (string positionalString)", + " {", + " this.positionalString = positionalString;", + " ", + " // TODO: Implement code here", + " ${throw new System.NotImplementedException();}", + " }", + " ", + " public string PositionalString", + " {", + " get { return positionalString; }", + " }", + " ", + " // This is a named argument", + " public int NamedInt { get; set; }", + "}" + ], + "description": "Attribute using recommended pattern" + }, + + "Checked block": { + + "prefix": "checked", + "body": [ + "checked", + "{", + " $0", + "}" + ], + "description": "Checked block" + }, + + "Class": { + + "prefix": "class", + "body": [ + "class ${Name}", + "{", + " $0", + "}" + ], + "description": "Class" + }, + + "Console.WriteLine": { + + "prefix": "cw", + "body": [ + "System.Console.WriteLine($0);" + ], + "description": "Console.WriteLine" + }, + + "do...while loop": { + + "prefix": "do", + "body": [ + "do", + "{", + " $0", + "} while (${true});" + ], + "description": "do...while loop" + }, + + "Else statement": { + + "prefix": "else", + "body": [ + "else", + "{", + " $0", + "}" + ], + "description": "Else statement" + }, + + "Enum": { + + "prefix": "enum", + "body": [ + "enum ${Name}", + "{", + " $0", + "}" + ], + "description": "Enum" + }, + + "Implementing Equals() according to guidelines": { + + "prefix": "equals", + "body": [ + "// override object.Equals", + "public override bool Equals (object obj)", + "{", + " //", + " // See the full list of guidelines at", + " // http://go.microsoft.com/fwlink/?LinkID=85237", + " // and also the guidance for operator== at", + " // http://go.microsoft.com/fwlink/?LinkId=85238", + " //", + " ", + " if (obj == null || GetType() != obj.GetType())", + " {", + " return false;", + " }", + " ", + " // TODO: write your implementation of Equals() here", + " ${1:throw new System.NotImplementedException();}", + " return base.Equals (obj);", + "}", + "", + "// override object.GetHashCode", + "public override int GetHashCode()", + "{", + " // TODO: write your implementation of GetHashCode() here", + " ${2:throw new System.NotImplementedException();}", + " return base.GetHashCode();", + "}" + ], + "description": "Implementing Equals() according to guidelines" + }, + + "Exception": { + + "prefix": "exception", + "body": [ + "[System.Serializable]", + "public class ${My}Exception : ${System.Exception}", + "{", + " public ${My}Exception() { }", + " public ${My}Exception( string message ) : base( message ) { }", + " public ${My}Exception( string message, System.Exception inner ) : base( message, inner ) { }", + " protected ${My}Exception(", + " System.Runtime.Serialization.SerializationInfo info,", + " System.Runtime.Serialization.StreamingContext context ) : base( info, context ) { }", + "}" + ], + "description": "Exception" + }, + + "Foreach statement": { + + "prefix": "foreach", + "body": [ + "foreach (${var} ${item} in ${collection})", + "{", + " $0", + "}" + ], + "description": "Foreach statement" + }, + + "Reverse for loop": { + + "prefix": "forr", + "body": [ + "for (int ${i} = ${length} - 1; ${i} >= 0 ; ${i}--)", + "{", + " $0", + "}" + ], + "description": "Reverse for loop" + }, + + "for loop": { + + "prefix": "for", + "body": [ + "for (int ${i} = 0; ${i} < ${length}; ${i}++)", + "{", + " $0", + "}" + ], + "description": "for loop" + }, + + "if statement": { + + "prefix": "if", + "body": [ + "if (${true})", + "{", + " $0", + "}" + ], + "description": "if statement" + }, + + "Indexer": { + + "prefix": "indexer", + "body": [ + "${public} ${object} this[${int} index]", + "{", + " get { $0 }", + " set { $1 }", + "}" + ], + "description": "Indexer" + }, + + "Interface": { + + "prefix": "interface", + "body": [ + "interface I${Name}", + "{", + " $0", + "}" + ], + "description": "Interface" + }, + + "Safely invoking an event": { + + "prefix": "invoke", + "body": [ + "${EventHandler} temp = ${MyEvent};", + "if (temp != null)", + "{", + " temp($0);", + "}" + ], + "description": "Safely invoking an event" + }, + + "Simple iterator": { + + "prefix": "iterator", + "body": [ + "public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()", + "{", + " $0throw new System.NotImplementedException();", + " yield return default(${ElementType});", + "}" + ], + "description": "Simple iterator" + }, + + "Named iterator/indexer pair using a nested class": { + + "prefix": "iterindex", + "body": [ + "public ${Name}Iterator ${Name}", + "{", + " get", + " {", + " return new ${Name}Iterator(this);", + " }", + "}", + "", + "public class ${Name}Iterator", + "{", + " readonly ${ClassName} outer;", + " ", + " internal ${Name}Iterator(${ClassName} outer)", + " {", + " this.outer = outer;", + " }", + " ", + " // TODO: provide an appropriate implementation here", + " public int Length { get { return 1; } }", + " ", + " public ${ElementType} this[int index]", + " {", + " get", + " {", + " //", + " // TODO: implement indexer here", + " //", + " // you have full access to ${ClassName} privates", + " //", + " ${throw new System.NotImplementedException();}", + " return default(${ElementType});", + " }", + " }", + " ", + " public System.Collections.Generic.IEnumerator<${ElementType}> GetEnumerator()", + " {", + " for (int i = 0; i < this.Length; i++)", + " {", + " yield return this[i];", + " }", + " }", + "}" + ], + "description": "Named iterator/indexer pair using a nested class" + }, + + "Lock statement": { + + "prefix": "lock", + "body": [ + "lock (${this})", + "{", + " $0", + "}" + ], + "description": "Lock statement" + }, + + "MessageBox.Show": { + + "prefix": "mbox", + "body": [ + "System.Windows.Forms.MessageBox.Show(\"${Text}\");$0" + ], + "description": "MessageBox.Show" + }, + + "Namespace": { + + "prefix": "namespace", + "body": [ + "namespace ${Name}", + "{", + " $0", + "}" + ], + "description": "Namespace" + }, + + "#if": { + + "prefix": "ifd", + "body": [ + "#if ${true}", + " $0", + "#endif" + ], + "description": "#if" + }, + + "#region": { + + "prefix": "region", + "body": [ + "#region ${Name}", + " $0", + "#endregion" + ], + "description": "#region" + }, + + "Property and backing field": { + + "prefix": "propfull", + "body": [ + "private ${int} ${myVar};", + + "public ${int} ${MyProperty}", + "{", + " get { return ${myVar};}", + " set { ${myVar} = value;}", + "}", + "$0" + ], + "description": "Property and backing field" + }, + + "propg": { + + "prefix": "propg", + "body": [ + "public ${int} ${MyProperty} { get; private set; }$0" + ], + "description": "An automatically implemented property with a 'get' accessor and a private 'set' accessor. C# 3.0 or higher" + }, + + "prop": { + + "prefix": "prop", + "body": [ + "public ${int} ${MyProperty} { get; set; }$0" + ], + "description": "An automatically implemented property. C# 3.0 or higher" + }, + + "sim": { + + "prefix": "sim", + "body": [ + "static int Main(string[] args)", + "{", + " $0", + " return 0;", + "}" + ], + "description": "int Main()" + }, + + "Struct": { + + "prefix": "struct", + "body": [ + "struct ${Name}", + "{", + " $0", + "}" + ], + "description": "Struct" + }, + + "svm": { + + "prefix": "svm", + "body": [ + "static void Main(string[] args)", + "{", + " $0", + "}" + ], + "description": "void Main()" + }, + + "Switch statement": { + + "prefix": "switch", + "body": [ + "switch (${switch_on})", + "{", + " $0", + " default:", + "}" + ], + "description": "Switch statement" + }, + + "Try finally": { + + "prefix": "tryf", + "body": [ + "try", + "{", + " ${_}", + "}", + "finally", + "{", + " $0", + "}" + ], + "description": "Try finally" + }, + + "Try catch": { + + "prefix": "try", + "body": [ + "try", + "{", + " ${_}", + "}", + "catch (${System.Exception})", + "{", + " $0", + " throw;", + "}" + ], + "description": "Try catch" + }, + + "Unchecked block": { + + "prefix": "unchecked", + "body": [ + "unchecked", + "{", + " $0", + "}" + ], + "description": "Unchecked block" + }, + + "Unsafe statement": { + + "prefix": "unsafe", + "body": [ + "unsafe", + "{", + " $0", + "}" + ], + "description": "Unsafe statement" + }, + + "Using statement": { + + "prefix": "using", + "body": [ + "using(${resource})", + "{", + " $0", + "}" + ], + "description": "Using statement" + }, + + "While loop": { + + "prefix": "while", + "body": [ + "while (${true})", + "{", + " $0", + "}" + ], + "description": "While loop" + }, + + "constructor": { + + "prefix": "ctor", + "body": [ + "${1:public} ${2:ClassName}(${3:Parameters})", + "{", + " ${0}", + "}" + ], + "description": "constructor" + }, "xUnit Test": { - "prefix": "fact", - "body": [ - "[Fact]", - "public void ${1:TestName}()", - "{", - "//Given", - "", - "//When", - "", - "//Then", - "}${0}" - ], - "description": "create xunit test method" - } + "prefix": "fact", + "body": [ + "[Fact]", + "public void ${1:TestName}()", + "{", + "//Given", + "", + "//When", + "", + "//Then", + "}${0}" + ], + "description": "create xunit test method" + } } From 140b1ef8a9c4bee93313863a50c17a43c8c5e62b Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 9 May 2017 07:55:03 -0700 Subject: [PATCH 16/31] Ensure children of OmniSharp server process are killed on Unix --- src/common.ts | 36 ++++++++++++++++++++++++++++++++++++ src/omnisharp/server.ts | 13 ++++++++++--- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/src/common.ts b/src/common.ts index b539099558..fbf5eda9c7 100644 --- a/src/common.ts +++ b/src/common.ts @@ -5,6 +5,7 @@ import * as cp from 'child_process'; import * as fs from 'fs'; +import * as os from 'os'; import * as path from 'path'; let extensionPath: string; @@ -60,6 +61,41 @@ export function execChildProcess(command: string, workingDirectory: string = get }); } +export function getUnixChildProcessIds(pid: number): Promise { + return new Promise((resolve, reject) => { + let ps = cp.exec('ps -A -o ppid,pid', (error, stdout, stderr) => + { + if (error) { + return reject(error); + } + + if (stderr) { + return reject(stderr); + } + + if (!stdout) { + return resolve([]); + } + + let lines = stdout.split(os.EOL); + let pairs = lines.map(line => line.trim().split(/\s+/)); + + let children = []; + + for (let pair of pairs) { + let ppid = parseInt(pair[0]); + if (ppid === pid) { + children.push(parseInt(pair[1])); + } + } + + resolve(children); + }); + + ps.on('error', reject); + }); +} + export function fileExists(filePath: string): Promise { return new Promise((resolve, reject) => { fs.stat(filePath, (err, stats) => { diff --git a/src/omnisharp/server.ts b/src/omnisharp/server.ts index a9c4fc0ab3..98c4447379 100644 --- a/src/omnisharp/server.ts +++ b/src/omnisharp/server.ts @@ -16,6 +16,7 @@ import TelemetryReporter from 'vscode-extension-telemetry'; import * as os from 'os'; import * as path from 'path'; import * as protocol from './protocol'; +import * as utils from '../common'; import * as vscode from 'vscode'; enum ServerState { @@ -337,9 +338,15 @@ export class OmniSharpServer { }); } else { - // Kill Unix process - this._serverProcess.kill('SIGTERM'); - cleanupPromise = Promise.resolve(); + // Kill Unix process and children + cleanupPromise = utils.getUnixChildProcessIds(this._serverProcess.pid) + .then(children => { + for (let child of children) { + process.kill(child, 'SIGTERM'); + } + + this._serverProcess.kill('SIGTERM'); + }); } return cleanupPromise.then(() => { From 9b1a4a62f66392a065b039e1b94cedcc8c78c134 Mon Sep 17 00:00:00 2001 From: Andrew Wang Date: Wed, 10 May 2017 10:39:46 -0700 Subject: [PATCH 17/31] Adding generateAssets to activationEvents (#1470) --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 62aa73b694..7a038f43ed 100644 --- a/package.json +++ b/package.json @@ -329,6 +329,7 @@ "onCommand:o.pickProjectAndStart", "onCommand:o.showOutput", "onCommand:dotnet.restore", + "onCommand:dotnet.generateAssets", "onCommand:csharp.downloadDebugger", "onCommand:csharp.listProcess", "onCommand:csharp.listRemoteProcess", @@ -2285,4 +2286,4 @@ } ] } -} \ No newline at end of file +} From 36fed38045866491bc176e8838bb45d9bc7da9fa Mon Sep 17 00:00:00 2001 From: Mike Mazmanyan Date: Thu, 11 May 2017 01:38:32 -0400 Subject: [PATCH 18/31] Updating completionItemProvider to use newly added items from CompletionItemKind enum --- package.json | 2 +- src/features/completionItemProvider.ts | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 7a038f43ed..15c893feed 100644 --- a/package.json +++ b/package.json @@ -321,7 +321,7 @@ } ], "engines": { - "vscode": "^1.10.1" + "vscode": "^1.12.0" }, "activationEvents": [ "onLanguage:csharp", diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index 060cece633..2958f337a0 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -90,7 +90,7 @@ _kinds['Class'] = CompletionItemKind.Class; _kinds['Delegate'] = CompletionItemKind.Class; // need a better option for this. _kinds['Enum'] = CompletionItemKind.Enum; _kinds['Interface'] = CompletionItemKind.Interface; -_kinds['Struct'] = CompletionItemKind.Class; // need a better option for this. +_kinds['Struct'] = CompletionItemKind.Struct; // variables _kinds['Local'] = CompletionItemKind.Variable; @@ -98,8 +98,8 @@ _kinds['Parameter'] = CompletionItemKind.Variable; _kinds['RangeVariable'] = CompletionItemKind.Variable; // members -_kinds['EnumMember'] = CompletionItemKind.Property; // need a better option for this. -_kinds['Event'] = CompletionItemKind.Field; // need a better option for this. +_kinds['EnumMember'] = CompletionItemKind.EnumMember; +_kinds['Event'] = CompletionItemKind.Event; _kinds['Field'] = CompletionItemKind.Field; _kinds['Property'] = CompletionItemKind.Property; _kinds['Method'] = CompletionItemKind.Method; From 875858a66cd49fd338e02d19f8489dfde336fc36 Mon Sep 17 00:00:00 2001 From: Abhitej Anoop John Bandi Date: Sat, 13 May 2017 02:28:10 +0530 Subject: [PATCH 19/31] Changes to enable MSTest based tests in vscode. --- src/features/dotnetTest.ts | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 947c123500..fc19b43857 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -184,10 +184,19 @@ export function updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: strin return; } - let testFeature = node.Features.find(value => (value.Name == 'XunitTestMethod' || value.Name == 'NUnitTestMethod')); + let testFeature = node.Features.find(value => (value.Name == 'XunitTestMethod' || value.Name == 'NUnitTestMethod' || value.Name == 'MSTestMethod')); if (testFeature) { // this test method has a test feature - let testFrameworkName = testFeature.Name == 'XunitTestMethod' ? 'xunit' : 'nunit'; + let testFrameworkName = 'xunit' + if(testFeature.Name == 'NunitTestMethod') + { + testFrameworkName = 'nunit'; + } + else if(testFeature.Name == 'MSTestMethod') + { + testFrameworkName = 'mstest' + } + bucket.push(new vscode.CodeLens( toRange(node.Location), { title: "run test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName, testFrameworkName] })); From 841b9a4a945b89bfbae8a297c3f500cb623d763f Mon Sep 17 00:00:00 2001 From: Abhitej Anoop John Bandi Date: Sun, 14 May 2017 00:52:50 +0530 Subject: [PATCH 20/31] nit fixes. --- src/features/dotnetTest.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index fc19b43857..488c124eb3 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -187,14 +187,14 @@ export function updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: strin let testFeature = node.Features.find(value => (value.Name == 'XunitTestMethod' || value.Name == 'NUnitTestMethod' || value.Name == 'MSTestMethod')); if (testFeature) { // this test method has a test feature - let testFrameworkName = 'xunit' + let testFrameworkName = 'xunit'; if(testFeature.Name == 'NunitTestMethod') { testFrameworkName = 'nunit'; } else if(testFeature.Name == 'MSTestMethod') { - testFrameworkName = 'mstest' + testFrameworkName = 'mstest'; } bucket.push(new vscode.CodeLens( From 78a89c0368cba1c83eb01be6e2d71551a66c3274 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Tue, 16 May 2017 17:52:09 -0700 Subject: [PATCH 21/31] Ensure that we log test messages while getting debug start info --- src/features/dotnetTest.ts | 41 ++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 488c124eb3..50c23d739e 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -108,7 +108,11 @@ function createLaunchConfiguration(program: string, args: string, cwd: string, d return result; } -function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener): Promise { +function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise { + // Listen for test messages while getting start info. + const disposable = server.onTestMessage(e => { + output.appendLine(e.Message); + }); const request: protocol.V2.DebugTestGetStartInfoRequest = { FileName: fileName, @@ -117,10 +121,18 @@ function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: stri }; return serverUtils.debugTestGetStartInfo(server, request) - .then(response => createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath())); + .then(response => { + disposable.dispose(); + return createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath()); + }); } -function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string): Promise { +function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, output: vscode.OutputChannel): Promise { + // Listen for test messages while getting start info. + const disposable = server.onTestMessage(e => { + output.appendLine(e.Message); + }); + const request: protocol.V2.GetTestStartInfoRequest = { FileName: fileName, MethodName: testMethod, @@ -128,16 +140,19 @@ function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: stri }; return serverUtils.getTestStartInfo(server, request) - .then(response => createLaunchConfiguration(response.Executable, response.Argument, response.WorkingDirectory, null)); + .then(response => { + disposable.dispose(); + return createLaunchConfiguration(response.Executable, response.Argument, response.WorkingDirectory, null); + }); } -function getLaunchConfiguration(server: OmniSharpServer, debugType: string, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener): Promise { +function getLaunchConfiguration(server: OmniSharpServer, debugType: string, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise { switch (debugType) { case "legacy": - return getLaunchConfigurationForLegacy(server, fileName, testMethod, testFrameworkName); + return getLaunchConfigurationForLegacy(server, fileName, testMethod, testFrameworkName, output); case "vstest": - return getLaunchConfigurationForVSTest(server, fileName, testMethod, testFrameworkName, debugEventListener); + return getLaunchConfigurationForVSTest(server, fileName, testMethod, testFrameworkName, debugEventListener, output); default: throw new Error(`Unexpected debug type: ${debugType}`); @@ -150,8 +165,10 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew // using VS Test. These require a different level of communication. let debugType: string; let debugEventListener: DebugEventListener = null; - let outputChannel = getTestOutputChannel(); - outputChannel.appendLine(`Debugging method '${testMethod}'.`); + + const output = getTestOutputChannel(); + + output.appendLine(`Debugging method '${testMethod}'.`); return serverUtils.requestProjectInformation(server, { FileName: fileName }) .then(projectInfo => { @@ -161,14 +178,14 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew } else if (projectInfo.MsBuildProject) { debugType = "vstest"; - debugEventListener = new DebugEventListener(fileName, server, outputChannel); + debugEventListener = new DebugEventListener(fileName, server, output); return debugEventListener.start(); } else { throw new Error(); } }) - .then(() => getLaunchConfiguration(server, debugType, fileName, testMethod, testFrameworkName, debugEventListener)) + .then(() => getLaunchConfiguration(server, debugType, fileName, testMethod, testFrameworkName, debugEventListener, output)) .then(config => vscode.commands.executeCommand('vscode.startDebug', config)) .catch(reason => { vscode.window.showErrorMessage(`Failed to start debugger: ${reason}`); @@ -238,6 +255,7 @@ class DebugEventListener { if (DebugEventListener.s_activeInstance !== null) { DebugEventListener.s_activeInstance.close(); } + DebugEventListener.s_activeInstance = this; this._serverSocket = net.createServer((socket: net.Socket) => { @@ -280,6 +298,7 @@ class DebugEventListener { this._outputChannel.appendLine("Warning: Communications error on debugger event channel. " + err.message); } }); + this._serverSocket.listen(this._pipePath, () => { isStarted = true; resolve(); From f4eadebf2bec5fd13a7e6adde8e1426a8bd7cf1b Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 17 May 2017 11:23:02 -0700 Subject: [PATCH 22/31] 1.10.0-beta2 -> 1.10.0-beta3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 15c893feed..b05565bab4 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.10.0-beta2", + "version": "1.10.0-beta3", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", From 83a9c159867cf5b143ef5ef898626814440445a5 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 17 May 2017 11:23:14 -0700 Subject: [PATCH 23/31] Update changelog for v1.10-beta3 --- CHANGELOG.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9588629b0..89165f15e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,11 +13,15 @@ * Object initializer members now appear in the completion list. ([#260](https://github.com/OmniSharp/omnisharp-vscode/issues/260)) * Completion appears within XML doc comment CREFs. * Initial support for completion on 'override' and 'partial' keywords. ([#1044](https://github.com/OmniSharp/omnisharp-vscode/issues/1044)) +* New VS Code completion item glyphs (e.g. struct, event, etc.) are supported. (PR: [#1472](https://github.com/OmniSharp/omnisharp-vscode/pull/1472)) _(Contributed by [@dopare](https://github.com/dopare))_ #### Project System * Project references to projects located outside of the current workspace directory are now loaded and processed. ([#963](https://github.com/OmniSharp/omnisharp-vscode/issues/963), PR: [omnisharp-roslyn#832](https://github.com/OmniSharp/omnisharp-vscode/issues/963)) * OmniSharp now loads .NET Core projects using the SDKs included with the .NET Core SDK appropriate for that project, if they're installed on the machine. ([#1438](https://github.com/OmniSharp/omnisharp-vscode/issues/1438), [omnisharp-roslyn#765](https://github.com/OmniSharp/omnisharp-roslyn/issues/765), PR: [omnisharp-roslyn#847](https://github.com/OmniSharp/omnisharp-roslyn/pull/847)) +* Options can now be set in an omnisharp.json to specify the Configuration (e.g. Debug) and Platform (e.g. AnyCPU) that MSBuild should use. ([omnisharp-roslyn#202](https://github.com/OmniSharp/omnisharp-roslyn/issues/202), PR: [omnisharp-roslyn#858](https://github.com/OmniSharp/omnisharp-roslyn/pull/858)) _(Contributed by [@nanoant](https://github.com/nanoant))_ +* Fixed issue where a package reference would be reported as an unresolved dependency if the reference differed from the intended dependency by case (PR: [#861](https://github.com/OmniSharp/omnisharp-roslyn/pull/861)) +* Cleaned up unresolved dependency detection in OmniSharp and added logging to help diagnose project issues. ([#1272](https://github.com/OmniSharp/omnisharp-vscode/issues/1272), PR: [#861](https://github.com/OmniSharp/omnisharp-roslyn/pull/862)) #### Scripting @@ -25,15 +29,20 @@ #### Unit Testing +* MSTest support added ([#1482](https://github.com/OmniSharp/omnisharp-vscode/issues/1482), PRs: [#1478](https://github.com/OmniSharp/omnisharp-vscode/pull/1478), [omnisharp-roslyn#856](https://github.com/OmniSharp/omnisharp-roslyn/pull/856)) _(Contributed by [@AbhitejJohn](https://github.com/AbhitejJohn))_ * Add support for NUnit Test Adapter. ([#1434](https://github.com/OmniSharp/omnisharp-vscode/issues/1434), PR: [omnisharp-roslyn#834](https://github.com/OmniSharp/omnisharp-roslyn/pull/834)) * Tests that define display names are now run properly. ([#1426](https://github.com/OmniSharp/omnisharp-vscode/issues/1426), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) * Tests with similar names are no longer incorrectly run together when one of them is clicked. ([#1432](https://github.com/OmniSharp/omnisharp-vscode/issues/1432), PR: [omnisharp-roslyn#833](https://github.com/OmniSharp/omnisharp-roslyn/pull/833)) -* Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PR: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436)) +* Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PRs: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436), [#1486](https://github.com/OmniSharp/omnisharp-vscode/pull/1486)) * Added `csharp.unitTestDebugingOptions` setting to pass launch.json-style debug options (example: `justMyCode`) when unit test debugging. #### Other Updates and Fixes * New `csharp.suppressHiddenDiagnostics` setting that can be set to true to display hidden diagnostics, such as 'unnecessary using directive'. ([#1429](https://github.com/OmniSharp/omnisharp-vscode/issues/1429), PR: [#1435](https://github.com/OmniSharp/omnisharp-vscode/pull/1435)) _(Contributed by [@cruz82](https://github.com/cruz82))_ +* Fix issue causing several code snippets to not be available. ([#1459](https://github.com/OmniSharp/omnisharp-vscode/issues/1459), PR: [#1461](https://github.com/OmniSharp/omnisharp-vscode/pull/1461)) _(Contributed by [@shaunluttin](https://github.com/shaunluttin))_ +* Ensure the 'Generate Assets for Build and Debug' command can cause the extension to activate. (PR: [#1470](https://github.com/OmniSharp/omnisharp-vscode/pull/1470)) +* The OmniSharp process is now correctly terminated on Unix when the 'Restart OmniSharp' command is invoked. ([#1445](https://github.com/OmniSharp/omnisharp-vscode/issues/1445), PR: [#1466](https://github.com/OmniSharp/omnisharp-vscode/pull/1466)) +* Added new `RoslynExtensions` option to allow specifying a set of assemblies in an omnisharp.json file that OmniSharp will look in to find Roslyn extensions to load. (PR: [omnisharp-roslyn#848](https://github.com/OmniSharp/omnisharp-roslyn/pull/848)) _(Contributed by [@filipw](https://github.com/filipw))_ ## 1.9.0 (April 20, 2017) From 2a182d874bfe5e29785adda45c459f35496abf46 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Wed, 17 May 2017 13:11:42 -0700 Subject: [PATCH 24/31] Update OmniSharp to 1.18 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index b05565bab4..186e9bf6dd 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.17.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.18.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -135,7 +135,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.17.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.18.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -147,7 +147,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.17.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.18.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", From f01e4f89ad32a4874b0e0b1784bea2ea44fb3d26 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 18 May 2017 09:25:32 -0700 Subject: [PATCH 25/31] Ensure that we save files before running or debugging tests --- src/features/dotnetTest.ts | 122 +++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 53 deletions(-) diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts index 50c23d739e..5d2948ec3b 100644 --- a/src/features/dotnetTest.ts +++ b/src/features/dotnetTest.ts @@ -17,7 +17,7 @@ import * as path from 'path'; let _testOutputChannel: vscode.OutputChannel = undefined; function getTestOutputChannel(): vscode.OutputChannel { - if (_testOutputChannel == undefined) { + if (_testOutputChannel === undefined) { _testOutputChannel = vscode.window.createOutputChannel(".NET Test Log"); } @@ -36,51 +36,66 @@ export function registerDotNetTestDebugCommand(server: OmniSharpServer): vscode. (testMethod, fileName, testFrameworkName) => debugDotnetTest(testMethod, fileName, testFrameworkName, server)); } -// Run test through dotnet-test command. This function can be moved to a separate structure -export function runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, server: OmniSharpServer) { - const output = getTestOutputChannel(); - - output.show(); - output.appendLine(`Running test ${testMethod}...`); - - const disposable = server.onTestMessage(e => { - output.appendLine(e.Message); - }); +function saveDirtyFiles(): Promise { + return Promise.resolve( + vscode.workspace.saveAll(/*includeUntitled*/ false)); +} +function runTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string): Promise { const request: protocol.V2.RunTestRequest = { FileName: fileName, MethodName: testMethod, TestFrameworkName: testFrameworkName }; - serverUtils.runTest(server, request) - .then(response => { - const totalTests = response.Results.length; + return serverUtils.runTest(server, request) + .then(response => response.Results); +} - let totalPassed = 0, totalFailed = 0, totalSkipped = 0; - for (let result of response.Results) { - switch (result.Outcome) { - case protocol.V2.TestOutcomes.Failed: - totalFailed += 1; - break; - case protocol.V2.TestOutcomes.Passed: - totalPassed += 1; - break; - case protocol.V2.TestOutcomes.Skipped: - totalSkipped += 1; - break; - } - } +function reportResults(results: protocol.V2.DotNetTestResult[], output: vscode.OutputChannel): Promise { + const totalTests = results.length; + + let totalPassed = 0, totalFailed = 0, totalSkipped = 0; + for (let result of results) { + switch (result.Outcome) { + case protocol.V2.TestOutcomes.Failed: + totalFailed += 1; + break; + case protocol.V2.TestOutcomes.Passed: + totalPassed += 1; + break; + case protocol.V2.TestOutcomes.Skipped: + totalSkipped += 1; + break; + } + } - output.appendLine(''); - output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`); - output.appendLine(''); + output.appendLine(''); + output.appendLine(`Total tests: ${totalTests}. Passed: ${totalPassed}. Failed: ${totalFailed}. Skipped: ${totalSkipped}`); + output.appendLine(''); - disposable.dispose(); - }, - reason => { + return Promise.resolve(); +} + +// Run test through dotnet-test command. This function can be moved to a separate structure +export function runDotnetTest(testMethod: string, fileName: string, testFrameworkName: string, server: OmniSharpServer) { + const output = getTestOutputChannel(); + + output.show(); + output.appendLine(`Running test ${testMethod}...`); + output.appendLine(''); + + const listener = server.onTestMessage(e => { + output.appendLine(e.Message); + }); + + saveDirtyFiles() + .then(_ => runTest(server, fileName, testMethod, testFrameworkName)) + .then(results => reportResults(results, output)) + .then(() => listener.dispose()) + .catch(reason => { + listener.dispose(); vscode.window.showErrorMessage(`Failed to run test because ${reason}.`); - disposable.dispose(); }); } @@ -88,7 +103,7 @@ function createLaunchConfiguration(program: string, args: string, cwd: string, d let debugOptions = vscode.workspace.getConfiguration('csharp').get('unitTestDebugingOptions'); // Get the initial set of options from the workspace setting - let result:any; + let result: any; if (typeof debugOptions === "object") { // clone the options object to avoid changing it result = JSON.parse(JSON.stringify(debugOptions)); @@ -110,7 +125,7 @@ function createLaunchConfiguration(program: string, args: string, cwd: string, d function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise { // Listen for test messages while getting start info. - const disposable = server.onTestMessage(e => { + const listener = server.onTestMessage(e => { output.appendLine(e.Message); }); @@ -122,14 +137,14 @@ function getLaunchConfigurationForVSTest(server: OmniSharpServer, fileName: stri return serverUtils.debugTestGetStartInfo(server, request) .then(response => { - disposable.dispose(); + listener.dispose(); return createLaunchConfiguration(response.FileName, response.Arguments, response.WorkingDirectory, debugEventListener.pipePath()); }); } function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: string, testMethod: string, testFrameworkName: string, output: vscode.OutputChannel): Promise { // Listen for test messages while getting start info. - const disposable = server.onTestMessage(e => { + const listener = server.onTestMessage(e => { output.appendLine(e.Message); }); @@ -141,7 +156,7 @@ function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: stri return serverUtils.getTestStartInfo(server, request) .then(response => { - disposable.dispose(); + listener.dispose(); return createLaunchConfiguration(response.Executable, response.Argument, response.WorkingDirectory, null); }); } @@ -149,9 +164,9 @@ function getLaunchConfigurationForLegacy(server: OmniSharpServer, fileName: stri function getLaunchConfiguration(server: OmniSharpServer, debugType: string, fileName: string, testMethod: string, testFrameworkName: string, debugEventListener: DebugEventListener, output: vscode.OutputChannel): Promise { switch (debugType) { - case "legacy": + case 'legacy': return getLaunchConfigurationForLegacy(server, fileName, testMethod, testFrameworkName, output); - case "vstest": + case 'vstest': return getLaunchConfigurationForVSTest(server, fileName, testMethod, testFrameworkName, debugEventListener, output); default: @@ -168,21 +183,24 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew const output = getTestOutputChannel(); - output.appendLine(`Debugging method '${testMethod}'.`); + output.show(); + output.appendLine(`Debugging method '${testMethod}'...`); + output.appendLine(''); - return serverUtils.requestProjectInformation(server, { FileName: fileName }) + return saveDirtyFiles() + .then(_ => serverUtils.requestProjectInformation(server, { FileName: fileName })) .then(projectInfo => { if (projectInfo.DotNetProject) { - debugType = "legacy"; + debugType = 'legacy'; return Promise.resolve(); } else if (projectInfo.MsBuildProject) { - debugType = "vstest"; + debugType = 'vstest'; debugEventListener = new DebugEventListener(fileName, server, output); return debugEventListener.start(); } else { - throw new Error(); + throw new Error('Expected project.json or .csproj project.'); } }) .then(() => getLaunchConfiguration(server, debugType, fileName, testMethod, testFrameworkName, debugEventListener, output)) @@ -197,7 +215,7 @@ export function debugDotnetTest(testMethod: string, fileName: string, testFramew export function updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: string, node: protocol.Node, isDebugEnable: boolean) { // backward compatible check: Features property doesn't present on older version OmniSharp - if (node.Features == undefined) { + if (node.Features === undefined) { return; } @@ -205,15 +223,13 @@ export function updateCodeLensForTest(bucket: vscode.CodeLens[], fileName: strin if (testFeature) { // this test method has a test feature let testFrameworkName = 'xunit'; - if(testFeature.Name == 'NunitTestMethod') - { + if (testFeature.Name == 'NunitTestMethod') { testFrameworkName = 'nunit'; } - else if(testFeature.Name == 'MSTestMethod') - { + else if (testFeature.Name == 'MSTestMethod') { testFrameworkName = 'mstest'; } - + bucket.push(new vscode.CodeLens( toRange(node.Location), { title: "run test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName, testFrameworkName] })); From 5f0c1dcd897b58f3c6ef00114d7b50dc577b228e Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 18 May 2017 11:03:17 -0700 Subject: [PATCH 26/31] Add default completion commit characters --- src/features/completionItemProvider.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index 2958f337a0..dfec97e340 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -14,6 +14,12 @@ import {CompletionItemProvider, CompletionItem, CompletionItemKind, Cancellation export default class OmniSharpCompletionItemProvider extends AbstractSupport implements CompletionItemProvider { + // copied from Roslyn here: https://github.com/dotnet/roslyn/blob/6e8f6d600b6c4bc0b92bc3d782a9e0b07e1c9f8e/src/Features/Core/Portable/Completion/CompletionRules.cs#L166-L169 + private static DefaultCommitCharacters = [ + ' ', '{', '}', '[', ']', '(', ')', '.', ',', ':', + ';', '+', '-', '*', '/', '%', '&', '|', '^', '!', + '~', '=', '<', '>', '?', '@', '#', '\'', '\"', '\\']; + public provideCompletionItems(document: TextDocument, position: Position, token: CancellationToken): Promise { let wordToComplete = ''; @@ -49,6 +55,7 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp completion.documentation = extractSummaryText(response.Description); completion.kind = _kinds[response.Kind] || CompletionItemKind.Property; completion.insertText = response.CompletionText.replace(/<>/g, ''); + completion.commitCharacters = OmniSharpCompletionItemProvider.DefaultCommitCharacters; let array = completions[completion.label]; if (!array) { From 37255ef0551e3e4abce8b5cf14c9b565bc586e76 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 18 May 2017 14:22:44 -0700 Subject: [PATCH 27/31] Remove old keybindings for accepting completion --- package.json | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/package.json b/package.json index 186e9bf6dd..30ca8b47ee 100644 --- a/package.json +++ b/package.json @@ -553,21 +553,6 @@ "command": "o.showOutput", "key": "Ctrl+L L", "mac": "Cmd+L L" - }, - { - "key": "shift+0", - "command": "^acceptSelectedSuggestion", - "when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey" - }, - { - "key": "shift+9", - "command": "^acceptSelectedSuggestion", - "when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey" - }, - { - "key": ".", - "command": "^acceptSelectedSuggestion", - "when": "editorTextFocus && suggestWidgetVisible && editorLangId == 'csharp' && suggestionSupportsAcceptOnKey" } ], "snippets": [ From 6123fc7207d702939fc3030f92bc47cfa9387703 Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Thu, 18 May 2017 15:39:40 -0700 Subject: [PATCH 28/31] A few tweaks that will work when OmniSharp is updated --- src/features/completionItemProvider.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/features/completionItemProvider.ts b/src/features/completionItemProvider.ts index dfec97e340..f2ce919967 100644 --- a/src/features/completionItemProvider.ts +++ b/src/features/completionItemProvider.ts @@ -46,7 +46,7 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp // transform AutoCompleteResponse to CompletionItem and // group by code snippet for (let response of responses) { - let completion = new CompletionItem(response.DisplayText); + let completion = new CompletionItem(response.CompletionText); completion.detail = response.ReturnType ? `${response.ReturnType} ${response.DisplayText}` @@ -105,11 +105,12 @@ _kinds['Parameter'] = CompletionItemKind.Variable; _kinds['RangeVariable'] = CompletionItemKind.Variable; // members +_kinds['Const'] = CompletionItemKind.Constant; _kinds['EnumMember'] = CompletionItemKind.EnumMember; _kinds['Event'] = CompletionItemKind.Event; _kinds['Field'] = CompletionItemKind.Field; -_kinds['Property'] = CompletionItemKind.Property; _kinds['Method'] = CompletionItemKind.Method; +_kinds['Property'] = CompletionItemKind.Property; // other stuff _kinds['Label'] = CompletionItemKind.Unit; // need a better option for this. From 4c827b3b19428ab2191441c09ee2be9d7de91e67 Mon Sep 17 00:00:00 2001 From: Gregg Miskelly Date: Thu, 18 May 2017 23:41:05 -0700 Subject: [PATCH 29/31] Update the debugger to 1-10-1 This updates the debugger package to new zips, updates the version number, and adds details to the changelog. --- CHANGELOG.md | 4 ++++ package.json | 50 +++++++++++++++++++++++++------------------------- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 89165f15e0..0caa43f413 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,10 @@ * Improve response from running/debugging tests to include output from build and test summary. ([#419](https://github.com/OmniSharp/omnisharp-vscode/issues/419), [#455](https://github.com/OmniSharp/omnisharp-vscode/issues/455), PRs: [#1436](https://github.com/OmniSharp/omnisharp-vscode/pull/1436), [#1486](https://github.com/OmniSharp/omnisharp-vscode/pull/1486)) * Added `csharp.unitTestDebugingOptions` setting to pass launch.json-style debug options (example: `justMyCode`) when unit test debugging. +#### Debugger +* Resolves crash on OSX when the target process loads an embedded PDB ([#1456](https://github.com/OmniSharp/omnisharp-vscode/issues/1456)). This commonly affects users trying to debug XUnit tests. +* Enhanced exception peek display to provide additional exception properties. + #### Other Updates and Fixes * New `csharp.suppressHiddenDiagnostics` setting that can be set to true to display hidden diagnostics, such as 'unnecessary using directive'. ([#1429](https://github.com/OmniSharp/omnisharp-vscode/issues/1429), PR: [#1435](https://github.com/OmniSharp/omnisharp-vscode/pull/1435)) _(Contributed by [@cruz82](https://github.com/cruz82))_ diff --git a/package.json b/package.json index 186e9bf6dd..3e0ba58ca3 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.10.0-beta3", + "version": "1.10.0-beta4", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation", @@ -157,8 +157,8 @@ }, { "description": ".NET Core Debugger (Windows / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-win7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-win7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-win7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-win7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "win7-x64" @@ -167,8 +167,8 @@ }, { "description": ".NET Core Debugger (macOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-osx.10.11-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-osx.10.11-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-osx.10.11-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-osx.10.11-x64.zip", "installPath": ".debugger", "runtimeIds": [ "osx.10.11-x64" @@ -181,8 +181,8 @@ }, { "description": ".NET Core Debugger (CentOS / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-centos.7-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-centos.7-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-centos.7-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-centos.7-x64.zip", "installPath": ".debugger", "runtimeIds": [ "centos.7-x64" @@ -195,8 +195,8 @@ }, { "description": ".NET Core Debugger (Debian / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-debian.8-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-debian.8-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-debian.8-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-debian.8-x64.zip", "installPath": ".debugger", "runtimeIds": [ "debian.8-x64" @@ -209,8 +209,8 @@ }, { "description": ".NET Core Debugger (Fedora 23 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-fedora.23-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-fedora.23-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-fedora.23-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-fedora.23-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.23-x64" @@ -223,8 +223,8 @@ }, { "description": ".NET Core Debugger (Fedora 24 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-fedora.24-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-fedora.24-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-fedora.24-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-fedora.24-x64.zip", "installPath": ".debugger", "runtimeIds": [ "fedora.24-x64" @@ -237,8 +237,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 13 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.13.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.13.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-opensuse.13.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-opensuse.13.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.13.2-x64" @@ -251,8 +251,8 @@ }, { "description": ".NET Core Debugger (OpenSUSE 42 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.42.1-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-opensuse.42.1-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-opensuse.42.1-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-opensuse.42.1-x64.zip", "installPath": ".debugger", "runtimeIds": [ "opensuse.42.1-x64" @@ -265,8 +265,8 @@ }, { "description": ".NET Core Debugger (RHEL / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-rhel.7.2-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-rhel.7.2-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-rhel.7.2-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-rhel.7.2-x64.zip", "installPath": ".debugger", "runtimeIds": [ "rhel.7-x64" @@ -279,8 +279,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 14.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.14.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.14.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.14.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.14.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.14.04-x64" @@ -293,8 +293,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.04 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.04-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.04-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.16.04-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.16.04-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.04-x64" @@ -307,8 +307,8 @@ }, { "description": ".NET Core Debugger (Ubuntu 16.10 / x64)", - "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.10-x64.zip", - "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-0/coreclr-debug-ubuntu.16.10-x64.zip", + "url": "https://vsdebugger.azureedge.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.16.10-x64.zip", + "fallbackUrl": "https://vsdebugger.blob.core.windows.net/coreclr-debug-1-10-1/coreclr-debug-ubuntu.16.10-x64.zip", "installPath": ".debugger", "runtimeIds": [ "ubuntu.16.10-x64" From 0cc8a005fc5aaab1bf4b977b5d7c096d8aadb82c Mon Sep 17 00:00:00 2001 From: Dustin Campbell Date: Fri, 19 May 2017 07:22:41 -0700 Subject: [PATCH 30/31] Update to OmniSharp 1.19 --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index dbddcfaa49..0a2417c38a 100644 --- a/package.json +++ b/package.json @@ -123,7 +123,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x86)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.18.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x86-1.19.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -135,7 +135,7 @@ }, { "description": "OmniSharp (.NET 4.6 / x64)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.18.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-win-x64-1.19.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "win32" @@ -147,7 +147,7 @@ }, { "description": "OmniSharp (Mono 4.6)", - "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.18.0.zip", + "url": "https://omnisharpdownload.blob.core.windows.net/ext/omnisharp-mono-1.19.0.zip", "installPath": "./bin/omnisharp", "platforms": [ "darwin", From 0697417fe2a754e4d15818dc5e55d67f046976e7 Mon Sep 17 00:00:00 2001 From: Gregg Miskelly Date: Mon, 22 May 2017 14:32:18 -0700 Subject: [PATCH 31/31] Add more files to .vscodeignore (#1505) This adds more files to the .vscodeignore file. Most importantly this excludes gulpfile.js as Windows Defender doesn't like it. --- .vscodeignore | 3 +++ package.json | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.vscodeignore b/.vscodeignore index b1f9ecfada..72116c06e2 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -8,6 +8,9 @@ src/** .gitignore .travis.yml tsconfig.json +ISSUE_TEMPLATE +tslint.json +gulpfile.js **/.nyc_output/** **/coverage/** diff --git a/package.json b/package.json index 0a2417c38a..b9fc3c5014 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "csharp", "publisher": "ms-vscode", - "version": "1.10.0-beta4", + "version": "1.10.0-beta5", "description": "C# for Visual Studio Code (powered by OmniSharp).", "displayName": "C#", "author": "Microsoft Corporation",