mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-01 09:35:41 -05:00
Merge from vscode 718331d6f3ebd1b571530ab499edb266ddd493d5
This commit is contained in:
@@ -27,7 +27,6 @@ const stringRegex = /^(['"]).*\1$/;
|
||||
const $ = dom.$;
|
||||
|
||||
export interface IRenderValueOptions {
|
||||
preserveWhitespace?: boolean;
|
||||
showChanged?: boolean;
|
||||
maxValueLength?: number;
|
||||
showHover?: boolean;
|
||||
@@ -49,11 +48,6 @@ export function renderViewTree(container: HTMLElement): HTMLElement {
|
||||
return treeContainer;
|
||||
}
|
||||
|
||||
export function replaceWhitespace(value: string): string {
|
||||
const map: { [x: string]: string } = { '\n': '\\n', '\r': '\\r', '\t': '\\t' };
|
||||
return value.replace(/[\n\r\t]/g, char => map[char]);
|
||||
}
|
||||
|
||||
export function renderExpressionValue(expressionOrValue: IExpressionContainer | string, container: HTMLElement, options: IRenderValueOptions): void {
|
||||
let value = typeof expressionOrValue === 'string' ? expressionOrValue : expressionOrValue.value;
|
||||
|
||||
@@ -86,11 +80,10 @@ export function renderExpressionValue(expressionOrValue: IExpressionContainer |
|
||||
if (options.maxValueLength && value && value.length > options.maxValueLength) {
|
||||
value = value.substr(0, options.maxValueLength) + '...';
|
||||
}
|
||||
if (value && !options.preserveWhitespace) {
|
||||
value = replaceWhitespace(value);
|
||||
} else {
|
||||
value = value || '';
|
||||
if (!value) {
|
||||
value = '';
|
||||
}
|
||||
|
||||
if (options.linkDetector) {
|
||||
container.textContent = '';
|
||||
const session = (expressionOrValue instanceof ExpressionContainer) ? expressionOrValue.getSession() : undefined;
|
||||
@@ -105,20 +98,19 @@ export function renderExpressionValue(expressionOrValue: IExpressionContainer |
|
||||
|
||||
export function renderVariable(variable: Variable, data: IVariableTemplateData, showChanged: boolean, highlights: IHighlight[], linkDetector?: LinkDetector): void {
|
||||
if (variable.available) {
|
||||
let text = replaceWhitespace(variable.name);
|
||||
let text = variable.name;
|
||||
if (variable.value && typeof variable.name === 'string') {
|
||||
text += ':';
|
||||
}
|
||||
data.label.set(text, highlights, variable.type ? variable.type : variable.name);
|
||||
dom.toggleClass(data.name, 'virtual', !!variable.presentationHint && variable.presentationHint.kind === 'virtual');
|
||||
} else if (variable.value && typeof variable.name === 'string') {
|
||||
} else if (variable.value && typeof variable.name === 'string' && variable.name) {
|
||||
data.label.set(':');
|
||||
}
|
||||
|
||||
renderExpressionValue(variable, data.value, {
|
||||
showChanged,
|
||||
maxValueLength: MAX_VALUE_RENDER_LENGTH_IN_VIEWLET,
|
||||
preserveWhitespace: false,
|
||||
showHover: true,
|
||||
colorize: true,
|
||||
linkDetector
|
||||
@@ -185,7 +177,7 @@ export abstract class AbstractExpressionsRenderer implements ITreeRenderer<IExpr
|
||||
const inputBox = new InputBox(inputBoxContainer, this.contextViewService, options);
|
||||
const styler = attachInputBoxStyler(inputBox, this.themeService);
|
||||
|
||||
inputBox.value = replaceWhitespace(options.initialValue);
|
||||
inputBox.value = options.initialValue;
|
||||
inputBox.focus();
|
||||
inputBox.select();
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
import { Gesture } from 'vs/base/browser/touch';
|
||||
import { IViewDescriptorService } from 'vs/workbench/common/views';
|
||||
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
||||
|
||||
const $ = dom.$;
|
||||
|
||||
@@ -633,7 +634,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea
|
||||
preserveFocus,
|
||||
selection,
|
||||
revealIfOpened: true,
|
||||
revealInCenterIfOutsideViewport: true,
|
||||
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,
|
||||
pinned: !preserveFocus
|
||||
}
|
||||
}, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
|
||||
|
||||
@@ -19,7 +19,7 @@ import { CallStackView } from 'vs/workbench/contrib/debug/browser/callStackView'
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
|
||||
import {
|
||||
IDebugService, VIEWLET_ID, DEBUG_PANEL_ID, CONTEXT_IN_DEBUG_MODE, INTERNAL_CONSOLE_OPTIONS_SCHEMA,
|
||||
CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_DEBUG_UX, BREAKPOINT_EDITOR_CONTRIBUTION_ID, REPL_VIEW_ID,
|
||||
CONTEXT_DEBUG_STATE, VARIABLES_VIEW_ID, CALLSTACK_VIEW_ID, WATCH_VIEW_ID, BREAKPOINTS_VIEW_ID, LOADED_SCRIPTS_VIEW_ID, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_STEP_BACK_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_DEBUG_UX, BREAKPOINT_EDITOR_CONTRIBUTION_ID, REPL_VIEW_ID, CONTEXT_BREAKPOINTS_EXIST,
|
||||
} from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { StartAction, AddFunctionBreakpointAction, ConfigureAction, DisableAllBreakpointsAction, EnableAllBreakpointsAction, RemoveAllBreakpointsAction, RunAction, ReapplyBreakpointsAction, SelectAndStartAction } from 'vs/workbench/contrib/debug/browser/debugActions';
|
||||
@@ -107,7 +107,7 @@ const viewsRegistry = Registry.as<IViewsRegistry>(ViewExtensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([{ id: VARIABLES_VIEW_ID, name: nls.localize('variables', "Variables"), ctorDescriptor: new SyncDescriptor(VariablesView), order: 10, weight: 40, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusVariablesView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: WATCH_VIEW_ID, name: nls.localize('watch', "Watch"), ctorDescriptor: new SyncDescriptor(WatchExpressionsView), order: 20, weight: 10, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusWatchView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: CALLSTACK_VIEW_ID, name: nls.localize('callStack', "Call Stack"), ctorDescriptor: new SyncDescriptor(CallStackView), order: 30, weight: 30, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusCallStackView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: new SyncDescriptor(BreakpointsView), order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' }, when: CONTEXT_DEBUG_UX.isEqualTo('default') }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: BREAKPOINTS_VIEW_ID, name: nls.localize('breakpoints', "Breakpoints"), ctorDescriptor: new SyncDescriptor(BreakpointsView), order: 40, weight: 20, canToggleVisibility: true, focusCommand: { id: 'workbench.debug.action.focusBreakpointsView' }, when: ContextKeyExpr.or(CONTEXT_BREAKPOINTS_EXIST, CONTEXT_DEBUG_UX.isEqualTo('default')) }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: StartView.ID, name: StartView.LABEL, ctorDescriptor: new SyncDescriptor(StartView), order: 10, weight: 40, canToggleVisibility: true, when: CONTEXT_DEBUG_UX.isEqualTo('simple') }], viewContainer);
|
||||
viewsRegistry.registerViews([{ id: LOADED_SCRIPTS_VIEW_ID, name: nls.localize('loadedScripts', "Loaded Scripts"), ctorDescriptor: new SyncDescriptor(LoadedScriptsView), order: 35, weight: 5, canToggleVisibility: true, collapsed: true, when: ContextKeyExpr.and(CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_DEBUG_UX.isEqualTo('default')) }], viewContainer);
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import { IContentWidget, ICodeEditor, IContentWidgetPosition, ContentWidgetPosit
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IDebugService, IExpression, IExpressionContainer, IStackFrame } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { renderExpressionValue, replaceWhitespace } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { renderExpressionValue } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { DomScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
||||
import { attachStylerCallback } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -230,7 +230,6 @@ export class DebugHoverWidget implements IContentWidget {
|
||||
this.valueContainer.hidden = false;
|
||||
renderExpressionValue(expression, this.valueContainer, {
|
||||
showChanged: false,
|
||||
preserveWhitespace: true,
|
||||
colorize: true
|
||||
});
|
||||
this.valueContainer.title = '';
|
||||
@@ -248,7 +247,7 @@ export class DebugHoverWidget implements IContentWidget {
|
||||
this.complexValueContainer.hidden = false;
|
||||
|
||||
await this.tree.setInput(expression);
|
||||
this.complexValueTitle.textContent = replaceWhitespace(expression.value);
|
||||
this.complexValueTitle.textContent = expression.value;
|
||||
this.complexValueTitle.title = expression.value;
|
||||
this.layoutTreeAndContainer();
|
||||
this.editor.layoutContentWidget(this);
|
||||
@@ -274,11 +273,13 @@ export class DebugHoverWidget implements IContentWidget {
|
||||
return;
|
||||
}
|
||||
|
||||
if (dom.isAncestor(document.activeElement, this.domNode)) {
|
||||
this.editor.focus();
|
||||
}
|
||||
this._isVisible = false;
|
||||
this.editor.deltaDecorations(this.highlightDecorations, []);
|
||||
this.highlightDecorations = [];
|
||||
this.editor.layoutContentWidget(this);
|
||||
this.editor.focus();
|
||||
}
|
||||
|
||||
getPosition(): IContentWidgetPosition | null {
|
||||
|
||||
@@ -36,7 +36,7 @@ import { IAction } from 'vs/base/common/actions';
|
||||
import { deepClone, equals } from 'vs/base/common/objects';
|
||||
import { DebugSession } from 'vs/workbench/contrib/debug/browser/debugSession';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { IDebugService, State, IDebugSession, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_MODE, IThread, IDebugConfiguration, VIEWLET_ID, DEBUG_PANEL_ID, IConfig, ILaunch, IViewModel, IConfigurationManager, IDebugModel, IEnablement, IBreakpoint, IBreakpointData, ICompound, IGlobalConfig, IStackFrame, AdapterEndEvent, getStateLabel, IDebugSessionOptions, CONTEXT_DEBUG_UX, REPL_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { IDebugService, State, IDebugSession, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_IN_DEBUG_MODE, IThread, IDebugConfiguration, VIEWLET_ID, DEBUG_PANEL_ID, IConfig, ILaunch, IViewModel, IConfigurationManager, IDebugModel, IEnablement, IBreakpoint, IBreakpointData, ICompound, IGlobalConfig, IStackFrame, AdapterEndEvent, getStateLabel, IDebugSessionOptions, CONTEXT_DEBUG_UX, REPL_VIEW_ID, CONTEXT_BREAKPOINTS_EXIST } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { getExtensionHostDebugSession } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
import { isErrorWithActions } from 'vs/base/common/errorsWithActions';
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
@@ -69,6 +69,7 @@ export class DebugService implements IDebugService {
|
||||
private debugState: IContextKey<string>;
|
||||
private inDebugMode: IContextKey<boolean>;
|
||||
private debugUx: IContextKey<string>;
|
||||
private breakpointsExist: IContextKey<boolean>;
|
||||
private breakpointsToSendOnResourceSaved: Set<string>;
|
||||
private initializing = false;
|
||||
private previousState: State | undefined;
|
||||
@@ -117,6 +118,9 @@ export class DebugService implements IDebugService {
|
||||
this.model = new DebugModel(this.loadBreakpoints(), this.loadFunctionBreakpoints(),
|
||||
this.loadExceptionBreakpoints(), this.loadDataBreakpoints(), this.loadWatchExpressions(), this.textFileService);
|
||||
this.toDispose.push(this.model);
|
||||
const setBreakpointsExistContext = () => this.breakpointsExist.set(!!(this.model.getBreakpoints().length || this.model.getDataBreakpoints().length || this.model.getFunctionBreakpoints().length));
|
||||
this.breakpointsExist = CONTEXT_BREAKPOINTS_EXIST.bindTo(contextKeyService);
|
||||
setBreakpointsExistContext();
|
||||
|
||||
this.viewModel = new ViewModel(contextKeyService);
|
||||
this.taskRunner = this.instantiationService.createInstance(DebugTaskRunner);
|
||||
@@ -169,6 +173,7 @@ export class DebugService implements IDebugService {
|
||||
this.activity = this.activityService.showActivity(VIEWLET_ID, new NumberBadge(numberOfSessions, n => n === 1 ? nls.localize('1activeSession', "1 active session") : nls.localize('nActiveSessions', "{0} active sessions", n)));
|
||||
}
|
||||
}));
|
||||
this.toDispose.push(this.model.onDidChangeBreakpoints(() => setBreakpointsExistContext()));
|
||||
}
|
||||
|
||||
getModel(): IDebugModel {
|
||||
@@ -513,11 +518,14 @@ export class DebugService implements IDebugService {
|
||||
try {
|
||||
await session.initialize(dbgr!);
|
||||
await session.launchOrAttach(session.configuration);
|
||||
if (forceFocus || !this.viewModel.focusedSession) {
|
||||
if (forceFocus || !this.viewModel.focusedSession || session.parentSession === this.viewModel.focusedSession) {
|
||||
await this.focusStackFrame(undefined, undefined, session);
|
||||
}
|
||||
} catch (err) {
|
||||
session.shutdown();
|
||||
if (this.viewModel.focusedSession === session) {
|
||||
await this.focusStackFrame(undefined);
|
||||
}
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
@@ -875,46 +883,44 @@ export class DebugService implements IDebugService {
|
||||
await this.sendExceptionBreakpoints(session);
|
||||
}
|
||||
|
||||
private sendBreakpoints(modelUri: uri, sourceModified = false, session?: IDebugSession): Promise<void> {
|
||||
private async sendBreakpoints(modelUri: uri, sourceModified = false, session?: IDebugSession): Promise<void> {
|
||||
const breakpointsToSend = this.model.getBreakpoints({ uri: modelUri, enabledOnly: true });
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s =>
|
||||
s.sendBreakpoints(modelUri, breakpointsToSend, sourceModified)
|
||||
);
|
||||
await sendToOneOrAllSessions(this.model, session, s => s.sendBreakpoints(modelUri, breakpointsToSend, sourceModified));
|
||||
}
|
||||
|
||||
private sendFunctionBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
private async sendFunctionBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
const breakpointsToSend = this.model.getFunctionBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.capabilities.supportsFunctionBreakpoints ? s.sendFunctionBreakpoints(breakpointsToSend) : Promise.resolve(undefined);
|
||||
await sendToOneOrAllSessions(this.model, session, async s => {
|
||||
if (s.capabilities.supportsFunctionBreakpoints) {
|
||||
await s.sendFunctionBreakpoints(breakpointsToSend);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private sendDataBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
const breakpointsToSend = this.model.getDataBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.capabilities.supportsDataBreakpoints ? s.sendDataBreakpoints(breakpointsToSend) : Promise.resolve(undefined);
|
||||
return sendToOneOrAllSessions(this.model, session, async s => {
|
||||
if (s.capabilities.supportsDataBreakpoints) {
|
||||
await s.sendDataBreakpoints(breakpointsToSend);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private sendExceptionBreakpoints(session?: IDebugSession): Promise<void> {
|
||||
const enabledExceptionBps = this.model.getExceptionBreakpoints().filter(exb => exb.enabled);
|
||||
|
||||
return this.sendToOneOrAllSessions(session, s => {
|
||||
return s.sendExceptionBreakpoints(enabledExceptionBps);
|
||||
return sendToOneOrAllSessions(this.model, session, async s => {
|
||||
if (s.capabilities.supportsConfigurationDoneRequest && (!s.capabilities.exceptionBreakpointFilters || s.capabilities.exceptionBreakpointFilters.length === 0)) {
|
||||
// Only call `setExceptionBreakpoints` as specified in dap protocol #90001
|
||||
return;
|
||||
}
|
||||
await s.sendExceptionBreakpoints(enabledExceptionBps);
|
||||
});
|
||||
}
|
||||
|
||||
private async sendToOneOrAllSessions(session: IDebugSession | undefined, send: (session: IDebugSession) => Promise<void>): Promise<void> {
|
||||
if (session) {
|
||||
await send(session);
|
||||
} else {
|
||||
await Promise.all(this.model.getSessions().map(s => send(s)));
|
||||
}
|
||||
}
|
||||
|
||||
private onFileChanges(fileChangesEvent: FileChangesEvent): void {
|
||||
const toRemove = this.model.getBreakpoints().filter(bp =>
|
||||
fileChangesEvent.contains(bp.uri, FileChangeType.DELETED));
|
||||
@@ -1126,3 +1132,11 @@ export function getStackFrameThreadAndSessionToFocus(model: IDebugModel, stackFr
|
||||
|
||||
return { session, thread, stackFrame };
|
||||
}
|
||||
|
||||
async function sendToOneOrAllSessions(model: DebugModel, session: IDebugSession | undefined, send: (session: IDebugSession) => Promise<void>): Promise<void> {
|
||||
if (session) {
|
||||
await send(session);
|
||||
} else {
|
||||
await Promise.all(model.getSessions().map(s => send(s)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -190,7 +190,7 @@ export class DebugSession implements IDebugSession {
|
||||
try {
|
||||
const customTelemetryService = await dbgr.getCustomTelemetryService();
|
||||
const debugAdapter = await dbgr.createDebugAdapter(this);
|
||||
this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.extensionHostDebugService, this.openerService);
|
||||
this.raw = new RawDebugSession(debugAdapter, dbgr, this.telemetryService, customTelemetryService, this.extensionHostDebugService, this.openerService, this.notificationService);
|
||||
|
||||
await this.raw.start();
|
||||
this.registerListeners();
|
||||
@@ -693,7 +693,6 @@ export class DebugSession implements IDebugSession {
|
||||
await this.raw.configurationDone();
|
||||
} catch (e) {
|
||||
// Disconnect the debug session on configuration done error #10596
|
||||
this.notificationService.error(e);
|
||||
if (this.raw) {
|
||||
this.raw.disconnect();
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import severity from 'vs/base/common/severity';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import Constants from 'vs/workbench/contrib/markers/browser/constants';
|
||||
import { ITaskService, ITaskSummary } from 'vs/workbench/contrib/tasks/common/taskService';
|
||||
import { IPanelService } from 'vs/workbench/services/panel/common/panelService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IWorkspaceFolder, IWorkspace } from 'vs/platform/workspace/common/workspace';
|
||||
import { TaskEvent, TaskEventKind, TaskIdentifier } from 'vs/workbench/contrib/tasks/common/tasks';
|
||||
@@ -18,6 +17,7 @@ import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { IDebugConfiguration } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { createErrorWithActions } from 'vs/base/common/errorsWithActions';
|
||||
import { IViewsService } from 'vs/workbench/common/views';
|
||||
|
||||
function once(match: (e: TaskEvent) => boolean, event: Event<TaskEvent>): Event<TaskEvent> {
|
||||
return (listener, thisArgs = null, disposables?) => {
|
||||
@@ -44,7 +44,7 @@ export class DebugTaskRunner {
|
||||
@ITaskService private readonly taskService: ITaskService,
|
||||
@IMarkerService private readonly markerService: IMarkerService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IPanelService private readonly panelService: IPanelService,
|
||||
@IViewsService private readonly viewsService: IViewsService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
) { }
|
||||
|
||||
@@ -56,7 +56,8 @@ export class DebugTaskRunner {
|
||||
try {
|
||||
this.canceled = false;
|
||||
const taskSummary = await this.runTask(root, taskId);
|
||||
if (this.canceled) {
|
||||
if (this.canceled || (taskSummary && taskSummary.exitCode === undefined)) {
|
||||
// User canceled, either debugging, or the prelaunch task
|
||||
return TaskRunResult.Failure;
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ export class DebugTaskRunner {
|
||||
return TaskRunResult.Success;
|
||||
}
|
||||
if (onTaskErrors === 'showErrors') {
|
||||
this.panelService.openPanel(Constants.MARKERS_PANEL_ID);
|
||||
await this.viewsService.openView(Constants.MARKERS_VIEW_ID);
|
||||
return Promise.resolve(TaskRunResult.Failure);
|
||||
}
|
||||
|
||||
@@ -77,7 +78,9 @@ export class DebugTaskRunner {
|
||||
? nls.localize('preLaunchTaskErrors', "Errors exist after running preLaunchTask '{0}'.", taskLabel)
|
||||
: errorCount === 1
|
||||
? nls.localize('preLaunchTaskError', "Error exists after running preLaunchTask '{0}'.", taskLabel)
|
||||
: nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", taskLabel, taskSummary ? taskSummary.exitCode : 0);
|
||||
: taskSummary && typeof taskSummary.exitCode === 'number'
|
||||
? nls.localize('preLaunchTaskExitCode', "The preLaunchTask '{0}' terminated with exit code {1}.", taskLabel, taskSummary.exitCode)
|
||||
: nls.localize('preLaunchTaskTerminated', "The preLaunchTask '{0}' terminated.", taskLabel);
|
||||
|
||||
const result = await this.dialogService.show(severity.Warning, message, [nls.localize('debugAnyway', "Debug Anyway"), nls.localize('showErrors', "Show Errors"), nls.localize('cancel', "Cancel")], {
|
||||
checkbox: {
|
||||
@@ -97,7 +100,7 @@ export class DebugTaskRunner {
|
||||
return TaskRunResult.Success;
|
||||
}
|
||||
|
||||
this.panelService.openPanel(Constants.MARKERS_PANEL_ID);
|
||||
await this.viewsService.openView(Constants.MARKERS_VIEW_ID);
|
||||
return Promise.resolve(TaskRunResult.Failure);
|
||||
} catch (err) {
|
||||
await onError(err.message, [this.taskService.configureAction()]);
|
||||
|
||||
@@ -606,8 +606,8 @@ export class LoadedScriptsView extends ViewPane {
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.tree = dispose(this.tree);
|
||||
this.treeLabels = dispose(this.treeLabels);
|
||||
dispose(this.tree);
|
||||
dispose(this.treeLabels);
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,6 @@
|
||||
border-radius: 2px;
|
||||
font-size: 0.9em;
|
||||
padding: 0 3px;
|
||||
margin-left: 0.8em;
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
@@ -174,12 +173,7 @@
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-call-stack .monaco-list-row:hover .stack-frame.has-actions .file .line-number {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-call-stack .monaco-list-row:hover .stack-frame.has-actions .monaco-action-bar {
|
||||
position: absolute;
|
||||
right: 2px;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.debug-viewlet .debug-call-stack .monaco-list-row .monaco-action-bar {
|
||||
@@ -250,6 +244,7 @@
|
||||
.debug-viewlet .debug-call-stack .stack-frame > .file > .file-name {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 0.8em;
|
||||
}
|
||||
|
||||
.vs-dark .debug-viewlet .debug-call-stack .monaco-list-row:not(.selected) .stack-frame > .file {
|
||||
|
||||
@@ -30,10 +30,6 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.monaco-workbench.mac .repl .repl-tree .monaco-tl-twistie {
|
||||
padding-right: 2px;
|
||||
}
|
||||
|
||||
.repl .repl-tree .output.expression.value-and-source {
|
||||
display: flex;
|
||||
}
|
||||
@@ -63,10 +59,6 @@
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
.repl .repl-tree .monaco-list-rows > .monaco-list-row .monaco-tl-twistie.collapsible {
|
||||
padding-left: 18px !important;
|
||||
}
|
||||
|
||||
.repl .repl-tree .output.expression > .value,
|
||||
.repl .repl-tree .evaluation-result.expression > .value {
|
||||
margin-left: 0px;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { env as processEnv } from 'vs/base/common/process';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
|
||||
/**
|
||||
* This interface represents a single command line argument split into a "prefix" and a "path" half.
|
||||
@@ -79,7 +80,8 @@ export class RawDebugSession implements IDisposable {
|
||||
private readonly telemetryService: ITelemetryService,
|
||||
public readonly customTelemetryService: ITelemetryService | undefined,
|
||||
private readonly extensionHostDebugService: IExtensionHostDebugService,
|
||||
private readonly openerService: IOpenerService
|
||||
private readonly openerService: IOpenerService,
|
||||
private readonly notificationService: INotificationService
|
||||
) {
|
||||
this.debugAdapter = debugAdapter;
|
||||
this._capabilities = Object.create(null);
|
||||
@@ -632,8 +634,8 @@ export class RawDebugSession implements IDisposable {
|
||||
return errors.canceled();
|
||||
}
|
||||
|
||||
const error = errorResponse && errorResponse.body ? errorResponse.body.error : null;
|
||||
const errorMessage = errorResponse ? errorResponse.message || '' : '';
|
||||
const error: DebugProtocol.Message | undefined = errorResponse?.body?.error;
|
||||
const errorMessage = errorResponse?.message || '';
|
||||
|
||||
if (error && error.sendTelemetry) {
|
||||
const telemetryMessage = error ? formatPII(error.format, true, error.variables) : errorMessage;
|
||||
@@ -641,15 +643,19 @@ export class RawDebugSession implements IDisposable {
|
||||
}
|
||||
|
||||
const userMessage = error ? formatPII(error.format, false, error.variables) : errorMessage;
|
||||
if (error && error.url) {
|
||||
const url = error?.url;
|
||||
if (error && url) {
|
||||
const label = error.urlLabel ? error.urlLabel : nls.localize('moreInfo', "More Info");
|
||||
return createErrorWithActions(userMessage, {
|
||||
actions: [new Action('debug.moreInfo', label, undefined, true, () => {
|
||||
this.openerService.open(URI.parse(error.url));
|
||||
this.openerService.open(URI.parse(url));
|
||||
return Promise.resolve(null);
|
||||
})]
|
||||
});
|
||||
}
|
||||
if (error && error.format && error.showUser) {
|
||||
this.notificationService.error(error.format);
|
||||
}
|
||||
|
||||
return new Error(userMessage);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import { registerEditorAction, ServicesAccessor, EditorAction } from 'vs/editor/
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
|
||||
import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { ICodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
@@ -60,17 +60,8 @@ import { IViewsService, IViewDescriptorService } from 'vs/workbench/common/views
|
||||
const $ = dom.$;
|
||||
|
||||
const HISTORY_STORAGE_KEY = 'debug.repl.history';
|
||||
const IPrivateReplService = createDecorator<IPrivateReplService>('privateReplService');
|
||||
const DECORATION_KEY = 'replinputdecoration';
|
||||
|
||||
interface IPrivateReplService {
|
||||
_serviceBrand: undefined;
|
||||
acceptReplInput(): void;
|
||||
getVisibleContent(): string;
|
||||
selectSession(session?: IDebugSession): Promise<void>;
|
||||
clearRepl(): Promise<void>;
|
||||
focusRepl(): void;
|
||||
}
|
||||
|
||||
function revealLastElement(tree: WorkbenchAsyncDataTree<any, any, any>) {
|
||||
tree.scrollTop = tree.scrollHeight - tree.renderHeight;
|
||||
@@ -78,7 +69,7 @@ function revealLastElement(tree: WorkbenchAsyncDataTree<any, any, any>) {
|
||||
|
||||
const sessionsToIgnore = new Set<IDebugSession>();
|
||||
|
||||
export class Repl extends ViewPane implements IPrivateReplService, IHistoryNavigationWidget {
|
||||
export class Repl extends ViewPane implements IHistoryNavigationWidget {
|
||||
_serviceBrand: undefined;
|
||||
|
||||
private static readonly REFRESH_DELAY = 100; // delay in ms to refresh the repl for new elements to show
|
||||
@@ -499,8 +490,7 @@ export class Repl extends ViewPane implements IPrivateReplService, IHistoryNavig
|
||||
this._register(scopedContextKeyService);
|
||||
CONTEXT_IN_DEBUG_REPL.bindTo(scopedContextKeyService).set(true);
|
||||
|
||||
this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection(
|
||||
[IContextKeyService, scopedContextKeyService], [IPrivateReplService, this]));
|
||||
this.scopedInstantiationService = this.instantiationService.createChild(new ServiceCollection([IContextKeyService, scopedContextKeyService]));
|
||||
const options = getSimpleEditorOptions();
|
||||
options.readOnly = true;
|
||||
options.ariaLabel = localize('debugConsole', "Debug Console");
|
||||
@@ -634,7 +624,8 @@ class AcceptReplInputAction extends EditorAction {
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
|
||||
SuggestController.get(editor).acceptSelectedSuggestion(false, true);
|
||||
accessor.get(IPrivateReplService).acceptReplInput();
|
||||
const repl = getReplView(accessor.get(IViewsService));
|
||||
repl?.acceptReplInput();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -656,7 +647,8 @@ class FilterReplAction extends EditorAction {
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
|
||||
SuggestController.get(editor).acceptSelectedSuggestion(false, true);
|
||||
accessor.get(IPrivateReplService).focusRepl();
|
||||
const repl = getReplView(accessor.get(IViewsService));
|
||||
repl?.focusRepl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -673,7 +665,10 @@ class ReplCopyAllAction extends EditorAction {
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): void | Promise<void> {
|
||||
const clipboardService = accessor.get(IClipboardService);
|
||||
return clipboardService.writeText(accessor.get(IPrivateReplService).getVisibleContent());
|
||||
const repl = getReplView(accessor.get(IViewsService));
|
||||
if (repl) {
|
||||
return clipboardService.writeText(repl.getVisibleContent());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,7 +697,7 @@ class SelectReplAction extends Action {
|
||||
|
||||
constructor(id: string, label: string,
|
||||
@IDebugService private readonly debugService: IDebugService,
|
||||
@IPrivateReplService private readonly replService: IPrivateReplService
|
||||
@IViewsService private readonly viewsService: IViewsService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
@@ -712,7 +707,10 @@ class SelectReplAction extends Action {
|
||||
if (session && session.state !== State.Inactive && session !== this.debugService.getViewModel().focusedSession) {
|
||||
await this.debugService.focusStackFrame(undefined, undefined, session, true);
|
||||
} else {
|
||||
await this.replService.selectSession(session);
|
||||
const repl = getReplView(this.viewsService);
|
||||
if (repl) {
|
||||
await repl.selectSession(session);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -733,3 +731,7 @@ export class ClearReplAction extends Action {
|
||||
aria.status(localize('debugConsoleCleared', "Debug console was cleared"));
|
||||
}
|
||||
}
|
||||
|
||||
function getReplView(viewsService: IViewsService): Repl | undefined {
|
||||
return viewsService.getActiveViewWithId(REPL_VIEW_ID) as Repl ?? undefined;
|
||||
}
|
||||
|
||||
@@ -96,7 +96,6 @@ export class ReplEvaluationResultsRenderer implements ITreeRenderer<ReplEvaluati
|
||||
renderElement(element: ITreeNode<ReplEvaluationResult, FuzzyScore>, index: number, templateData: IReplEvaluationResultTemplateData): void {
|
||||
const expression = element.element;
|
||||
renderExpressionValue(expression, templateData.value, {
|
||||
preserveWhitespace: !expression.hasChildren,
|
||||
showHover: false,
|
||||
colorize: true,
|
||||
linkDetector: this.linkDetector
|
||||
@@ -230,7 +229,6 @@ export class ReplRawObjectsRenderer implements ITreeRenderer<RawObjectReplElemen
|
||||
|
||||
// value
|
||||
renderExpressionValue(element.value, templateData.value, {
|
||||
preserveWhitespace: true,
|
||||
showHover: false,
|
||||
linkDetector: this.linkDetector
|
||||
});
|
||||
|
||||
@@ -267,7 +267,6 @@ export class WatchExpressionsRenderer extends AbstractExpressionsRenderer {
|
||||
renderExpressionValue(expression, data.value, {
|
||||
showChanged: true,
|
||||
maxValueLength: MAX_VALUE_RENDER_LENGTH_IN_VIEWLET,
|
||||
preserveWhitespace: false,
|
||||
showHover: true,
|
||||
colorize: true
|
||||
});
|
||||
|
||||
@@ -55,6 +55,7 @@ export const CONTEXT_FOCUSED_SESSION_IS_ATTACH = new RawContextKey<boolean>('foc
|
||||
export const CONTEXT_STEP_BACK_SUPPORTED = new RawContextKey<boolean>('stepBackSupported', false);
|
||||
export const CONTEXT_RESTART_FRAME_SUPPORTED = new RawContextKey<boolean>('restartFrameSupported', false);
|
||||
export const CONTEXT_JUMP_TO_CURSOR_SUPPORTED = new RawContextKey<boolean>('jumpToCursorSupported', false);
|
||||
export const CONTEXT_BREAKPOINTS_EXIST = new RawContextKey<boolean>('breakpointsExist', false);
|
||||
|
||||
export const EDITOR_CONTRIBUTION_ID = 'editor.contrib.debug';
|
||||
export const BREAKPOINT_EDITOR_CONTRIBUTION_ID = 'editor.contrib.breakpoint';
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
ITreeElement, IExpression, IExpressionContainer, IDebugSession, IStackFrame, IExceptionBreakpoint, IBreakpoint, IFunctionBreakpoint, IDebugModel,
|
||||
IThread, IRawModelUpdate, IScope, IRawStoppedDetails, IEnablement, IBreakpointData, IExceptionInfo, IBreakpointsChangeEvent, IBreakpointUpdateData, IBaseBreakpoint, State, IDataBreakpoint
|
||||
} from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { Source, UNKNOWN_SOURCE_LABEL } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { Source, UNKNOWN_SOURCE_LABEL, getUriFromSource } from 'vs/workbench/contrib/debug/common/debugSource';
|
||||
import { commonSuffixLength } from 'vs/base/common/strings';
|
||||
import { posix } from 'vs/base/common/path';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
@@ -515,6 +515,7 @@ interface IBreakpointSessionData extends DebugProtocol.Breakpoint {
|
||||
supportsLogPoints: boolean;
|
||||
supportsFunctionBreakpoints: boolean;
|
||||
supportsDataBreakpoints: boolean;
|
||||
sessionId: string;
|
||||
}
|
||||
|
||||
function toBreakpointSessionData(data: DebugProtocol.Breakpoint, capabilities: DebugProtocol.Capabilities): IBreakpointSessionData {
|
||||
@@ -549,6 +550,7 @@ export abstract class BaseBreakpoint extends Enablement implements IBaseBreakpoi
|
||||
if (!data) {
|
||||
this.sessionData.delete(sessionId);
|
||||
} else {
|
||||
data.sessionId = sessionId;
|
||||
this.sessionData.set(sessionId, data);
|
||||
}
|
||||
|
||||
@@ -596,7 +598,7 @@ export abstract class BaseBreakpoint extends Enablement implements IBaseBreakpoi
|
||||
export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
|
||||
|
||||
constructor(
|
||||
public uri: uri,
|
||||
private _uri: uri,
|
||||
private _lineNumber: number,
|
||||
private _column: number | undefined,
|
||||
enabled: boolean,
|
||||
@@ -616,12 +618,16 @@ export class Breakpoint extends BaseBreakpoint implements IBreakpoint {
|
||||
|
||||
get verified(): boolean {
|
||||
if (this.data) {
|
||||
return this.data.verified && !this.textFileService.isDirty(this.uri);
|
||||
return this.data.verified && !this.textFileService.isDirty(this._uri);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
get uri(): uri {
|
||||
return this.verified && this.data && this.data.source ? getUriFromSource(this.data.source, this.data.source.path, this.data.sessionId) : this._uri;
|
||||
}
|
||||
|
||||
get column(): number | undefined {
|
||||
return this.verified && this.data && typeof this.data.column === 'number' ? this.data.column : this._column;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { URI as uri } from 'vs/base/common/uri';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { normalize, isAbsolute } from 'vs/base/common/path';
|
||||
import * as resources from 'vs/base/common/resources';
|
||||
import { DEBUG_SCHEME } from 'vs/workbench/contrib/debug/common/debug';
|
||||
@@ -13,6 +13,7 @@ import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from 'vs/workbench/services/
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { isUri } from 'vs/workbench/contrib/debug/common/debugUtils';
|
||||
import { ITextEditor } from 'vs/workbench/common/editor';
|
||||
import { TextEditorSelectionRevealType } from 'vs/platform/editor/common/editor';
|
||||
|
||||
export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source");
|
||||
|
||||
@@ -31,7 +32,7 @@ export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Sourc
|
||||
|
||||
export class Source {
|
||||
|
||||
readonly uri: uri;
|
||||
readonly uri: URI;
|
||||
available: boolean;
|
||||
raw: DebugProtocol.Source;
|
||||
|
||||
@@ -47,30 +48,7 @@ export class Source {
|
||||
path = `${DEBUG_SCHEME}:${UNKNOWN_SOURCE_LABEL}`;
|
||||
}
|
||||
|
||||
if (typeof this.raw.sourceReference === 'number' && this.raw.sourceReference > 0) {
|
||||
this.uri = uri.from({
|
||||
scheme: DEBUG_SCHEME,
|
||||
path,
|
||||
query: `session=${sessionId}&ref=${this.raw.sourceReference}`
|
||||
});
|
||||
} else {
|
||||
if (isUri(path)) { // path looks like a uri
|
||||
this.uri = uri.parse(path);
|
||||
} else {
|
||||
// assume a filesystem path
|
||||
if (isAbsolute(path)) {
|
||||
this.uri = uri.file(path);
|
||||
} else {
|
||||
// path is relative: since VS Code cannot deal with this by itself
|
||||
// create a debug url that will result in a DAP 'source' request when the url is resolved.
|
||||
this.uri = uri.from({
|
||||
scheme: DEBUG_SCHEME,
|
||||
path,
|
||||
query: `session=${sessionId}`
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
this.uri = getUriFromSource(this.raw, path, sessionId);
|
||||
}
|
||||
|
||||
get name() {
|
||||
@@ -95,19 +73,19 @@ export class Source {
|
||||
|
||||
openInEditor(editorService: IEditorService, selection: IRange, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<ITextEditor | undefined> {
|
||||
return !this.available ? Promise.resolve(undefined) : editorService.openEditor({
|
||||
resource: this.uri,
|
||||
resource: this.uri.with({ query: null }),
|
||||
description: this.origin,
|
||||
options: {
|
||||
preserveFocus,
|
||||
selection,
|
||||
revealIfOpened: true,
|
||||
revealInCenterIfOutsideViewport: true,
|
||||
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,
|
||||
pinned: pinned || (!preserveFocus && !this.inMemory)
|
||||
}
|
||||
}, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
|
||||
}
|
||||
|
||||
static getEncodedDebugData(modelUri: uri): { name: string, path: string, sessionId?: string, sourceReference?: number } {
|
||||
static getEncodedDebugData(modelUri: URI): { name: string, path: string, sessionId?: string, sourceReference?: number } {
|
||||
let path: string;
|
||||
let sourceReference: number | undefined;
|
||||
let sessionId: string | undefined;
|
||||
@@ -148,3 +126,28 @@ export class Source {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export function getUriFromSource(raw: DebugProtocol.Source, path: string | undefined, sessionId: string): URI {
|
||||
if (typeof raw.sourceReference === 'number' && raw.sourceReference > 0) {
|
||||
return URI.from({
|
||||
scheme: DEBUG_SCHEME,
|
||||
path,
|
||||
query: `session=${sessionId}&ref=${raw.sourceReference}`
|
||||
});
|
||||
}
|
||||
|
||||
if (path && isUri(path)) { // path looks like a uri
|
||||
return URI.parse(path);
|
||||
}
|
||||
// assume a filesystem path
|
||||
if (path && isAbsolute(path)) {
|
||||
return URI.file(path);
|
||||
}
|
||||
// path is relative: since VS Code cannot deal with this by itself
|
||||
// create a debug url that will result in a DAP 'source' request when the url is resolved.
|
||||
return URI.from({
|
||||
scheme: DEBUG_SCHEME,
|
||||
path,
|
||||
query: `session=${sessionId}`
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { deepClone } from 'vs/base/common/objects';
|
||||
|
||||
const _formatPIIRegexp = /{([^}]+)}/g;
|
||||
|
||||
export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string }): string {
|
||||
export function formatPII(value: string, excludePII: boolean, args: { [key: string]: string } | undefined): string {
|
||||
return value.replace(_formatPIIRegexp, function (match, group) {
|
||||
if (excludePII && group.length > 0 && group[0] !== '_') {
|
||||
return match;
|
||||
@@ -246,6 +246,9 @@ export function getVisibleAndSorted<T extends { presentation?: IConfigPresentati
|
||||
return -1;
|
||||
}
|
||||
if (!first.presentation.group) {
|
||||
if (!second.presentation.group) {
|
||||
return compareOrders(first.presentation.order, second.presentation.order);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (!second.presentation.group) {
|
||||
@@ -254,13 +257,18 @@ export function getVisibleAndSorted<T extends { presentation?: IConfigPresentati
|
||||
if (first.presentation.group !== second.presentation.group) {
|
||||
return first.presentation.group.localeCompare(second.presentation.group);
|
||||
}
|
||||
if (typeof first.presentation.order !== 'number') {
|
||||
return 1;
|
||||
}
|
||||
if (typeof second.presentation.order !== 'number') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return first.presentation.order - second.presentation.order;
|
||||
return compareOrders(first.presentation.order, second.presentation.order);
|
||||
});
|
||||
}
|
||||
|
||||
function compareOrders(first: number | undefined, second: number | undefined): number {
|
||||
if (typeof first !== 'number') {
|
||||
return 1;
|
||||
}
|
||||
if (typeof second !== 'number') {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return first - second;
|
||||
}
|
||||
|
||||
@@ -4,17 +4,18 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { replaceWhitespace, renderExpressionValue, renderVariable, renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import { renderExpressionValue, renderVariable, renderViewTree } from 'vs/workbench/contrib/debug/browser/baseDebugView';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { Expression, Variable, Scope, StackFrame, Thread, DebugModel } from 'vs/workbench/contrib/debug/common/debugModel';
|
||||
import { MockSession } from 'vs/workbench/contrib/debug/test/common/mockDebug';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test';
|
||||
import { isStatusbarInDebugMode } from 'vs/workbench/contrib/debug/browser/statusbarColorProvider';
|
||||
import { State } from 'vs/workbench/contrib/debug/common/debug';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
const $ = dom.$;
|
||||
|
||||
suite('Debug - Base Debug View', () => {
|
||||
@@ -28,13 +29,6 @@ suite('Debug - Base Debug View', () => {
|
||||
linkDetector = instantiationService.createInstance(LinkDetector);
|
||||
});
|
||||
|
||||
test('replace whitespace', () => {
|
||||
assert.equal(replaceWhitespace('hey there'), 'hey there');
|
||||
assert.equal(replaceWhitespace('hey there\n'), 'hey there\\n');
|
||||
assert.equal(replaceWhitespace('hey \r there\n\t'), 'hey \\r there\\n\\t');
|
||||
assert.equal(replaceWhitespace('hey \r\t\n\t\t\n there'), 'hey \\r\\t\\n\\t\\t\\n there');
|
||||
});
|
||||
|
||||
test('render view tree', () => {
|
||||
const container = $('.container');
|
||||
const treeContainer = renderViewTree(container);
|
||||
@@ -47,7 +41,7 @@ suite('Debug - Base Debug View', () => {
|
||||
|
||||
test.skip('render expression value', () => { // {{SQL CARBON EDIT}} skip test
|
||||
let container = $('.container');
|
||||
renderExpressionValue('render \n me', container, { showHover: true, preserveWhitespace: true });
|
||||
renderExpressionValue('render \n me', container, { showHover: true });
|
||||
assert.equal(container.className, 'value');
|
||||
assert.equal(container.title, 'render \n me');
|
||||
assert.equal(container.textContent, 'render \n me');
|
||||
@@ -76,7 +70,7 @@ suite('Debug - Base Debug View', () => {
|
||||
renderExpressionValue(expression, container, { colorize: true, maxValueLength: 4, linkDetector });
|
||||
assert.equal(container.textContent, 'this...');
|
||||
|
||||
expression.value = process.platform === 'win32' ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
expression.value = isWindows ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
container = $('.container');
|
||||
renderExpressionValue(expression, container, { colorize: true, linkDetector });
|
||||
assert.ok(container.querySelector('a'));
|
||||
@@ -109,7 +103,7 @@ suite('Debug - Base Debug View', () => {
|
||||
assert.equal(label.element.textContent, 'foo:');
|
||||
assert.equal(label.element.title, 'string');
|
||||
|
||||
variable.value = process.platform === 'win32' ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
variable.value = isWindows ? 'C:\\foo.js:5' : '/foo.js:5';
|
||||
expression = $('.');
|
||||
name = $('.');
|
||||
value = $('.');
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
import { WorkspaceFolder } from 'vs/platform/workspace/common/workspace';
|
||||
|
||||
@@ -135,7 +135,7 @@ suite('Debug - REPL', () => {
|
||||
model.addSession(session);
|
||||
|
||||
const adapter = new MockDebugAdapter();
|
||||
const raw = new RawDebugSession(adapter, undefined!, undefined!, undefined!, undefined!, undefined!);
|
||||
const raw = new RawDebugSession(adapter, undefined!, undefined!, undefined!, undefined!, undefined!, undefined!);
|
||||
session.initializeForTest(raw);
|
||||
|
||||
await session.addReplExpression(undefined, 'before.1');
|
||||
|
||||
@@ -103,15 +103,34 @@ suite('Debug - Utils', () => {
|
||||
order: 500
|
||||
}
|
||||
});
|
||||
configs.push({
|
||||
type: 'node',
|
||||
request: 'launch',
|
||||
name: 'h',
|
||||
presentation: {
|
||||
order: 700
|
||||
}
|
||||
});
|
||||
configs.push({
|
||||
type: 'node',
|
||||
request: 'launch',
|
||||
name: 'i',
|
||||
presentation: {
|
||||
order: 1000
|
||||
}
|
||||
});
|
||||
|
||||
const sorted = getVisibleAndSorted(configs);
|
||||
assert.equal(sorted.length, 7);
|
||||
assert.equal(sorted.length, 9);
|
||||
assert.equal(sorted[0].name, 'f');
|
||||
assert.equal(sorted[1].name, 'd');
|
||||
assert.equal(sorted[2].name, 'e');
|
||||
assert.equal(sorted[3].name, 'g');
|
||||
assert.equal(sorted[4].name, 'b');
|
||||
assert.equal(sorted[5].name, 'p');
|
||||
assert.equal(sorted[6].name, 'a');
|
||||
assert.equal(sorted[4].name, 'h');
|
||||
assert.equal(sorted[5].name, 'i');
|
||||
assert.equal(sorted[6].name, 'b');
|
||||
assert.equal(sorted[7].name, 'p');
|
||||
assert.equal(sorted[8].name, 'a');
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { appendStylizedStringToContainer, handleANSIOutput, calcANSI8bitColor } from 'vs/workbench/contrib/debug/browser/debugANSIHandling';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/browser/workbenchTestServices';
|
||||
import { LinkDetector } from 'vs/workbench/contrib/debug/browser/linkDetector';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -11,7 +11,7 @@ import { Debugger } from 'vs/workbench/contrib/debug/common/debugger';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ExecutableDebugAdapter } from 'vs/workbench/contrib/debug/node/debugAdapter';
|
||||
import { TestTextResourcePropertiesService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestTextResourcePropertiesService } from 'vs/editor/test/common/services/modelService.test';
|
||||
import { ExtensionIdentifier, IExtensionDescription } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user