diff --git a/README.md b/README.md
index b5708cd6e1..5d325f42c5 100644
--- a/README.md
+++ b/README.md
@@ -24,6 +24,18 @@ Please file any issues at https://github.com/OmniSharp/omnisharp-vscode/issues.
### Debugging
The C# extension now supports basic debugging capabilities! See http://aka.ms/vscclrdebugger for details.
+### What's new in C# extension version 1.1
+
+* Preliminary support for `dotnet test`
+* Fix for OmniSharp installation problems on networks with an http proxy
+* Debugger support for an external console
+* Debugger support for environment variables
+* Support for debugging .NET Core 1.0.0 post RC2 builds
+* Automatic web vs. console debugger configuration detection
+* Detach support
+* Fix expression evaluation errors when referencing assemblies which aren't currently loaded
+* Fix expression evaluation on Windows 7
+
### Development
First install:
diff --git a/coreclr-debug/NuGet.config b/coreclr-debug/NuGet.config
index 5db080cb7d..045c4497c2 100644
--- a/coreclr-debug/NuGet.config
+++ b/coreclr-debug/NuGet.config
@@ -4,5 +4,7 @@
+
+
diff --git a/debugger.md b/debugger.md
index d548941c09..691c1f5ab9 100644
--- a/debugger.md
+++ b/debugger.md
@@ -116,9 +116,21 @@ You can optionally configure a file by file mapping by providing map following t
"sourceFileMap": {
"C:\foo":"/home/me/foo"
- }
+ }
#####Symbol Path
You can optionally provide paths to symbols following this schema:
"symbolPath":"[ \"/Volumes/symbols\"]"
+
+#####Environment variables
+Environment variables may be passed to your program using this schema:
+
+ "env": {
+ "myVariableName":"theValueGoesHere"
+ }
+
+#####External console (terminal) window
+The target process can optionally launch into a seperate console window. You will want this if your console app takes console input (ex: Console.ReadLine). This can be enabled with:
+
+ "externalConsole": true
diff --git a/package.json b/package.json
index 6a270cbeea..3171c4aa97 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "csharp",
"publisher": "ms-vscode",
- "version": "1.0.12",
+ "version": "1.1.4",
"description": "C# for Visual Studio Code (powered by OmniSharp).",
"displayName": "C#",
"author": "Microsoft Corporation",
@@ -22,7 +22,7 @@
"postinstall": "tsc"
},
"dependencies": {
- "decompress": "^3.0.0",
+ "decompress": "^4.0.0",
"del": "^2.0.2",
"fs-extra-promise": "^0.3.1",
"http-proxy-agent": "^1.0.0",
@@ -263,6 +263,17 @@
}
}
},
+ "env": {
+ "type": "object",
+ "additionalProperties": { "type": "string" },
+ "description": "Environment variables passed to the program.",
+ "default": { }
+ },
+ "externalConsole": {
+ "type": "boolean",
+ "description": "If 'true' the debugger should launch the target application into a new external console.",
+ "default": false
+ },
"sourceFileMap": {
"type": "object",
"description": "Optional source file mappings passed to the debug engine. Example: '{ \"C:\\foo\":\"/home/user/foo\" }'",
@@ -282,6 +293,98 @@
"type": "string"
},
"default": []
+ },
+ "pipeTransport": {
+ "type": "object",
+ "description": "When present, this tells the debugger to connect to a remote computer using another executable as a pipe that will relay standard input/output between VS Code and the .NET Core debugger backend executable (clrdbg).",
+ "default": {
+ "pipeProgram": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'",
+ "pipeArgs": []
+ },
+ "properties" : {
+ "pipeProgram": {
+ "type": "string",
+ "description": "The fully qualified pipe command to execute.",
+ "default": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'"
+ },
+ "pipeArgs": {
+ "type": "array",
+ "description": "Command line arguments passed to the pipe program.",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ },
+ "windows": {
+ "type": "object",
+ "description": "Windows-specific pipe launch configuration options",
+ "default": {
+ "pipeProgram": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'",
+ "pipeArgs": []
+ },
+ "properties": {
+ "pipeProgram": {
+ "type": "string",
+ "description": "The fully qualified pipe command to execute.",
+ "default": "enter the fully qualified path for the pipe program name, for example 'c:\\tools\\plink.exe'"
+ },
+ "pipeArgs": {
+ "type": "array",
+ "description": "Command line arguments passed to the pipe program.",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ }
+ }
+ },
+ "osx": {
+ "type": "object",
+ "description": "OSX-specific pipe launch configuration options",
+ "default": {
+ "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
+ "pipeArgs": []
+ },
+ "properties": {
+ "pipeProgram": {
+ "type": "string",
+ "description": "The fully qualified pipe command to execute.",
+ "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.",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ }
+ }
+ },
+ "linux": {
+ "type": "object",
+ "description": "Linux-specific pipe launch configuration options",
+ "default": {
+ "pipeProgram": "enter the fully qualified path for the pipe program name, for example '/usr/bin/ssh'",
+ "pipeArgs": []
+ },
+ "properties": {
+ "pipeProgram": {
+ "type": "string",
+ "description": "The fully qualified pipe command to execute.",
+ "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.",
+ "items": {
+ "type": "string"
+ },
+ "default": []
+ }
+ }
+ }
+ }
}
}
},
@@ -330,7 +433,8 @@
"program": "${workspaceRoot}/bin/Debug//",
"args": [],
"cwd": "${workspaceRoot}",
- "stopAtEntry": false
+ "stopAtEntry": false,
+ "externalConsole": false
},
{
"name": ".NET Core Launch (web)",
@@ -354,6 +458,9 @@
"linux": {
"command": "xdg-open"
}
+ },
+ "env": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
}
},
{
diff --git a/src/assets.ts b/src/assets.ts
index b921a533ce..29172eaf18 100644
--- a/src/assets.ts
+++ b/src/assets.ts
@@ -24,7 +24,9 @@ interface ConsoleLaunchConfiguration extends DebugConfiguration {
program: string,
args: string[],
cwd: string,
- stopAtEntry: boolean
+ stopAtEntry: boolean,
+ env?: any,
+ externalConsole?: boolean
}
interface CommandLine {
@@ -137,6 +139,7 @@ function createLaunchConfiguration(targetFramework: string, executableName: stri
program: '${workspaceRoot}/bin/Debug/' + targetFramework + '/'+ executableName,
args: [],
cwd: '${workspaceRoot}',
+ externalConsole: false,
stopAtEntry: false
}
}
@@ -164,6 +167,9 @@ function createWebLaunchConfiguration(targetFramework: string, executableName: s
linux: {
command: 'xdg-open'
}
+ },
+ env: {
+ ASPNETCORE_ENVIRONMENT: "Development"
}
}
}
@@ -177,14 +183,25 @@ function createAttachConfiguration(): AttachConfiguration {
}
}
-function createLaunchJson(targetFramework: string, executableName: string): any {
- return {
- version: '0.2.0',
- configurations: [
- createLaunchConfiguration(targetFramework, executableName),
- createWebLaunchConfiguration(targetFramework, executableName),
- createAttachConfiguration()
- ]
+function createLaunchJson(targetFramework: string, executableName: string, isWebProject: boolean): any {
+ let version = '0.2.0';
+ if (!isWebProject) {
+ return {
+ version: version,
+ configurations: [
+ createLaunchConfiguration(targetFramework, executableName),
+ createAttachConfiguration()
+ ]
+ }
+ }
+ else {
+ return {
+ version: version,
+ configurations: [
+ createWebLaunchConfiguration(targetFramework, executableName),
+ createAttachConfiguration()
+ ]
+ }
}
}
@@ -220,7 +237,24 @@ function addTasksJsonIfNecessary(info: protocol.DotNetWorkspaceInformation, path
});
}
-function addLaunchJsonIfNecessary(info: protocol.DotNetWorkspaceInformation, paths: Paths, operations: Operations) {
+function hasWebServerDependency(projectJsonPath: string) {
+ let projectJson = fs.readFileSync(projectJsonPath, 'utf8');
+ let projectJsonObject = JSON.parse(projectJson);
+
+ if (projectJsonObject == null) {
+ return false;
+ }
+
+ for (var key in projectJsonObject.dependencies) {
+ if (key.toLowerCase().startsWith("microsoft.aspnetcore.server")) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+function addLaunchJsonIfNecessary(info: protocol.DotNetWorkspaceInformation, paths: Paths, operations: Operations, projectJsonPath: string) {
return new Promise((resolve, reject) => {
if (!operations.addLaunchJson) {
return resolve();
@@ -248,7 +282,7 @@ function addLaunchJsonIfNecessary(info: protocol.DotNetWorkspaceInformation, pat
}
}
- const launchJson = createLaunchJson(targetFramework, executableName);
+ const launchJson = createLaunchJson(targetFramework, executableName, hasWebServerDependency(projectJsonPath));
const launchJsonText = JSON.stringify(launchJson, null, ' ');
return fs.writeFileAsync(paths.launchJsonPath, launchJsonText);
@@ -284,7 +318,7 @@ export function addAssetsIfNecessary(server: OmnisharpServer) {
return fs.ensureDirAsync(paths.vscodeFolder).then(() => {
return Promise.all([
addTasksJsonIfNecessary(info.DotNet, paths, operations),
- addLaunchJsonIfNecessary(info.DotNet, paths, operations)
+ addLaunchJsonIfNecessary(info.DotNet, paths, operations, projectJsonPath)
]);
});
});
diff --git a/src/coreclr-debug/main.ts b/src/coreclr-debug/main.ts
index 3ee83a871e..f8c77524c0 100644
--- a/src/coreclr-debug/main.ts
+++ b/src/coreclr-debug/main.ts
@@ -200,25 +200,29 @@ function isOnPath(command : string) : boolean {
return false;
}
let fileName = command;
- let seperatorChar = ':';
if (process.platform == 'win32') {
// on Windows, add a '.exe', and the path is semi-colon seperatode
fileName = fileName + ".exe";
- seperatorChar = ';';
}
-
- let pathSegments: string[] = pathValue.split(seperatorChar);
+
+ let pathSegments: string[] = pathValue.split(path.delimiter);
for (let segment of pathSegments) {
if (segment.length === 0 || !path.isAbsolute(segment)) {
continue;
}
-
+
const segmentPath = path.join(segment, fileName);
- if (CoreClrDebugUtil.existsSync(segmentPath)) {
- return true;
+
+ try {
+ if (CoreClrDebugUtil.existsSync(segmentPath)) {
+ return true;
+ }
+ } catch (err) {
+ // any error from existsSync can be treated as the command not being on the path
+ continue;
}
}
-
+
return false;
}
@@ -332,9 +336,9 @@ function createProjectJson(targetRuntime: string): any
emitEntryPoint: true
},
dependencies: {
- "Microsoft.VisualStudio.clrdbg": "14.0.25229-preview-2963841",
- "Microsoft.VisualStudio.clrdbg.MIEngine": "14.0.30401-preview-1",
- "Microsoft.VisualStudio.OpenDebugAD7": "1.0.20405-preview-1",
+ "Microsoft.VisualStudio.clrdbg": "14.0.25406-preview-3044032",
+ "Microsoft.VisualStudio.clrdbg.MIEngine": "14.0.30606-preview-1",
+ "Microsoft.VisualStudio.OpenDebugAD7": "1.0.20527-preview-1",
"NETStandard.Library": "1.5.0-rc2-24027",
"Newtonsoft.Json": "7.0.1",
"Microsoft.VisualStudio.Debugger.Interop.Portable": "1.0.1",
diff --git a/src/coreclr-debug/util.ts b/src/coreclr-debug/util.ts
index baca1c201c..e17f35af98 100644
--- a/src/coreclr-debug/util.ts
+++ b/src/coreclr-debug/util.ts
@@ -83,7 +83,7 @@ export default class CoreClrDebugUtil
fs.accessSync(path, fs.F_OK);
return true;
} catch (err) {
- if (err.code === 'ENOENT') {
+ if (err.code === 'ENOENT' || err.code === 'ENOTDIR') {
return false;
} else {
throw Error(err.code);
diff --git a/src/features/codeLensProvider.ts b/src/features/codeLensProvider.ts
index 496b660d72..1c24c1e1bd 100644
--- a/src/features/codeLensProvider.ts
+++ b/src/features/codeLensProvider.ts
@@ -8,76 +8,79 @@
import {CancellationToken, CodeLens, Range, Uri, TextDocument, CodeLensProvider} from 'vscode';
import {toRange, toLocation} from '../typeConvertion';
import AbstractSupport from './abstractProvider';
+import {updateCodeLensForTest} from './dotnetTest';
import * as protocol from '../protocol';
import * as serverUtils from '../omnisharpUtils';
class OmniSharpCodeLens extends CodeLens {
- fileName: string;
+ fileName: string;
- constructor(fileName: string, range: Range) {
- super(range);
- this.fileName = fileName;
- }
+ constructor(fileName: string, range: Range) {
+ super(range);
+ this.fileName = fileName;
+ }
}
export default class OmniSharpCodeLensProvider extends AbstractSupport implements CodeLensProvider {
- private static filteredSymbolNames: { [name: string]: boolean } = {
- 'Equals': true,
- 'Finalize': true,
- 'GetHashCode': true,
- 'ToString': true
- };
-
- provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable {
-
- return serverUtils.currentFileMembersAsTree(this._server, { Filename: document.fileName }, token).then(tree => {
- let ret: CodeLens[] = [];
- tree.TopLevelTypeDefinitions.forEach(node => OmniSharpCodeLensProvider._convertQuickFix(ret, document.fileName, node));
- return ret;
- });
- }
-
- private static _convertQuickFix(bucket: CodeLens[], fileName:string, node: protocol.Node): void {
-
- if (node.Kind === 'MethodDeclaration' && OmniSharpCodeLensProvider.filteredSymbolNames[node.Location.Text]) {
- return;
- }
-
- let lens = new OmniSharpCodeLens(fileName, toRange(node.Location));
- bucket.push(lens);
-
- for (let child of node.ChildNodes) {
- OmniSharpCodeLensProvider._convertQuickFix(bucket, fileName, child);
- }
- }
-
- resolveCodeLens(codeLens: CodeLens, token: CancellationToken): Thenable {
- if (codeLens instanceof OmniSharpCodeLens) {
-
- let req = {
- Filename: codeLens.fileName,
- Line: codeLens.range.start.line + 1,
- Column: codeLens.range.start.character + 1,
- OnlyThisFile: false,
- ExcludeDefinition: true
- };
-
- return serverUtils.findUsages(this._server, req, token).then(res => {
- if (!res || !Array.isArray(res.QuickFixes)) {
- return;
- }
-
- let len = res.QuickFixes.length;
- codeLens.command = {
- title: len === 1 ? '1 reference' : `${len} references`,
- command: 'editor.action.showReferences',
- arguments: [Uri.file(req.Filename), codeLens.range.start, res.QuickFixes.map(toLocation)]
- };
-
- return codeLens;
- });
- }
- }
+ private static filteredSymbolNames: { [name: string]: boolean } = {
+ 'Equals': true,
+ 'Finalize': true,
+ 'GetHashCode': true,
+ 'ToString': true
+ };
+
+ provideCodeLenses(document: TextDocument, token: CancellationToken): CodeLens[] | Thenable {
+ let request = { Filename: document.fileName };
+ return serverUtils.currentFileMembersAsTree(this._server, { Filename: document.fileName }, token).then(tree => {
+ let ret: CodeLens[] = [];
+ tree.TopLevelTypeDefinitions.forEach(node => this._convertQuickFix(ret, document.fileName, node));
+ return ret;
+ });
+ }
+
+ private _convertQuickFix(bucket: CodeLens[], fileName: string, node: protocol.Node): void {
+
+ if (node.Kind === 'MethodDeclaration' && OmniSharpCodeLensProvider.filteredSymbolNames[node.Location.Text]) {
+ return;
+ }
+
+ let lens = new OmniSharpCodeLens(fileName, toRange(node.Location));
+ bucket.push(lens);
+
+ for (let child of node.ChildNodes) {
+ this._convertQuickFix(bucket, fileName, child);
+ }
+
+ updateCodeLensForTest(bucket, fileName, node, this._server.isDebugEnable());
+ }
+
+ resolveCodeLens(codeLens: CodeLens, token: CancellationToken): Thenable {
+ if (codeLens instanceof OmniSharpCodeLens) {
+
+ let req = {
+ Filename: codeLens.fileName,
+ Line: codeLens.range.start.line + 1,
+ Column: codeLens.range.start.character + 1,
+ OnlyThisFile: false,
+ ExcludeDefinition: true
+ };
+
+ return serverUtils.findUsages(this._server, req, token).then(res => {
+ if (!res || !Array.isArray(res.QuickFixes)) {
+ return;
+ }
+
+ let len = res.QuickFixes.length;
+ codeLens.command = {
+ title: len === 1 ? '1 reference' : `${len} references`,
+ command: 'editor.action.showReferences',
+ arguments: [Uri.file(req.Filename), codeLens.range.start, res.QuickFixes.map(toLocation)]
+ };
+
+ return codeLens;
+ });
+ }
+ }
}
diff --git a/src/features/commands.ts b/src/features/commands.ts
index e3e71241b6..7036e9e494 100644
--- a/src/features/commands.ts
+++ b/src/features/commands.ts
@@ -13,134 +13,139 @@ import * as fs from 'fs-extra-promise';
import * as path from 'path';
import * as protocol from '../protocol';
import * as vscode from 'vscode';
+import * as dotnetTest from './dotnetTest'
let channel = vscode.window.createOutputChannel('.NET');
export default function registerCommands(server: OmnisharpServer, extensionPath: string) {
- let d1 = vscode.commands.registerCommand('o.restart', () => server.restart());
- let d2 = vscode.commands.registerCommand('o.pickProjectAndStart', () => pickProjectAndStart(server));
- let d3 = vscode.commands.registerCommand('o.showOutput', () => server.getChannel().show(vscode.ViewColumn.Three));
- let d4 = vscode.commands.registerCommand('dotnet.restore', () => dotnetRestoreAllProjects(server));
-
+ let d1 = vscode.commands.registerCommand('o.restart', () => server.restart());
+ let d2 = vscode.commands.registerCommand('o.pickProjectAndStart', () => pickProjectAndStart(server));
+ let d3 = vscode.commands.registerCommand('o.showOutput', () => server.getChannel().show(vscode.ViewColumn.Three));
+ let d4 = vscode.commands.registerCommand('dotnet.restore', () => dotnetRestoreAllProjects(server));
+
// register empty handler for csharp.installDebugger
// running the command activates the extension, which is all we need for installation to kickoff
let d5 = vscode.commands.registerCommand('csharp.downloadDebugger', () => { });
-
- return vscode.Disposable.from(d1, d2, d3, d4, d5);
+
+ // register two commands for running and debugging xunit tests
+ let d6 = dotnetTest.registerDotNetTestRunCommand(server);
+ let d7 = dotnetTest.registerDotNetTestDebugCommand(server);
+
+ return vscode.Disposable.from(d1, d2, d3, d4, d5, d6, d7);
}
function pickProjectAndStart(server: OmnisharpServer) {
- return findLaunchTargets().then(targets => {
-
- let currentPath = server.getSolutionPathOrFolder();
- if (currentPath) {
- for (let target of targets) {
- if (target.target.fsPath === currentPath) {
- target.label = `\u2713 ${target.label}`;
- }
- }
- }
-
- return vscode.window.showQuickPick(targets, {
- matchOnDescription: true,
- placeHolder: `Select 1 of ${targets.length} projects`
- }).then(target => {
- if (target) {
- return server.restart(target.target.fsPath);
- }
- });
- });
+ return findLaunchTargets().then(targets => {
+
+ let currentPath = server.getSolutionPathOrFolder();
+ if (currentPath) {
+ for (let target of targets) {
+ if (target.target.fsPath === currentPath) {
+ target.label = `\u2713 ${target.label}`;
+ }
+ }
+ }
+
+ return vscode.window.showQuickPick(targets, {
+ matchOnDescription: true,
+ placeHolder: `Select 1 of ${targets.length} projects`
+ }).then(target => {
+ if (target) {
+ return server.restart(target.target.fsPath);
+ }
+ });
+ });
}
interface Command {
- label: string;
- description: string;
- execute(): Thenable;
+ label: string;
+ description: string;
+ execute(): Thenable;
}
function projectsToCommands(projects: protocol.DotNetProject[]): Promise[] {
- return projects.map(project => {
- let projectDirectory = project.Path;
-
- return fs.lstatAsync(projectDirectory).then(stats => {
- if (stats.isFile()) {
- projectDirectory = path.dirname(projectDirectory);
- }
-
- return {
- label: `dotnet restore - (${project.Name || path.basename(project.Path)})`,
- description: projectDirectory,
- execute() {
- return runDotnetRestore(projectDirectory);
- }
- };
- });
- });
+ return projects.map(project => {
+ let projectDirectory = project.Path;
+
+ return fs.lstatAsync(projectDirectory).then(stats => {
+ if (stats.isFile()) {
+ projectDirectory = path.dirname(projectDirectory);
+ }
+
+ return {
+ label: `dotnet restore - (${project.Name || path.basename(project.Path)})`,
+ description: projectDirectory,
+ execute() {
+ return runDotnetRestore(projectDirectory);
+ }
+ };
+ });
+ });
}
export function dotnetRestoreAllProjects(server: OmnisharpServer) {
- if (!server.isRunning()) {
- return Promise.reject('OmniSharp server is not running.');
- }
-
- return serverUtils.requestWorkspaceInformation(server).then(info => {
-
- if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
- return Promise.reject("No .NET Core projects found");
- }
-
- let commandPromises = projectsToCommands(info.DotNet.Projects);
-
- return Promise.all(commandPromises).then(commands => {
- return vscode.window.showQuickPick(commands);
- }).then(command => {
- if (command) {
- return command.execute();
- }
- });
- });
+ if (!server.isRunning()) {
+ return Promise.reject('OmniSharp server is not running.');
+ }
+
+ return serverUtils.requestWorkspaceInformation(server).then(info => {
+
+ if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
+ return Promise.reject("No .NET Core projects found");
+ }
+
+ let commandPromises = projectsToCommands(info.DotNet.Projects);
+
+ return Promise.all(commandPromises).then(commands => {
+ return vscode.window.showQuickPick(commands);
+ }).then(command => {
+ if (command) {
+ return command.execute();
+ }
+ });
+ });
}
export function dotnetRestoreForProject(server: OmnisharpServer, fileName: string) {
- if (!server.isRunning()) {
- return Promise.reject('OmniSharp server is not running.');
- }
-
- return serverUtils.requestWorkspaceInformation(server).then(info => {
-
- if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
- return Promise.reject("No .NET Core projects found");
- }
-
- let directory = path.dirname(fileName);
-
- for (let project of info.DotNet.Projects) {
- if (project.Path === directory) {
- return runDotnetRestore(directory, fileName);
- }
- }
- });
+ if (!server.isRunning()) {
+ return Promise.reject('OmniSharp server is not running.');
+ }
+
+ return serverUtils.requestWorkspaceInformation(server).then(info => {
+
+ if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
+ return Promise.reject("No .NET Core projects found");
+ }
+
+ let directory = path.dirname(fileName);
+
+ for (let project of info.DotNet.Projects) {
+ if (project.Path === directory) {
+ return runDotnetRestore(directory, fileName);
+ }
+ }
+ });
}
function runDotnetRestore(cwd: string, fileName?: string) {
- return new Promise((resolve, reject) => {
- channel.clear();
- channel.show();
-
- let cmd = 'dotnet restore';
- if (fileName) {
- cmd = `${cmd} "${fileName}"`
- }
-
- return cp.exec(cmd, {cwd: cwd, env: process.env}, (err, stdout, stderr) => {
- channel.append(stdout.toString());
- channel.append(stderr.toString());
- if (err) {
- channel.append('ERROR: ' + err);
- }
- });
- });
+ return new Promise((resolve, reject) => {
+ channel.clear();
+ channel.show();
+
+ let cmd = 'dotnet restore';
+ if (fileName) {
+ cmd = `${cmd} "${fileName}"`
+ }
+
+ return cp.exec(cmd, { cwd: cwd, env: process.env }, (err, stdout, stderr) => {
+ channel.append(stdout.toString());
+ channel.append(stderr.toString());
+ if (err) {
+ channel.append('ERROR: ' + err);
+ }
+ });
+ });
}
\ No newline at end of file
diff --git a/src/features/dotnetTest.ts b/src/features/dotnetTest.ts
new file mode 100644
index 0000000000..65e2c7407e
--- /dev/null
+++ b/src/features/dotnetTest.ts
@@ -0,0 +1,95 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+
+'use strict';
+
+import {OmnisharpServer} from '../omnisharpServer';
+import {toRange} from '../typeConvertion';
+import * as vscode from 'vscode';
+import * as serverUtils from "../omnisharpUtils";
+import * as protocol from '../protocol';
+
+let _testOutputChannel: vscode.OutputChannel = undefined;
+
+function getTestOutputChannel(): vscode.OutputChannel {
+ if (_testOutputChannel == undefined) {
+ _testOutputChannel = vscode.window.createOutputChannel(".NET Test Log");
+ }
+
+ return _testOutputChannel;
+}
+
+export function registerDotNetTestRunCommand(server: OmnisharpServer): vscode.Disposable {
+ return vscode.commands.registerCommand(
+ 'dotnet.test.run',
+ (testMethod, fileName) => runDotnetTest(testMethod, fileName, server));
+}
+
+export function registerDotNetTestDebugCommand(server: OmnisharpServer): vscode.Disposable {
+ return vscode.commands.registerCommand(
+ 'dotnet.test.debug',
+ (testMethod, fileName) => debugDotnetTest(testMethod, fileName, server));
+}
+
+// Run test through dotnet-test command. This function can be moved to a separate structure
+export function runDotnetTest(testMethod: string, fileName: string, server: OmnisharpServer) {
+ getTestOutputChannel().show();
+ getTestOutputChannel().appendLine('Running test ' + testMethod + '...');
+ serverUtils
+ .runDotNetTest(server, { FileName: fileName, MethodName: testMethod })
+ .then(
+ response => {
+ if (response.Pass) {
+ getTestOutputChannel().appendLine('Test passed \n');
+ }
+ else {
+ getTestOutputChannel().appendLine('Test failed \n');
+ }
+ },
+ reason => {
+ vscode.window.showErrorMessage(`Failed to run test because ${reason}.`);
+ });
+}
+
+// Run test through dotnet-test command with debugger attached
+export function debugDotnetTest(testMethod: string, fileName: string, server: OmnisharpServer) {
+ serverUtils.getTestStartInfo(server, { FileName: fileName, MethodName: testMethod }).then(response => {
+ vscode.commands.executeCommand(
+ 'vscode.startDebug', {
+ "name": ".NET test launch",
+ "type": "coreclr",
+ "request": "launch",
+ "program": response.Executable,
+ "args": response.Argument.split(' '),
+ "cwd": "${workspaceRoot}",
+ "stopAtEntry": false
+ }
+ ).then(
+ response => { },
+ reason => { vscode.window.showErrorMessage(`Failed to start debugger on test because ${reason}.`) });
+ });
+}
+
+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) {
+ return;
+ }
+
+ let testFeature = node.Features.find(value => value.Name == 'XunitTestMethod');
+ if (testFeature) {
+ // this test method has a test feature
+
+ bucket.push(new vscode.CodeLens(
+ toRange(node.Location),
+ { title: "run test", command: 'dotnet.test.run', arguments: [testFeature.Data, fileName] }));
+
+ if (isDebugEnable) {
+ bucket.push(new vscode.CodeLens(
+ toRange(node.Location),
+ { title: "debug test", command: 'dotnet.test.debug', arguments: [testFeature.Data, fileName] }));
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/omnisharpDownload.ts b/src/omnisharpDownload.ts
index 4b42cf4a58..dbb407c08e 100644
--- a/src/omnisharpDownload.ts
+++ b/src/omnisharpDownload.ts
@@ -13,29 +13,30 @@ import * as tmp from 'tmp';
import {parse} from 'url';
import {SupportedPlatform, getSupportedPlatform} from './utils';
import {getProxyAgent} from './proxy';
+import {OutputChannel} from 'vscode';
-const Decompress = require('decompress');
+const decompress = require('decompress');
const BaseDownloadUrl = 'https://vscodeoscon.blob.core.windows.net/ext';
const DefaultInstallLocation = path.join(__dirname, '../.omnisharp');
-const ApiToken = '18a6f5ecea711220d4f433d4fd41062d479fda1d';
+const OmniSharpVersion = '1.9-beta4';
tmp.setGracefulCleanup();
function getOmnisharpAssetName(): string {
switch (getSupportedPlatform()) {
case SupportedPlatform.Windows:
- return 'omnisharp-win-x64-net451.zip';
+ return `omnisharp-${OmniSharpVersion}-win-x64-net451.zip`;
case SupportedPlatform.OSX:
- return 'omnisharp-osx-x64-netcoreapp1.0.tar.gz';
+ return `omnisharp-${OmniSharpVersion}-osx-x64-netcoreapp1.0.tar.gz`;
case SupportedPlatform.CentOS:
- return 'omnisharp-centos-x64-netcoreapp1.0.tar.gz';
+ return `omnisharp-${OmniSharpVersion}-centos-x64-netcoreapp1.0.tar.gz`;
case SupportedPlatform.Debian:
- return 'omnisharp-debian-x64-netcoreapp1.0.tar.gz';
+ return `omnisharp-${OmniSharpVersion}-debian-x64-netcoreapp1.0.tar.gz`;
case SupportedPlatform.RHEL:
- return 'omnisharp-rhel-x64-netcoreapp1.0.tar.gz';
+ return `omnisharp-${OmniSharpVersion}-rhel-x64-netcoreapp1.0.tar.gz`;
case SupportedPlatform.Ubuntu:
- return 'omnisharp-ubuntu-x64-netcoreapp1.0.tar.gz';
+ return `omnisharp-${OmniSharpVersion}-ubuntu-x64-netcoreapp1.0.tar.gz`;
default:
if (process.platform === 'linux') {
@@ -73,14 +74,14 @@ function download(urlString: string): Promise {
});
}
-export function downloadOmnisharp(): Promise {
+export function downloadOmnisharp(output: OutputChannel): Promise {
return new Promise((resolve, reject) => {
- console.log(`[OmniSharp]: Installing to ${DefaultInstallLocation}`);
+ output.appendLine(`[INFO] Installing to ${DefaultInstallLocation}`);
const assetName = getOmnisharpAssetName();
const urlString = `${BaseDownloadUrl}/${assetName}`;
- console.log(`[OmniSharp] Attempting to download ${assetName}...`);
+ output.appendLine(`[INFO] Attempting to download ${assetName}...`);
return download(urlString)
.then(inStream => {
@@ -89,7 +90,7 @@ export function downloadOmnisharp(): Promise {
return reject(err);
}
- console.log(`[OmniSharp] Downloading to ${tmpPath}...`);
+ output.appendLine(`[INFO] Downloading to ${tmpPath}...`);
const outStream = fs.createWriteStream(null, { fd: fd });
@@ -99,30 +100,18 @@ export function downloadOmnisharp(): Promise {
outStream.once('finish', () => {
// At this point, the asset has finished downloading.
- console.log(`[OmniSharp] Download complete!`);
+ output.appendLine(`[INFO] Download complete!`);
+ output.appendLine(`[INFO] Decompressing...`);
- let decompress = new Decompress()
- .src(tmpPath)
- .dest(DefaultInstallLocation);
-
- if (path.extname(assetName).toLowerCase() === '.zip') {
- decompress = decompress.use(Decompress.zip());
- console.log(`[OmniSharp] Unzipping...`);
- }
- else {
- decompress = decompress.use(Decompress.targz());
- console.log(`[OmniSharp] Untaring...`);
- }
-
- decompress.run((err, files) => {
- if (err) {
+ return decompress(tmpPath, DefaultInstallLocation)
+ .then(files => {
+ output.appendLine(`[INFO] Done! ${files.length} files unpacked.`)
+ return resolve(true);
+ })
+ .error(err => {
+ output.appendLine(`[ERROR] ${err}`);
return reject(err);
- }
-
- console.log(`[OmniSharp] Done! ${files.length} files unpacked.`)
-
- return resolve(true);
- });
+ });
});
inStream.pipe(outStream);
diff --git a/src/omnisharpServer.ts b/src/omnisharpServer.ts
index 96d6c946e1..33bf072240 100644
--- a/src/omnisharpServer.ts
+++ b/src/omnisharpServer.ts
@@ -14,6 +14,7 @@ import {Disposable, CancellationToken, OutputChannel, workspace, window} from 'v
import {ErrorMessage, UnresolvedDependenciesMessage, MSBuildProjectDiagnostics, ProjectInformationResponse} from './protocol';
import getLaunchTargets, {LaunchTarget} from './launchTargetFinder';
import TelemetryReporter from 'vscode-extension-telemetry';
+import * as vscode from 'vscode'
enum ServerState {
Starting,
@@ -31,29 +32,29 @@ interface Request {
module Events {
export const StateChanged = 'stateChanged';
-
+
export const StdOut = 'stdout';
export const StdErr = 'stderr';
-
+
export const Error = 'Error';
export const ServerError = 'ServerError';
-
+
export const UnresolvedDependencies = 'UnresolvedDependencies';
export const PackageRestoreStarted = 'PackageRestoreStarted';
export const PackageRestoreFinished = 'PackageRestoreFinished';
-
+
export const ProjectChanged = 'ProjectChanged';
export const ProjectAdded = 'ProjectAdded';
export const ProjectRemoved = 'ProjectRemoved';
-
+
export const MsBuildProjectDiagnostics = 'MsBuildProjectDiagnostics';
-
+
export const BeforeServerStart = 'BeforeServerStart';
export const ServerStart = 'ServerStart';
export const ServerStop = 'ServerStop';
-
+
export const MultipleLaunchTargets = 'server:MultipleLaunchTargets';
-
+
export const Started = 'started';
}
@@ -65,7 +66,7 @@ class Delays {
idleDelays: number = 0; // 501-1500 milliseconds
nonFocusDelays: number = 0; // 1501-3000 milliseconds
bigDelays: number = 0; // 3000+ milliseconds
-
+
public report(elapsedTime: number) {
if (elapsedTime <= 25) {
this.immediateDelays += 1;
@@ -89,8 +90,8 @@ class Delays {
this.bigDelays += 1;
}
}
-
- public toMeasures(): {[key: string]: number} {
+
+ public toMeasures(): { [key: string]: number } {
return {
immedateDelays: this.immediateDelays,
nearImmediateDelays: this.nearImmediateDelays,
@@ -115,6 +116,8 @@ export abstract class OmnisharpServer {
private _isProcessingQueue = false;
private _channel: OutputChannel;
+ private _isDebugEnable: boolean = false;
+
protected _serverProcess: ChildProcess;
protected _extraArgv: string[];
@@ -132,28 +135,28 @@ export abstract class OmnisharpServer {
return this._state;
}
- private _setState(value: ServerState) : void {
+ private _setState(value: ServerState): void {
if (typeof value !== 'undefined' && value !== this._state) {
this._state = value;
this._fireEvent(Events.StateChanged, this._state);
}
}
-
+
private _recordRequestDelay(requestName: string, elapsedTime: number) {
let delays = this._requestDelays[requestName];
if (!delays) {
delays = new Delays();
this._requestDelays[requestName] = delays;
}
-
+
delays.report(elapsedTime);
}
-
+
public reportAndClearTelemetry() {
for (var path in this._requestDelays) {
const eventName = 'omnisharp' + path;
const measures = this._requestDelays[path].toMeasures();
-
+
this._reporter.sendTelemetryEvent(eventName, null, measures);
}
@@ -168,6 +171,10 @@ export abstract class OmnisharpServer {
return this._channel;
}
+ public isDebugEnable(): boolean {
+ return this._isDebugEnable;
+ }
+
// --- eventing
public onStdout(listener: (e: string) => any, thisArg?: any) {
@@ -186,7 +193,7 @@ export abstract class OmnisharpServer {
return this._addListener(Events.ServerError, listener, thisArg);
}
- public onUnresolvedDependencies(listener: (e: UnresolvedDependenciesMessage) => any, thisArg?:any) {
+ public onUnresolvedDependencies(listener: (e: UnresolvedDependenciesMessage) => any, thisArg?: any) {
return this._addListener(Events.UnresolvedDependencies, listener, thisArg);
}
@@ -214,7 +221,7 @@ export abstract class OmnisharpServer {
return this._addListener(Events.MsBuildProjectDiagnostics, listener, thisArg);
}
- public onBeforeServerStart(listener: (e:string) => any) {
+ public onBeforeServerStart(listener: (e: string) => any) {
return this._addListener(Events.BeforeServerStart, listener);
}
@@ -271,6 +278,13 @@ export abstract class OmnisharpServer {
this._setState(ServerState.Started);
this._fireEvent(Events.ServerStart, solutionPath);
return this._doConnect();
+ }).then(_ => {
+ return vscode.commands.getCommands()
+ .then(commands => {
+ if (commands.find(c => c == "vscode.startDebug")) {
+ this._isDebugEnable = true;
+ }
+ });
}).then(_ => {
this._processQueue();
}, err => {
@@ -300,7 +314,7 @@ export abstract class OmnisharpServer {
return reject(err);
}
});
-
+
killer.on('exit', resolve);
killer.on('error', reject);
});
@@ -309,7 +323,7 @@ export abstract class OmnisharpServer {
this._serverProcess.kill('SIGTERM');
ret = Promise.resolve(undefined);
}
-
+
return ret.then(_ => {
this._start = null;
this._serverProcess = null;
@@ -327,7 +341,7 @@ export abstract class OmnisharpServer {
}
}
- public autoStart(preferredPath:string): Thenable {
+ public autoStart(preferredPath: string): Thenable {
return getLaunchTargets().then(targets => {
if (targets.length === 0) {
return new Promise((resolve, reject) => {
@@ -368,13 +382,13 @@ export abstract class OmnisharpServer {
if (this._getState() !== ServerState.Started) {
return Promise.reject('server has been stopped or not started');
}
-
+
let startTime: number;
let request: Request;
-
+
let promise = new Promise((resolve, reject) => {
startTime = Date.now();
-
+
request = {
path,
data,
@@ -382,9 +396,9 @@ export abstract class OmnisharpServer {
onError: err => reject(err),
_enqueued: Date.now()
};
-
+
this._queue.push(request);
-
+
if (this._getState() === ServerState.Started && !this._isProcessingQueue) {
this._processQueue();
}
@@ -406,7 +420,7 @@ export abstract class OmnisharpServer {
let endTime = Date.now();
let elapsedTime = endTime - startTime;
this._recordRequestDelay(path, elapsedTime);
-
+
return response;
});
}
@@ -504,19 +518,17 @@ export class StdioOmnisharpServer extends OmnisharpServer {
// timeout logic
const handle = setTimeout(() => {
- if (listener)
- {
+ if (listener) {
listener.dispose();
}
-
+
reject(new Error('Failed to start OmniSharp'));
}, StdioOmnisharpServer.StartupTimeout);
// handle started-event
listener = this.onOmnisharpStart(() => {
- if (listener)
- {
- listener.dispose();
+ if (listener) {
+ listener.dispose();
}
clearTimeout(handle);
resolve(this);
@@ -552,17 +564,17 @@ export class StdioOmnisharpServer extends OmnisharpServer {
switch (packet.Type) {
case 'response':
- this._handleResponsePacket( packet);
+ this._handleResponsePacket(packet);
break;
case 'event':
- this._handleEventPacket( packet);
+ this._handleEventPacket(packet);
break;
default:
console.warn('unknown packet: ', packet);
break;
}
};
-
+
this._rl.addListener('line', onLineReceived);
this._callOnStop.push(() => this._rl.removeListener('line', onLineReceived));
}
@@ -590,7 +602,7 @@ export class StdioOmnisharpServer extends OmnisharpServer {
if (packet.Event === 'log') {
// handle log events
- const entry = <{ LogLevel: string; Name: string; Message: string; }> packet.Body;
+ const entry = <{ LogLevel: string; Name: string; Message: string; }>packet.Body;
this._fireEvent(Events.StdOut, `[${entry.LogLevel}:${entry.Name}] ${entry.Message}\n`);
return;
} else {
diff --git a/src/omnisharpServerLauncher.ts b/src/omnisharpServerLauncher.ts
index 561c7d805f..b4d0bb87d2 100644
--- a/src/omnisharpServerLauncher.ts
+++ b/src/omnisharpServerLauncher.ts
@@ -37,7 +37,7 @@ export function installOmnisharpIfNeeded(output: OutputChannel): Promise
throw err;
}
- return downloadOmnisharp().then(_ => {
+ return downloadOmnisharp(output).then(_ => {
return getOmnisharpLaunchFilePath();
})
});
diff --git a/src/omnisharpUtils.ts b/src/omnisharpUtils.ts
index 409a51e239..d1b1e88227 100644
--- a/src/omnisharpUtils.ts
+++ b/src/omnisharpUtils.ts
@@ -73,3 +73,10 @@ export function updateBuffer(server: OmnisharpServer, request: protocol.UpdateBu
return server.makeRequest(protocol.Requests.UpdateBuffer, request);
}
+export function getTestStartInfo(server: OmnisharpServer, request: protocol.V2.GetTestStartInfoRequest) {
+ return server.makeRequest(protocol.V2.Requests.GetTestStartInfo, request);
+}
+
+export function runDotNetTest(server: OmnisharpServer, request: protocol.V2.RunDotNetTestRequest) {
+ return server.makeRequest(protocol.V2.Requests.RunDotNetTest, request);
+}
\ No newline at end of file
diff --git a/src/protocol.ts b/src/protocol.ts
index 959d05a17d..76bb72bd18 100644
--- a/src/protocol.ts
+++ b/src/protocol.ts
@@ -23,16 +23,16 @@ export module Requests {
export const RemoveFromProject = '/removefromproject';
export const Rename = '/rename';
export const RunCodeAction = '/runcodeaction';
- export const SignatureHelp = '/signatureHelp';
+ export const SignatureHelp = '/signatureHelp';
export const TypeLookup = '/typelookup';
export const UpdateBuffer = '/updatebuffer';
}
export interface Request {
- Filename: string;
- Line?: number;
- Column?: number;
- Buffer?: string;
+ Filename: string;
+ Line?: number;
+ Column?: number;
+ Buffer?: string;
Changes?: LinePositionSpanTextChange[];
}
@@ -49,394 +49,423 @@ export interface UpdateBufferRequest extends Request {
}
export interface ChangeBufferRequest {
- FileName: string;
- StartLine: number;
- StartColumn: number;
- EndLine: number;
- EndColumn: number;
- NewText: string;
+ FileName: string;
+ StartLine: number;
+ StartColumn: number;
+ EndLine: number;
+ EndColumn: number;
+ NewText: string;
}
export interface AddToProjectRequest extends Request {
- //?
+ //?
}
export interface RemoveFromProjectRequest extends Request {
- //?
+ //?
}
export interface FindUsagesRequest extends Request {
- // MaxWidth: number; ?
- OnlyThisFile: boolean;
- ExcludeDefinition: boolean;
+ // MaxWidth: number; ?
+ OnlyThisFile: boolean;
+ ExcludeDefinition: boolean;
}
export interface FindSymbolsRequest extends Request {
- Filter: string;
+ Filter: string;
}
export interface FormatRequest extends Request {
- ExpandTab: boolean;
+ ExpandTab: boolean;
}
export interface CodeActionRequest extends Request {
- CodeAction: number;
- WantsTextChanges?: boolean;
- SelectionStartColumn?: number;
- SelectionStartLine?: number;
- SelectionEndColumn?: number;
- SelectionEndLine?: number;
+ CodeAction: number;
+ WantsTextChanges?: boolean;
+ SelectionStartColumn?: number;
+ SelectionStartLine?: number;
+ SelectionEndColumn?: number;
+ SelectionEndLine?: number;
}
export interface FormatResponse {
- Buffer: string;
+ Buffer: string;
}
export interface TextChange {
- NewText: string;
- StartLine: number;
- StartColumn: number;
- EndLine: number;
- EndColumn: number;
+ NewText: string;
+ StartLine: number;
+ StartColumn: number;
+ EndLine: number;
+ EndColumn: number;
}
export interface FormatAfterKeystrokeRequest extends Request {
- Character: string;
+ Character: string;
}
export interface FormatRangeRequest extends Request {
- EndLine: number;
- EndColumn: number;
+ EndLine: number;
+ EndColumn: number;
}
export interface FormatRangeResponse {
- Changes: TextChange[];
+ Changes: TextChange[];
}
export interface ResourceLocation {
- FileName: string;
- Line: number;
- Column: number;
+ FileName: string;
+ Line: number;
+ Column: number;
}
export interface Error {
- Message: string;
- Line: number;
- Column: number;
- EndLine: number;
- EndColumn: number;
- FileName: string;
+ Message: string;
+ Line: number;
+ Column: number;
+ EndLine: number;
+ EndColumn: number;
+ FileName: string;
}
export interface ErrorResponse {
- Errors: Error[];
+ Errors: Error[];
}
export interface QuickFix {
- LogLevel: string;
- FileName: string;
- Line: number;
- Column: number;
- EndLine: number;
- EndColumn: number;
- Text: string;
- Projects: string[];
+ LogLevel: string;
+ FileName: string;
+ Line: number;
+ Column: number;
+ EndLine: number;
+ EndColumn: number;
+ Text: string;
+ Projects: string[];
}
export interface SymbolLocation extends QuickFix {
- Kind: string;
+ Kind: string;
}
export interface QuickFixResponse {
- QuickFixes: QuickFix[];
+ QuickFixes: QuickFix[];
}
export interface FindSymbolsResponse {
- QuickFixes: SymbolLocation[];
+ QuickFixes: SymbolLocation[];
}
export interface TypeLookupRequest extends Request {
- IncludeDocumentation: boolean;
+ IncludeDocumentation: boolean;
}
export interface TypeLookupResponse {
- Type: string;
- Documentation: string;
+ Type: string;
+ Documentation: string;
}
export interface RunCodeActionResponse {
- Text: string;
- Changes: TextChange[];
+ Text: string;
+ Changes: TextChange[];
}
export interface GetCodeActionsResponse {
- CodeActions: string[];
+ CodeActions: string[];
+}
+
+export interface SyntaxFeature {
+ Name: string;
+ Data: string;
}
export interface Node {
- ChildNodes: Node[];
- Location: QuickFix;
- Kind: string;
+ ChildNodes: Node[];
+ Location: QuickFix;
+ Kind: string;
+ Features: SyntaxFeature[];
}
export interface CurrentFileMembersAsTreeResponse {
- TopLevelTypeDefinitions: Node[];
+ TopLevelTypeDefinitions: Node[];
}
export interface AutoCompleteRequest extends Request {
- WordToComplete: string;
- WantDocumentationForEveryCompletionResult?: boolean;
- WantImportableTypes?: boolean;
- WantMethodHeader?: boolean;
- WantSnippet?: boolean;
- WantReturnType?: boolean;
- WantKind?: boolean;
+ WordToComplete: string;
+ WantDocumentationForEveryCompletionResult?: boolean;
+ WantImportableTypes?: boolean;
+ WantMethodHeader?: boolean;
+ WantSnippet?: boolean;
+ WantReturnType?: boolean;
+ WantKind?: boolean;
}
export interface AutoCompleteResponse {
- CompletionText: string;
- Description: string;
- DisplayText: string;
- RequiredNamespaceImport: string;
- MethodHeader: string;
- ReturnType: string;
- Snippet: string;
- Kind: string;
+ CompletionText: string;
+ Description: string;
+ DisplayText: string;
+ RequiredNamespaceImport: string;
+ MethodHeader: string;
+ ReturnType: string;
+ Snippet: string;
+ Kind: string;
}
export interface ProjectInformationResponse {
- MsBuildProject: MSBuildProject;
- DnxProject: DnxProject;
+ MsBuildProject: MSBuildProject;
+ DnxProject: DnxProject;
}
export interface WorkspaceInformationResponse {
- MsBuild: MsBuildWorkspaceInformation;
- Dnx: DnxWorkspaceInformation;
+ MsBuild: MsBuildWorkspaceInformation;
+ Dnx: DnxWorkspaceInformation;
DotNet: DotNetWorkspaceInformation;
- ScriptCs: ScriptCsContext;
+ ScriptCs: ScriptCsContext;
}
export interface MsBuildWorkspaceInformation {
- SolutionPath: string;
- Projects: MSBuildProject[];
+ SolutionPath: string;
+ Projects: MSBuildProject[];
}
export interface ScriptCsContext {
- CsxFiles: { [n: string]: string };
- References: { [n: string]: string };
- Usings: { [n: string]: string };
- ScriptPacks: { [n: string]: string };
- Path: string;
+ CsxFiles: { [n: string]: string };
+ References: { [n: string]: string };
+ Usings: { [n: string]: string };
+ ScriptPacks: { [n: string]: string };
+ Path: string;
}
export interface MSBuildProject {
- ProjectGuid: string;
- Path: string;
- AssemblyName: string;
- TargetPath: string;
- TargetFramework: string;
- SourceFiles: string[];
+ ProjectGuid: string;
+ Path: string;
+ AssemblyName: string;
+ TargetPath: string;
+ TargetFramework: string;
+ SourceFiles: string[];
}
export interface DnxWorkspaceInformation {
- RuntimePath: string;
- DesignTimeHostPort: number;
- Projects: DnxProject[];
+ RuntimePath: string;
+ DesignTimeHostPort: number;
+ Projects: DnxProject[];
}
export interface DnxProject {
- Path: string;
- Name: string;
- Commands: { [name: string]: string; };
- Configurations: string[];
- ProjectSearchPaths: string[];
- Frameworks: DnxFramework[];
- GlobalJsonPath: string;
- SourceFiles: string[];
+ Path: string;
+ Name: string;
+ Commands: { [name: string]: string; };
+ Configurations: string[];
+ ProjectSearchPaths: string[];
+ Frameworks: DnxFramework[];
+ GlobalJsonPath: string;
+ SourceFiles: string[];
}
export interface DnxFramework {
- Name: string;
- FriendlyName: string;
- ShortName: string;
+ Name: string;
+ FriendlyName: string;
+ ShortName: string;
}
export interface DotNetWorkspaceInformation {
- Projects: DotNetProject[];
- RuntimePath: string;
+ Projects: DotNetProject[];
+ RuntimePath: string;
}
export interface DotNetProject {
- Path: string;
- Name: string;
- ProjectSearchPaths: string[];
- Configurations: DotNetConfiguration[];
- Frameworks: DotNetFramework[];
- SourceFiles: string[];
+ Path: string;
+ Name: string;
+ ProjectSearchPaths: string[];
+ Configurations: DotNetConfiguration[];
+ Frameworks: DotNetFramework[];
+ SourceFiles: string[];
}
export interface DotNetConfiguration {
- Name: string;
- CompilationOutputPath: string;
- CompilationOutputAssemblyFile: string;
- CompilationOutputPdbFile: string;
- EmitEntryPoint?: boolean;
+ Name: string;
+ CompilationOutputPath: string;
+ CompilationOutputAssemblyFile: string;
+ CompilationOutputPdbFile: string;
+ EmitEntryPoint?: boolean;
}
export interface DotNetFramework {
- Name: string;
- FriendlyName: string;
- ShortName: string;
+ Name: string;
+ FriendlyName: string;
+ ShortName: string;
}
export interface RenameRequest extends Request {
- RenameTo: string;
- WantsTextChanges?: boolean;
+ RenameTo: string;
+ WantsTextChanges?: boolean;
}
export interface ModifiedFileResponse {
- FileName: string;
- Buffer: string;
- Changes: TextChange[];
+ FileName: string;
+ Buffer: string;
+ Changes: TextChange[];
}
export interface RenameResponse {
- Changes: ModifiedFileResponse[];
+ Changes: ModifiedFileResponse[];
}
export interface SignatureHelp {
- Signatures: SignatureHelpItem[];
- ActiveSignature: number;
- ActiveParameter: number;
+ Signatures: SignatureHelpItem[];
+ ActiveSignature: number;
+ ActiveParameter: number;
}
export interface SignatureHelpItem {
- Name: string;
- Label: string;
- Documentation: string;
- Parameters: SignatureHelpParameter[];
+ Name: string;
+ Label: string;
+ Documentation: string;
+ Parameters: SignatureHelpParameter[];
}
export interface SignatureHelpParameter {
- Name: string;
- Label: string;
- Documentation: string;
+ Name: string;
+ Label: string;
+ Documentation: string;
}
export interface MSBuildProjectDiagnostics {
- FileName: string;
- Warnings: MSBuildDiagnosticsMessage[];
- Errors: MSBuildDiagnosticsMessage[];
+ FileName: string;
+ Warnings: MSBuildDiagnosticsMessage[];
+ Errors: MSBuildDiagnosticsMessage[];
}
export interface MSBuildDiagnosticsMessage {
- LogLevel: string;
- FileName: string;
- Text: string;
- StartLine: number;
- StartColumn: number;
- EndLine: number;
- EndColumn: number;
+ LogLevel: string;
+ FileName: string;
+ Text: string;
+ StartLine: number;
+ StartColumn: number;
+ EndLine: number;
+ EndColumn: number;
}
export interface ErrorMessage {
- Text: string;
- FileName: string;
- Line: number;
- Column: number;
+ Text: string;
+ FileName: string;
+ Line: number;
+ Column: number;
}
export interface PackageRestoreMessage {
- FileName: string;
- Succeeded: boolean;
+ FileName: string;
+ Succeeded: boolean;
}
export interface UnresolvedDependenciesMessage {
- FileName: string;
- UnresolvedDependencies: PackageDependency[];
+ FileName: string;
+ UnresolvedDependencies: PackageDependency[];
}
export interface PackageDependency {
- Name: string;
- Version: string;
+ Name: string;
+ Version: string;
}
export namespace V2 {
-
+
export module Requests {
export const GetCodeActions = '/v2/getcodeactions';
export const RunCodeAction = '/v2/runcodeaction';
+ export const GetTestStartInfo = '/v2/getteststartinfo';
+ export const RunDotNetTest = '/v2/runtest';
+ }
+
+ export interface Point {
+ Line: number;
+ Column: number;
+ }
+
+ export interface Range {
+ Start: Point;
+ End: Point;
+ }
+
+ export interface GetCodeActionsRequest extends Request {
+ Selection: Range;
}
- export interface Point {
- Line: number;
- Column: number;
- }
-
- export interface Range {
- Start: Point;
- End: Point;
- }
-
- export interface GetCodeActionsRequest extends Request {
- Selection: Range;
- }
-
- export interface OmniSharpCodeAction {
- Identifier: string;
- Name: string;
- }
-
- export interface GetCodeActionsResponse {
- CodeActions: OmniSharpCodeAction[];
- }
-
- export interface RunCodeActionRequest extends Request {
- Identifier: string;
- Selection: Range;
- WantsTextChanges: boolean;
- }
-
- export interface RunCodeActionResponse {
- Changes: ModifiedFileResponse[];
- }
-
-
- export interface MSBuildProjectDiagnostics {
- FileName: string;
- Warnings: MSBuildDiagnosticsMessage[];
- Errors: MSBuildDiagnosticsMessage[];
- }
-
- export interface MSBuildDiagnosticsMessage {
- LogLevel: string;
- FileName: string;
- Text: string;
- StartLine: number;
- StartColumn: number;
- EndLine: number;
- EndColumn: number;
- }
-
- export interface ErrorMessage {
- Text: string;
- FileName: string;
- Line: number;
- Column: number;
- }
-
- export interface PackageRestoreMessage {
- FileName: string;
- Succeeded: boolean;
- }
-
- export interface UnresolvedDependenciesMessage {
- FileName: string;
- UnresolvedDependencies: PackageDependency[];
- }
-
- export interface PackageDependency {
- Name: string;
- Version: string;
- }
+ export interface OmniSharpCodeAction {
+ Identifier: string;
+ Name: string;
+ }
+
+ export interface GetCodeActionsResponse {
+ CodeActions: OmniSharpCodeAction[];
+ }
+
+ export interface RunCodeActionRequest extends Request {
+ Identifier: string;
+ Selection: Range;
+ WantsTextChanges: boolean;
+ }
+
+ export interface RunCodeActionResponse {
+ Changes: ModifiedFileResponse[];
+ }
+
+
+ export interface MSBuildProjectDiagnostics {
+ FileName: string;
+ Warnings: MSBuildDiagnosticsMessage[];
+ Errors: MSBuildDiagnosticsMessage[];
+ }
+
+ export interface MSBuildDiagnosticsMessage {
+ LogLevel: string;
+ FileName: string;
+ Text: string;
+ StartLine: number;
+ StartColumn: number;
+ EndLine: number;
+ EndColumn: number;
+ }
+
+ export interface ErrorMessage {
+ Text: string;
+ FileName: string;
+ Line: number;
+ Column: number;
+ }
+
+ export interface PackageRestoreMessage {
+ FileName: string;
+ Succeeded: boolean;
+ }
+
+ export interface UnresolvedDependenciesMessage {
+ FileName: string;
+ UnresolvedDependencies: PackageDependency[];
+ }
+
+ export interface PackageDependency {
+ Name: string;
+ Version: string;
+ }
+
+ // dotnet-test endpoints
+ export interface GetTestStartInfoRequest {
+ FileName: string;
+ MethodName: string;
+ }
+
+ export interface GetTestStartInfoResponse {
+ Executable: string;
+ Argument: string;
+ }
+
+ export interface RunDotNetTestRequest {
+ FileName: string;
+ MethodName: string;
+ }
+
+ export interface RunDotNetTestResponse {
+ Failure: string;
+ Pass: boolean;
+ }
}
\ No newline at end of file