Skip to content

Commit 8f42658

Browse files
Merge pull request #345 from DustinCampbell/merge-dev-into-master
Merge dev into master
2 parents 15e500b + f236900 commit 8f42658

File tree

13 files changed

+199
-115
lines changed

13 files changed

+199
-115
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ Please file any issues at https://github.com/OmniSharp/omnisharp-vscode/issues.
2525
The C# extension now supports basic debugging capabilities! See http://aka.ms/vscclrdebugger for details.
2626

2727
### Development
28+
29+
First install:
30+
* Node.js (newer than 4.3.1)
31+
* Npm (newer 2.14.12)
32+
2833
To **run and develop** do the following:
2934

3035
* Run `npm i`

debugger.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ Install Visual Studio Code (VSC). Pick the latest VSC version from here: https:/
1515

1616
If you are not sure what version you have, you can see your version of VS Code:
1717

18-
* **OSX:** Code->Abort Visual Studio Code
19-
* **Windows / Linux:** Help->Abort
18+
* **OSX:** Code->About Visual Studio Code
19+
* **Windows / Linux:** Help->About
2020

2121
##### 2: Install .NET command line tools
2222
Install the .NET Core command line tools (CLI) by following the installation part of the instructions here: http://dotnet.github.io/getting-started

package.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
"decompress": "^3.0.0",
2626
"del": "^2.0.2",
2727
"fs-extra-promise": "^0.3.1",
28-
"run-in-terminal": "*",
2928
"semver": "*",
3029
"vscode-debugprotocol": "^1.6.1",
3130
"vscode-extension-telemetry": "0.0.4",
@@ -295,7 +294,7 @@
295294
"processId": {
296295
"type": "integer",
297296
"description": "The process id to attach to. If this is used, 'processName' should not be used.",
298-
"default": ""
297+
"default": 0
299298
},
300299
"sourceFileMap": {
301300
"type": "object",
@@ -359,7 +358,7 @@
359358
"name": ".NET Core Attach",
360359
"type": "coreclr",
361360
"request": "attach",
362-
"processName": "<example>"
361+
"processId": 0
363362
}
364363
]
365364
}

src/assets.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ interface WebLaunchConfiguration extends ConsoleLaunchConfiguration {
4545
}
4646

4747
interface AttachConfiguration extends DebugConfiguration {
48-
processName: string
48+
processId: number
4949
}
5050

5151
interface Paths {
@@ -173,7 +173,7 @@ function createAttachConfiguration(): AttachConfiguration {
173173
name: '.NET Core Attach',
174174
type: 'coreclr',
175175
request: 'attach',
176-
processName: '<example>'
176+
processId: 0
177177
}
178178
}
179179

src/coreclr-debug/main.ts

Lines changed: 76 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ export function activate(context: vscode.ExtensionContext, reporter: TelemetryRe
5757

5858
writeInstallBeginFile().then(function() {
5959
installStage = 'writeProjectJson';
60-
return writeProjectJson();
60+
return writeProjectJson(_channel);
6161
}).then(function() {
6262
installStage = 'dotnetRestore'
6363
return spawnChildProcess('dotnet', ['--verbose', 'restore', '--configfile', 'NuGet.config'], _channel, _util.coreClrDebugDir())
@@ -185,7 +185,7 @@ function removeLibCoreClrTraceProvider() : Promise<void>
185185
if (err) {
186186
reject(err.code);
187187
} else {
188-
_channel.appendLine('Succesfully deleted ' + filePath);
188+
_channel.appendLine('Successfully deleted ' + filePath);
189189
resolve();
190190
}
191191
});
@@ -240,12 +240,16 @@ function ensureAd7EngineExists(channel: vscode.OutputChannel, outputDirectory: s
240240
});
241241
}
242242

243-
function writeProjectJson(): Promise<void> {
244-
return new Promise<void>(function(resolve, reject) {
245-
var projectJson = createProjectJson(CoreClrDebugUtil.getPlatformRuntimeId());
243+
function writeProjectJson(channel: vscode.OutputChannel): Promise<void> {
244+
return new Promise<void>(function (resolve, reject) {
245+
const projectJsonPath = path.join(_util.coreClrDebugDir(), 'project.json');
246+
_channel.appendLine('Creating ' + projectJsonPath);
247+
248+
const projectJson = createProjectJson(getPlatformRuntimeId(channel));
246249

247-
fs.writeFile(path.join(_util.coreClrDebugDir(), 'project.json'), JSON.stringify(projectJson, null, 2), {encoding: 'utf8'}, function(err) {
248-
if (err) {
250+
fs.writeFile(projectJsonPath, JSON.stringify(projectJson, null, 2), {encoding: 'utf8'}, function(err) {
251+
if (err) {
252+
channel.appendLine('Error: Unable to write to project.json: ' + err.message);
249253
reject(err.code);
250254
}
251255
else {
@@ -255,6 +259,71 @@ function writeProjectJson(): Promise<void> {
255259
});
256260
}
257261

262+
function getPlatformRuntimeId(channel: vscode.OutputChannel) : string {
263+
switch (process.platform) {
264+
case 'win32':
265+
return 'win7-x64';
266+
case 'darwin':
267+
return getDotnetRuntimeId(channel);
268+
case 'linux':
269+
return getDotnetRuntimeId(channel);
270+
default:
271+
channel.appendLine('Error: Unsupported platform ' + process.platform);
272+
throw Error('Unsupported platform ' + process.platform);
273+
}
274+
}
275+
276+
function getDotnetRuntimeId(channel: vscode.OutputChannel): string {
277+
channel.appendLine("Starting 'dotnet --info'");
278+
279+
const cliVersionErrorMessage = "Ensure that .NET Core CLI Tools version >= 1.0.0-beta-002173 is installed. Run 'dotnet --version' to see what version is installed.";
280+
281+
let child = child_process.spawnSync('dotnet', ['--info'], { cwd: _util.coreClrDebugDir() });
282+
283+
if (child.stderr.length > 0) {
284+
channel.append('Error: ' + child.stderr.toString());
285+
}
286+
const out = child.stdout.toString();
287+
if (out.length > 0) {
288+
channel.append(out);
289+
}
290+
291+
if (child.status !== 0) {
292+
const message = `Error: 'dotnet --info' failed with error ${child.status}`;
293+
channel.appendLine(message);
294+
channel.appendLine(cliVersionErrorMessage);
295+
throw new Error(message);
296+
}
297+
298+
if (out.length === 0) {
299+
const message = "Error: 'dotnet --info' provided no output";
300+
channel.appendLine(message);
301+
channel.appendLine(cliVersionErrorMessage);
302+
throw new Error(message);
303+
}
304+
305+
let lines = out.split('\n');
306+
let ridLine = lines.filter(function (value) {
307+
return value.trim().startsWith('RID:');
308+
});
309+
310+
if (ridLine.length < 1) {
311+
channel.appendLine("Error: Cannot find 'RID' property");
312+
channel.appendLine(cliVersionErrorMessage);
313+
throw new Error('Cannot obtain Runtime ID from dotnet cli');
314+
}
315+
316+
let rid = ridLine[0].split(':')[1].trim();
317+
318+
if (!rid) {
319+
channel.appendLine("Error: Unable to parse 'RID' property.");
320+
channel.appendLine(cliVersionErrorMessage);
321+
throw new Error('Unable to determine Runtime ID');
322+
}
323+
324+
return rid;
325+
}
326+
258327
function createProjectJson(targetRuntime: string): any
259328
{
260329
let projectJson = {

src/coreclr-debug/util.ts

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -112,40 +112,6 @@ export default class CoreClrDebugUtil
112112
}
113113
}
114114

115-
static getPlatformRuntimeId() : string {
116-
switch(process.platform) {
117-
case 'win32':
118-
return 'win7-x64';
119-
case 'darwin':
120-
return CoreClrDebugUtil.getDotnetRuntimeId();
121-
case 'linux':
122-
return CoreClrDebugUtil.getDotnetRuntimeId();
123-
default:
124-
throw Error('Unsupported platform ' + process.platform);
125-
}
126-
}
127-
128-
static getDotnetRuntimeId() : string {
129-
let out = child_process.execSync('dotnet --info').toString();
130-
131-
let lines = out.split('\n');
132-
let ridLine = lines.filter(function(value) {
133-
return value.trim().startsWith('RID');
134-
});
135-
136-
if (ridLine.length < 1) {
137-
throw new Error('Cannot obtain Runtime ID from dotnet cli');
138-
}
139-
140-
let rid = ridLine[0].split(':')[1].trim();
141-
142-
if (!rid) {
143-
throw new Error('Unable to determine Runtime ID');
144-
}
145-
146-
return rid;
147-
}
148-
149115
/** Used for diagnostics only */
150116
logToFile(message: string): void {
151117
let logFolder = path.resolve(this.coreClrDebugDir(), "extension.log");

src/features/commands.ts

Lines changed: 68 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@
88
import {OmnisharpServer} from '../omnisharpServer';
99
import * as serverUtils from '../omnisharpUtils';
1010
import findLaunchTargets from '../launchTargetFinder';
11-
import {runInTerminal} from 'run-in-terminal';
11+
import * as cp from 'child_process';
12+
import * as fs from 'fs-extra-promise';
1213
import * as path from 'path';
14+
import * as protocol from '../protocol';
1315
import * as vscode from 'vscode';
1416

15-
const isWindows = process.platform === 'win32';
17+
let channel = vscode.window.createOutputChannel('.NET');
1618

1719
export default function registerCommands(server: OmnisharpServer, extensionPath: string) {
1820
let d1 = vscode.commands.registerCommand('o.restart', () => server.restart());
@@ -57,6 +59,26 @@ interface Command {
5759
execute(): Thenable<any>;
5860
}
5961

62+
function projectsToCommands(projects: protocol.DotNetProject[]): Promise<Command>[] {
63+
return projects.map(project => {
64+
let projectDirectory = project.Path;
65+
66+
return fs.lstatAsync(projectDirectory).then(stats => {
67+
if (stats.isFile()) {
68+
projectDirectory = path.dirname(projectDirectory);
69+
}
70+
71+
return {
72+
label: `dotnet restore - (${project.Name || path.basename(project.Path)})`,
73+
description: projectDirectory,
74+
execute() {
75+
return runDotnetRestore(projectDirectory);
76+
}
77+
};
78+
});
79+
});
80+
}
81+
6082
export function dotnetRestoreAllProjects(server: OmnisharpServer) {
6183

6284
if (!server.isRunning()) {
@@ -65,23 +87,15 @@ export function dotnetRestoreAllProjects(server: OmnisharpServer) {
6587

6688
return serverUtils.requestWorkspaceInformation(server).then(info => {
6789

68-
let commands: Command[] = [];
90+
if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
91+
return Promise.reject("No .NET Core projects found");
92+
}
93+
94+
let commandPromises = projectsToCommands(info.DotNet.Projects);
6995

70-
if ('DotNet' in info && info.DotNet.Projects.length > 0) {
71-
for (let project of info.DotNet.Projects) {
72-
commands.push({
73-
label: `dotnet restor - (${project.Name || path.basename(project.Path)})`,
74-
description: path.dirname(project.Path),
75-
execute() {
76-
return runInTerminal('dotnet', ['restore'], {
77-
cwd: path.dirname(project.Path)
78-
});
79-
}
80-
});
81-
}
82-
}
83-
84-
return vscode.window.showQuickPick(commands).then(command => {
96+
return Promise.all(commandPromises).then(commands => {
97+
return vscode.window.showQuickPick(commands);
98+
}).then(command => {
8599
if (command) {
86100
return command.execute();
87101
}
@@ -91,17 +105,42 @@ export function dotnetRestoreAllProjects(server: OmnisharpServer) {
91105

92106
export function dotnetRestoreForProject(server: OmnisharpServer, fileName: string) {
93107

108+
if (!server.isRunning()) {
109+
return Promise.reject('OmniSharp server is not running.');
110+
}
111+
94112
return serverUtils.requestWorkspaceInformation(server).then(info => {
95-
if ('DotNet' in info && info.DotNet.Projects.length > 0) {
96-
for (let project of info.DotNet.Projects) {
97-
if (project.Path === path.dirname(fileName)) {
98-
return runInTerminal('dotnet', ['restore', fileName], {
99-
cwd: path.dirname(project.Path)
100-
});
101-
}
102-
}
103-
}
104-
105-
return Promise.reject(`Failed to execute restore, try to run 'dotnet restore' manually for ${fileName}.`);
113+
114+
if (!('DotNet in info') || info.DotNet.Projects.length < 1) {
115+
return Promise.reject("No .NET Core projects found");
116+
}
117+
118+
let directory = path.dirname(fileName);
119+
120+
for (let project of info.DotNet.Projects) {
121+
if (project.Path === directory) {
122+
return runDotnetRestore(directory, fileName);
123+
}
124+
}
125+
});
126+
}
127+
128+
function runDotnetRestore(cwd: string, fileName?: string) {
129+
return new Promise<cp.ChildProcess>((resolve, reject) => {
130+
channel.clear();
131+
channel.show();
132+
133+
let cmd = 'dotnet restore';
134+
if (fileName) {
135+
cmd = `${cmd} "${fileName}"`
136+
}
137+
138+
return cp.exec(cmd, {cwd: cwd, env: process.env}, (err, stdout, stderr) => {
139+
channel.append(stdout.toString());
140+
channel.append(stderr.toString());
141+
if (err) {
142+
channel.append('ERROR: ' + err);
143+
}
144+
});
106145
});
107146
}

src/features/completionItemProvider.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
'use strict';
77

8-
import {plain} from './documentation';
8+
import {extractSummaryText} from './documentation';
99
import AbstractSupport from './abstractProvider';
1010
import * as protocol from '../protocol';
1111
import * as serverUtils from '../omnisharpUtils';
@@ -26,6 +26,7 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp
2626
req.WordToComplete = wordToComplete;
2727
req.WantDocumentationForEveryCompletionResult = true;
2828
req.WantKind = true;
29+
req.WantReturnType = true;
2930

3031
return serverUtils.autoComplete(this._server, req).then(values => {
3132

@@ -40,14 +41,15 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp
4041
// group by code snippet
4142
for (let value of values) {
4243
let completion = new CompletionItem(value.CompletionText.replace(/\(|\)|<|>/g, ''));
43-
completion.detail = value.DisplayText;
44-
completion.documentation = plain(value.Description);
44+
completion.detail = value.ReturnType ? `${value.ReturnType} ${value.DisplayText}` : value.DisplayText;
45+
completion.documentation = extractSummaryText(value.Description);
4546
completion.kind = _kinds[value.Kind] || CompletionItemKind.Property;
4647

4748
let array = completions[completion.label];
4849
if (!array) {
4950
completions[completion.label] = [completion];
50-
} else {
51+
}
52+
else {
5153
array.push(completion);
5254
}
5355
}
@@ -62,10 +64,12 @@ export default class OmniSharpCompletionItemProvider extends AbstractSupport imp
6264
// remove non overloaded items
6365
delete completions[key];
6466

65-
} else {
67+
}
68+
else {
6669
// indicate that there is more
6770
suggestion.detail = `${suggestion.detail} (+ ${overloadCount} overload(s))`;
6871
}
72+
6973
result.push(suggestion);
7074
}
7175

0 commit comments

Comments
 (0)