diff --git a/src/vs/base/node/console.ts b/src/vs/base/node/console.ts index fc3cf3baeabd2e2a3a9774e8ca322aab1f02876d..4d53f78841d521ce297965fe1c01665f345398b6 100644 --- a/src/vs/base/node/console.ts +++ b/src/vs/base/node/console.ts @@ -59,11 +59,21 @@ export function getFirstFrame(arg0: IRemoteConsoleLog | string): IStackFrame { return getFirstFrame(parse(arg0).stack); } - // Parse a source information out of the stack if we have one. Format: + // Parse a source information out of the stack if we have one. Format can be: // at vscode.commands.registerCommand (/Users/someone/Desktop/test-ts/out/src/extension.js:18:17) + // or + // at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17 + // or + // at c:\Users\someone\Desktop\end-js\extension.js:19:17 + // or + // at e.$executeContributedCommand(c:\Users\someone\Desktop\end-js\extension.js:19:17) const stack = arg0; if (stack) { - const matches = /.+\((.+):(\d+):(\d+)\)/.exec(stack); + // at [^\/]* => line starts with "at" followed by any character except '/' (to not capture unix paths too late) + // (?:(?:[a-zA-Z]+:)|(?:[\/])|(?:\\\\) => windows drive letter OR unix root OR unc root + // (?:.+) => simple pattern for the path, only works because of the line/col pattern after + // :(?:\d+):(?:\d+) => :line:column data + const matches = /at [^\/]*((?:(?:[a-zA-Z]+:)|(?:[\/])|(?:\\\\))(?:.+)):(\d+):(\d+)/.exec(stack); if (matches.length === 4) { return { uri: URI.file(matches[1]), diff --git a/src/vs/base/test/node/console.test.ts b/src/vs/base/test/node/console.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..6bf716b32f6df9ba6050eef4c382c989e47aded4 --- /dev/null +++ b/src/vs/base/test/node/console.test.ts @@ -0,0 +1,43 @@ +/*--------------------------------------------------------------------------------------------- + * 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 * as assert from 'assert'; +import { getFirstFrame } from 'vs/base/node/console'; +import { normalize } from 'path'; + +suite('Console', () => { + + test('getFirstFrame', function () { + let stack = 'at vscode.commands.registerCommand (/Users/someone/Desktop/test-ts/out/src/extension.js:18:17)'; + let frame = getFirstFrame(stack); + + assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js')); + assert.equal(frame.line, 18); + assert.equal(frame.column, 17); + + stack = 'at /Users/someone/Desktop/test-ts/out/src/extension.js:18:17'; + frame = getFirstFrame(stack); + + assert.equal(frame.uri.fsPath, normalize('/Users/someone/Desktop/test-ts/out/src/extension.js')); + assert.equal(frame.line, 18); + assert.equal(frame.column, 17); + + stack = 'at c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17'; + frame = getFirstFrame(stack); + + assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js'); + assert.equal(frame.line, 18); + assert.equal(frame.column, 17); + + stack = 'at e.$executeContributedCommand(c:\\Users\\someone\\Desktop\\end-js\\extension.js:18:17)'; + frame = getFirstFrame(stack); + + assert.equal(frame.uri.fsPath, 'c:\\Users\\someone\\Desktop\\end-js\\extension.js'); + assert.equal(frame.line, 18); + assert.equal(frame.column, 17); + }); +}); \ No newline at end of file