提交 1637345e 编写于 作者: I isidor

debugUtils

上级 77a8731d
......@@ -730,19 +730,3 @@ export interface IDebugEditorContribution extends IEditorContribution {
closeBreakpointWidget(): void;
addLaunchConfiguration(): TPromise<any>;
}
// utils
const _formatPIIRegexp = /{([^}]+)}/g;
export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string {
return value.replace(_formatPIIRegexp, function (match, group) {
if (excludePII && group.length > 0 && group[0] !== '_') {
return match;
}
return args && args.hasOwnProperty(group) ?
args[group] :
match;
});
}
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Range } from 'vs/editor/common/core/range';
const _formatPIIRegexp = /{([^}]+)}/g;
export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string {
return value.replace(_formatPIIRegexp, function (match, group) {
if (excludePII && group.length > 0 && group[0] !== '_') {
return match;
}
return args && args.hasOwnProperty(group) ?
args[group] :
match;
});
}
export function getExactExpressionRange(lineContent: string, range: Range): Range {
let matchingExpression: string = undefined;
let startOffset = 0;
// Some example supported expressions: myVar.prop, a.b.c.d, myVar?.prop, myVar->prop, MyClass::StaticProp, *myVar
// Match any character except a set of characters which often break interesting sub-expressions
let expression: RegExp = /([^()\[\]{}<>\s+\-/%~#^;=|,`!]|\->)+/g;
let result: RegExpExecArray = undefined;
// First find the full expression under the cursor
while (result = expression.exec(lineContent)) {
let start = result.index + 1;
let end = start + result[0].length;
if (start <= range.startColumn && end >= range.endColumn) {
matchingExpression = result[0];
startOffset = start;
break;
}
}
// If there are non-word characters after the cursor, we want to truncate the expression then.
// For example in expression 'a.b.c.d', if the focus was under 'b', 'a.b' would be evaluated.
if (matchingExpression) {
let subExpression: RegExp = /\w+/g;
let subExpressionResult: RegExpExecArray = undefined;
while (subExpressionResult = subExpression.exec(matchingExpression)) {
let subEnd = subExpressionResult.index + 1 + startOffset + subExpressionResult[0].length;
if (subEnd >= range.endColumn) {
break;
}
}
if (subExpressionResult) {
matchingExpression = matchingExpression.substring(0, subExpression.lastIndex);
}
}
return matchingExpression ?
new Range(range.startLineNumber, startOffset, range.endLineNumber, startOffset + matchingExpression.length - 1) :
new Range(range.startLineNumber, 0, range.endLineNumber, 0);
}
......@@ -28,6 +28,7 @@ import { editorHoverBackground, editorHoverBorder } from 'vs/platform/theme/comm
import { WorkbenchTree, WorkbenchTreeController } from 'vs/platform/list/browser/listService';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { getExactExpressionRange } from 'vs/workbench/parts/debug/common/debugUtils';
const $ = dom.$;
const MAX_ELEMENTS_SHOWN = 18;
......@@ -138,55 +139,12 @@ export class DebugHoverWidget implements IContentWidget {
return this.domNode;
}
private getExactExpressionRange(lineContent: string, range: Range): Range {
let matchingExpression: string = undefined;
let startOffset = 0;
// Some example supported expressions: myVar.prop, a.b.c.d, myVar?.prop, myVar->prop, MyClass::StaticProp, *myVar
// Match any character except a set of characters which often break interesting sub-expressions
let expression: RegExp = /([^()\[\]{}<>\s+\-/%~#^;=|,`!]|\->)+/g;
let result: RegExpExecArray = undefined;
// First find the full expression under the cursor
while (result = expression.exec(lineContent)) {
let start = result.index + 1;
let end = start + result[0].length;
if (start <= range.startColumn && end >= range.endColumn) {
matchingExpression = result[0];
startOffset = start;
break;
}
}
// If there are non-word characters after the cursor, we want to truncate the expression then.
// For example in expression 'a.b.c.d', if the focus was under 'b', 'a.b' would be evaluated.
if (matchingExpression) {
let subExpression: RegExp = /\w+/g;
let subExpressionResult: RegExpExecArray = undefined;
while (subExpressionResult = subExpression.exec(matchingExpression)) {
let subEnd = subExpressionResult.index + 1 + startOffset + subExpressionResult[0].length;
if (subEnd >= range.endColumn) {
break;
}
}
if (subExpressionResult) {
matchingExpression = matchingExpression.substring(0, subExpression.lastIndex);
}
}
return matchingExpression ?
new Range(range.startLineNumber, startOffset, range.endLineNumber, startOffset + matchingExpression.length - 1) :
new Range(range.startLineNumber, 0, range.endLineNumber, 0);
}
public showAt(range: Range, focus: boolean): TPromise<void> {
const pos = range.getStartPosition();
const process = this.debugService.getViewModel().focusedProcess;
const lineContent = this.editor.getModel().getLineContent(pos.lineNumber);
const expressionRange = this.getExactExpressionRange(lineContent, range);
const expressionRange = getExactExpressionRange(lineContent, range);
// use regex to extract the sub-expression #9821
const matchingExpression = lineContent.substring(expressionRange.startColumn - 1, expressionRange.endColumn);
if (!matchingExpression) {
......
......@@ -17,6 +17,7 @@ import { IOutputService } from 'vs/workbench/parts/output/common/output';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { INotificationService } from 'vs/platform/notification/common/notification';
import { StreamDebugAdapter } from 'vs/workbench/parts/debug/node/debugAdapter';
import { formatPII } from 'vs/workbench/parts/debug/common/debugUtils';
export interface SessionExitedEvent extends debug.DebugEvent {
......@@ -211,7 +212,7 @@ export class RawDebugSession implements debug.ISession {
const promise = this.internalSend<R>(command, args).then(response => response, (errorResponse: DebugProtocol.ErrorResponse) => {
const error = errorResponse && errorResponse.body ? errorResponse.body.error : null;
const errorMessage = errorResponse ? errorResponse.message : '';
const telemetryMessage = error ? debug.formatPII(error.format, true, error.variables) : errorMessage;
const telemetryMessage = error ? formatPII(error.format, true, error.variables) : errorMessage;
if (error && error.sendTelemetry) {
/* __GDPR__
"debugProtocolErrorResponse" : {
......@@ -228,7 +229,7 @@ export class RawDebugSession implements debug.ISession {
}
}
const userMessage = error ? debug.formatPII(error.format, false, error.variables) : errorMessage;
const userMessage = error ? formatPII(error.format, false, error.variables) : errorMessage;
if (error && error.url) {
const label = error.urlLabel ? error.urlLabel : nls.localize('moreInfo', "More Info");
return TPromise.wrapError<R>(errors.create(userMessage, {
......
......@@ -3,18 +3,18 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as debug from 'vs/workbench/parts/debug/common/debug';
import * as assert from 'assert';
import { formatPII } from 'vs/workbench/parts/debug/common/debugUtils';
suite('Debug - Utils', () => {
test('formatPII', () => {
assert.strictEqual(debug.formatPII('Foo Bar', false, {}), 'Foo Bar');
assert.strictEqual(debug.formatPII('Foo {key} Bar', false, {}), 'Foo {key} Bar');
assert.strictEqual(debug.formatPII('Foo {key} Bar', false, { 'key': 'yes' }), 'Foo yes Bar');
assert.strictEqual(debug.formatPII('Foo {_0} Bar {_0}', true, { '_0': 'yes' }), 'Foo yes Bar yes');
assert.strictEqual(debug.formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes' }), 'Foo yes Bar {1}{2}');
assert.strictEqual(debug.formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes', '1': 'undefined' }), 'Foo yes Bar undefined{2}');
assert.strictEqual(debug.formatPII('Foo {_key0} Bar {key1}{key2}', true, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar {key1}{key2}');
assert.strictEqual(debug.formatPII('Foo {_key0} Bar {key1}{key2}', false, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar 5false');
assert.strictEqual(formatPII('Foo Bar', false, {}), 'Foo Bar');
assert.strictEqual(formatPII('Foo {key} Bar', false, {}), 'Foo {key} Bar');
assert.strictEqual(formatPII('Foo {key} Bar', false, { 'key': 'yes' }), 'Foo yes Bar');
assert.strictEqual(formatPII('Foo {_0} Bar {_0}', true, { '_0': 'yes' }), 'Foo yes Bar yes');
assert.strictEqual(formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes' }), 'Foo yes Bar {1}{2}');
assert.strictEqual(formatPII('Foo {0} Bar {1}{2}', false, { '0': 'yes', '1': 'undefined' }), 'Foo yes Bar undefined{2}');
assert.strictEqual(formatPII('Foo {_key0} Bar {key1}{key2}', true, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar {key1}{key2}');
assert.strictEqual(formatPII('Foo {_key0} Bar {key1}{key2}', false, { '_key0': 'yes', 'key1': '5', 'key2': 'false' }), 'Foo yes Bar 5false');
});
});
\ No newline at end of file
});
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册