Skip to content

Commit

Permalink
Make debug editor contributions lazy (microsoft#170270)
Browse files Browse the repository at this point in the history
  • Loading branch information
roblourens authored Dec 30, 2022
1 parent d227bd7 commit 92df25d
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 111 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { RunOnceScheduler } from 'vs/base/common/async';
import { memoize } from 'vs/base/common/decorators';
import { onUnexpectedError } from 'vs/base/common/errors';
import { MarkdownString } from 'vs/base/common/htmlContent';
import { Disposable, dispose, disposeIfDisposable, IDisposable } from 'vs/base/common/lifecycle';
import { dispose, disposeIfDisposable, IDisposable } from 'vs/base/common/lifecycle';
import * as env from 'vs/base/common/platform';
import severity from 'vs/base/common/severity';
import { noBreakWhitespace } from 'vs/base/common/strings';
Expand Down Expand Up @@ -188,33 +188,7 @@ async function createCandidateDecorations(model: ITextModel, breakpointDecoratio
return result;
}

export class LazyBreakpointEditorContribution extends Disposable implements IBreakpointEditorContribution {
private _contrib: IBreakpointEditorContribution | undefined;

constructor(editor: ICodeEditor, @IInstantiationService instantiationService: IInstantiationService) {
super();

const listener = editor.onDidChangeModel(() => {
if (editor.hasModel()) {
listener.dispose();
this._contrib = this._register(instantiationService.createInstance(BreakpointEditorContribution, editor));
}
});
}
showBreakpointWidget(lineNumber: number, column: number | undefined, context?: BreakpointWidgetContext | undefined): void {
this._contrib?.showBreakpointWidget(lineNumber, column, context);
}

closeBreakpointWidget(): void {
this._contrib?.closeBreakpointWidget();
}

getContextMenuActionsAtPosition(lineNumber: number, model: ITextModel): IAction[] {
return this._contrib?.getContextMenuActionsAtPosition(lineNumber, model) ?? [];
}
}

class BreakpointEditorContribution implements IBreakpointEditorContribution {
export class BreakpointEditorContribution implements IBreakpointEditorContribution {

private breakpointHintDecoration: string | null = null;
private breakpointWidget: BreakpointWidget | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { Range } from 'vs/editor/common/core/range';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { IModelDecorationOptions, IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
import { localize } from 'vs/nls';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant, themeColorFromId, ThemeIcon } from 'vs/platform/theme/common/themeService';
Expand Down Expand Up @@ -108,20 +107,7 @@ export function createDecorationsForStackFrame(stackFrame: IStackFrame, isFocuse
return result;
}

export class LazyCallStackEditorContribution extends Disposable {
constructor(editor: ICodeEditor, @IInstantiationService instantiationService: IInstantiationService) {
super();

const listener = editor.onDidChangeModel(() => {
if (editor.hasModel()) {
listener.dispose();
this._register(instantiationService.createInstance(CallStackEditorContribution, editor));
}
});
}
}

class CallStackEditorContribution extends Disposable implements IEditorContribution {
export class CallStackEditorContribution extends Disposable implements IEditorContribution {
private decorations = this.editor.createDecorationsCollection();

constructor(
Expand Down
14 changes: 7 additions & 7 deletions src/vs/workbench/contrib/debug/browser/debug.contribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneCont
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry } from 'vs/workbench/common/contributions';
import { EditorExtensions } from 'vs/workbench/common/editor';
import { Extensions as ViewExtensions, IViewContainersRegistry, IViewsRegistry, ViewContainer, ViewContainerLocation } from 'vs/workbench/common/views';
import { LazyBreakpointEditorContribution } from 'vs/workbench/contrib/debug/browser/breakpointEditorContribution';
import { BreakpointEditorContribution } from 'vs/workbench/contrib/debug/browser/breakpointEditorContribution';
import { BreakpointsView } from 'vs/workbench/contrib/debug/browser/breakpointsView';
import { LazyCallStackEditorContribution } from 'vs/workbench/contrib/debug/browser/callStackEditorContribution';
import { CallStackEditorContribution } from 'vs/workbench/contrib/debug/browser/callStackEditorContribution';
import { CallStackView } from 'vs/workbench/contrib/debug/browser/callStackView';
import { registerColors } from 'vs/workbench/contrib/debug/browser/debugColors';
import { ADD_CONFIGURATION_ID, CALLSTACK_BOTTOM_ID, CALLSTACK_BOTTOM_LABEL, CALLSTACK_DOWN_ID, CALLSTACK_DOWN_LABEL, CALLSTACK_TOP_ID, CALLSTACK_TOP_LABEL, CALLSTACK_UP_ID, CALLSTACK_UP_LABEL, CONTINUE_ID, CONTINUE_LABEL, COPY_STACK_TRACE_ID, DEBUG_COMMAND_CATEGORY, DEBUG_CONSOLE_QUICK_ACCESS_PREFIX, DEBUG_QUICK_ACCESS_PREFIX, DEBUG_RUN_COMMAND_ID, DEBUG_RUN_LABEL, DEBUG_START_COMMAND_ID, DEBUG_START_LABEL, DISCONNECT_AND_SUSPEND_ID, DISCONNECT_AND_SUSPEND_LABEL, DISCONNECT_ID, DISCONNECT_LABEL, EDIT_EXPRESSION_COMMAND_ID, FOCUS_REPL_ID, JUMP_TO_CURSOR_ID, NEXT_DEBUG_CONSOLE_ID, NEXT_DEBUG_CONSOLE_LABEL, OPEN_LOADED_SCRIPTS_LABEL, PAUSE_ID, PAUSE_LABEL, PREV_DEBUG_CONSOLE_ID, PREV_DEBUG_CONSOLE_LABEL, REMOVE_EXPRESSION_COMMAND_ID, RESTART_FRAME_ID, RESTART_LABEL, RESTART_SESSION_ID, SELECT_AND_START_ID, SELECT_AND_START_LABEL, SELECT_DEBUG_CONSOLE_ID, SELECT_DEBUG_CONSOLE_LABEL, SELECT_DEBUG_SESSION_ID, SELECT_DEBUG_SESSION_LABEL, SET_EXPRESSION_COMMAND_ID, SHOW_LOADED_SCRIPTS_ID, STEP_INTO_ID, STEP_INTO_LABEL, STEP_INTO_TARGET_ID, STEP_INTO_TARGET_LABEL, STEP_OUT_ID, STEP_OUT_LABEL, STEP_OVER_ID, STEP_OVER_LABEL, STOP_ID, STOP_LABEL, TERMINATE_THREAD_ID, TOGGLE_INLINE_BREAKPOINT_ID } from 'vs/workbench/contrib/debug/browser/debugCommands';
import { DebugConsoleQuickAccess } from 'vs/workbench/contrib/debug/browser/debugConsoleQuickAccess';
import { RunToCursorAction, SelectionToReplAction, SelectionToWatchExpressionsAction } from 'vs/workbench/contrib/debug/browser/debugEditorActions';
import { LazyDebugEditorContribution } from 'vs/workbench/contrib/debug/browser/debugEditorContribution';
import { DebugEditorContribution } from 'vs/workbench/contrib/debug/browser/debugEditorContribution';
import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons';
import { DebugProgressContribution } from 'vs/workbench/contrib/debug/browser/debugProgress';
import { StartDebugQuickAccessProvider } from 'vs/workbench/contrib/debug/browser/debugQuickAccess';
Expand All @@ -49,7 +49,7 @@ import { StatusBarColorProvider } from 'vs/workbench/contrib/debug/browser/statu
import { ADD_TO_WATCH_ID, BREAK_WHEN_VALUE_CHANGES_ID, BREAK_WHEN_VALUE_IS_ACCESSED_ID, BREAK_WHEN_VALUE_IS_READ_ID, COPY_EVALUATE_PATH_ID, COPY_VALUE_ID, SET_VARIABLE_ID, VariablesView, VIEW_MEMORY_ID } from 'vs/workbench/contrib/debug/browser/variablesView';
import { ADD_WATCH_ID, ADD_WATCH_LABEL, REMOVE_WATCH_EXPRESSIONS_COMMAND_ID, REMOVE_WATCH_EXPRESSIONS_LABEL, WatchExpressionsView } from 'vs/workbench/contrib/debug/browser/watchExpressionsView';
import { WelcomeView } from 'vs/workbench/contrib/debug/browser/welcomeView';
import { BREAKPOINTS_VIEW_ID, BREAKPOINT_EDITOR_CONTRIBUTION_ID, CALLSTACK_VIEW_ID, CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_CAN_VIEW_MEMORY, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_HAS_DEBUGGED, CONTEXT_DEBUG_STATE, CONTEXT_DEBUG_UX, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_IN_DEBUG_MODE, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_SET_EXPRESSION_SUPPORTED, CONTEXT_SET_VARIABLE_SUPPORTED, CONTEXT_STACK_FRAME_SUPPORTS_RESTART, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_SUSPEND_DEBUGGEE_SUPPORTED, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED, CONTEXT_VARIABLE_EVALUATE_NAME_PRESENT, CONTEXT_VARIABLE_IS_READONLY, CONTEXT_WATCH_ITEM_TYPE, DEBUG_PANEL_ID, DISASSEMBLY_VIEW_ID, EDITOR_CONTRIBUTION_ID, getStateLabel, IDebugService, INTERNAL_CONSOLE_OPTIONS_SCHEMA, LOADED_SCRIPTS_VIEW_ID, REPL_VIEW_ID, State, VARIABLES_VIEW_ID, VIEWLET_ID, WATCH_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
import { BREAKPOINTS_VIEW_ID, BREAKPOINT_EDITOR_CONTRIBUTION_ID, CALLSTACK_VIEW_ID, CONTEXT_BREAKPOINTS_EXIST, CONTEXT_BREAK_WHEN_VALUE_CHANGES_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_ACCESSED_SUPPORTED, CONTEXT_BREAK_WHEN_VALUE_IS_READ_SUPPORTED, CONTEXT_CALLSTACK_ITEM_TYPE, CONTEXT_CAN_VIEW_MEMORY, CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_STATE, CONTEXT_DEBUG_UX, CONTEXT_FOCUSED_SESSION_IS_ATTACH, CONTEXT_HAS_DEBUGGED, CONTEXT_IN_DEBUG_MODE, CONTEXT_JUMP_TO_CURSOR_SUPPORTED, CONTEXT_LOADED_SCRIPTS_SUPPORTED, CONTEXT_RESTART_FRAME_SUPPORTED, CONTEXT_SET_EXPRESSION_SUPPORTED, CONTEXT_SET_VARIABLE_SUPPORTED, CONTEXT_STACK_FRAME_SUPPORTS_RESTART, CONTEXT_STEP_INTO_TARGETS_SUPPORTED, CONTEXT_SUSPEND_DEBUGGEE_SUPPORTED, CONTEXT_TERMINATE_DEBUGGEE_SUPPORTED, CONTEXT_VARIABLE_EVALUATE_NAME_PRESENT, CONTEXT_VARIABLE_IS_READONLY, CONTEXT_WATCH_ITEM_TYPE, DEBUG_PANEL_ID, DISASSEMBLY_VIEW_ID, EDITOR_CONTRIBUTION_ID, getStateLabel, IDebugService, INTERNAL_CONSOLE_OPTIONS_SCHEMA, LOADED_SCRIPTS_VIEW_ID, REPL_VIEW_ID, State, VARIABLES_VIEW_ID, VIEWLET_ID, WATCH_VIEW_ID } from 'vs/workbench/contrib/debug/common/debug';
import { DebugContentProvider } from 'vs/workbench/contrib/debug/common/debugContentProvider';
import { DebugLifecycle } from 'vs/workbench/contrib/debug/common/debugLifecycle';
import { DisassemblyViewInput } from 'vs/workbench/contrib/debug/common/disassemblyViewInput';
Expand Down Expand Up @@ -90,9 +90,9 @@ Registry.as<IQuickAccessRegistry>(QuickAccessExtensions.Quickaccess).registerQui
helpEntries: [{ description: nls.localize('tasksQuickAccessHelp', "Show All Debug Consoles"), commandId: SELECT_DEBUG_CONSOLE_ID }]
});

registerEditorContribution('editor.contrib.callStack', LazyCallStackEditorContribution, EditorContributionInstantiation.Eager);
registerEditorContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID, LazyBreakpointEditorContribution, EditorContributionInstantiation.Eager);
registerEditorContribution(EDITOR_CONTRIBUTION_ID, LazyDebugEditorContribution, EditorContributionInstantiation.Eager);
registerEditorContribution('editor.contrib.callStack', CallStackEditorContribution, EditorContributionInstantiation.AfterFirstRender);
registerEditorContribution(BREAKPOINT_EDITOR_CONTRIBUTION_ID, BreakpointEditorContribution, EditorContributionInstantiation.AfterFirstRender);
registerEditorContribution(EDITOR_CONTRIBUTION_ID, DebugEditorContribution, EditorContributionInstantiation.BeforeFirstInteraction);

const registerDebugCommandPaletteItem = (id: string, title: ICommandActionTitle, when?: ContextKeyExpression, precondition?: ContextKeyExpression) => {
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
Expand Down
95 changes: 34 additions & 61 deletions src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,50 +3,50 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import * as nls from 'vs/nls';
import * as strings from 'vs/base/common/strings';
import { addDisposableListener } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { distinct, flatten } from 'vs/base/common/arrays';
import { RunOnceScheduler } from 'vs/base/common/async';
import * as env from 'vs/base/common/platform';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { memoize } from 'vs/base/common/decorators';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { Event } from 'vs/base/common/event';
import { visit } from 'vs/base/common/json';
import { setProperty } from 'vs/base/common/jsonEdit';
import { Constants } from 'vs/base/common/uint';
import { KeyCode } from 'vs/base/common/keyCodes';
import { IKeyboardEvent, StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
import { InlineValueContext } from 'vs/editor/common/languages';
import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { distinct, flatten } from 'vs/base/common/arrays';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { DEFAULT_WORD_REGEXP } from 'vs/editor/common/core/wordHelper';
import { ICodeEditor, IEditorMouseEvent, MouseTargetType, IPartialEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
import { Range } from 'vs/editor/common/core/range';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugEditorContribution, IDebugService, State, IStackFrame, IDebugConfiguration, IExpression, IExceptionInfo, IDebugSession, CONTEXT_EXCEPTION_WIDGET_VISIBLE } from 'vs/workbench/contrib/debug/common/debug';
import { ExceptionWidget } from 'vs/workbench/contrib/debug/browser/exceptionWidget';
import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor';
import { Position } from 'vs/editor/common/core/position';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { basename } from 'vs/base/common/path';
import * as env from 'vs/base/common/platform';
import * as strings from 'vs/base/common/strings';
import { Constants } from 'vs/base/common/uint';
import { CoreEditingCommands } from 'vs/editor/browser/coreCommands';
import { memoize } from 'vs/base/common/decorators';
import { IEditorHoverOptions, EditorOption } from 'vs/editor/common/config/editorOptions';
import { DebugHoverWidget } from 'vs/workbench/contrib/debug/browser/debugHover';
import { IModelDeltaDecoration, InjectedTextCursorStops, ITextModel } from 'vs/editor/common/model';
import { Disposable, dispose, IDisposable } from 'vs/base/common/lifecycle';
import { ICodeEditor, IEditorMouseEvent, IPartialEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
import { EditorOption, IEditorHoverOptions } from 'vs/editor/common/config/editorOptions';
import { EditOperation } from 'vs/editor/common/core/editOperation';
import { basename } from 'vs/base/common/path';
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { DEFAULT_WORD_REGEXP } from 'vs/editor/common/core/wordHelper';
import { StandardTokenType } from 'vs/editor/common/encodedTokenAttributes';
import { InlineValueContext } from 'vs/editor/common/languages';
import { IModelDeltaDecoration, InjectedTextCursorStops, ITextModel } from 'vs/editor/common/model';
import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { ModesHoverController } from 'vs/editor/contrib/hover/browser/hover';
import { HoverStartMode, HoverStartSource } from 'vs/editor/contrib/hover/browser/hoverOperation';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { Event } from 'vs/base/common/event';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
import * as nls from 'vs/nls';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { registerColor } from 'vs/platform/theme/common/colorRegistry';
import { addDisposableListener } from 'vs/base/browser/dom';
import { DomEmitter } from 'vs/base/browser/event';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import { IFeatureDebounceInformation, ILanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
import { FloatingClickWidget } from 'vs/workbench/browser/codeeditor';
import { DebugHoverWidget } from 'vs/workbench/contrib/debug/browser/debugHover';
import { ExceptionWidget } from 'vs/workbench/contrib/debug/browser/exceptionWidget';
import { CONTEXT_EXCEPTION_WIDGET_VISIBLE, IDebugConfiguration, IDebugEditorContribution, IDebugService, IDebugSession, IExceptionInfo, IExpression, IStackFrame, State } from 'vs/workbench/contrib/debug/common/debug';
import { Expression } from 'vs/workbench/contrib/debug/common/debugModel';
import { IHostService } from 'vs/workbench/services/host/browser/host';

const MAX_NUM_INLINE_VALUES = 100; // JS Global scope can have 700+ entries. We want to limit ourselves for perf reasons
const MAX_INLINE_DECORATOR_LENGTH = 150; // Max string length of each inline decorator when debugging. If exceeded ... is added
Expand Down Expand Up @@ -209,33 +209,6 @@ function getWordToLineNumbersMap(model: ITextModel | null): Map<string, number[]
return result;
}

export class LazyDebugEditorContribution extends Disposable implements IDebugEditorContribution {
private _contrib: IDebugEditorContribution | undefined;

constructor(editor: ICodeEditor, @IInstantiationService instantiationService: IInstantiationService) {
super();

const listener = editor.onDidChangeModel(() => {
if (editor.hasModel()) {
listener.dispose();
this._contrib = this._register(instantiationService.createInstance(DebugEditorContribution, editor));
}
});
}

showHover(position: Position, focus: boolean): Promise<void> {
return this._contrib ? this._contrib.showHover(position, focus) : Promise.resolve();
}

addLaunchConfiguration(): Promise<any> {
return this._contrib ? this._contrib.addLaunchConfiguration() : Promise.resolve();
}

closeExceptionWidget(): void {
this._contrib?.closeExceptionWidget();
}
}

export class DebugEditorContribution implements IDebugEditorContribution {

private toDispose: IDisposable[];
Expand Down

0 comments on commit 92df25d

Please sign in to comment.