From 92df25dd8c42fdc5bbc44115f597c60a3daf41c0 Mon Sep 17 00:00:00 2001 From: Rob Lourens Date: Fri, 30 Dec 2022 01:05:16 -0600 Subject: [PATCH] Make debug editor contributions lazy (#170270) Fix #166969 --- .../browser/breakpointEditorContribution.ts | 30 +----- .../browser/callStackEditorContribution.ts | 16 +--- .../debug/browser/debug.contribution.ts | 14 +-- .../debug/browser/debugEditorContribution.ts | 95 +++++++------------ 4 files changed, 44 insertions(+), 111 deletions(-) diff --git a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts index e1eb88b7dfedc..1c06c65952f53 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts @@ -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'; @@ -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; diff --git a/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts index 79cc37f580f02..b7d9b5b0e8d13 100644 --- a/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/callStackEditorContribution.ts @@ -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'; @@ -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( diff --git a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts index 30173c4b03e31..1bd9cafd3be04 100644 --- a/src/vs/workbench/contrib/debug/browser/debug.contribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debug.contribution.ts @@ -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'; @@ -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'; @@ -90,9 +90,9 @@ Registry.as(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, { diff --git a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts index 90976464bb3cd..1a68770af7465 100644 --- a/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/debugEditorContribution.ts @@ -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 @@ -209,33 +209,6 @@ function getWordToLineNumbersMap(model: ITextModel | null): Map { - if (editor.hasModel()) { - listener.dispose(); - this._contrib = this._register(instantiationService.createInstance(DebugEditorContribution, editor)); - } - }); - } - - showHover(position: Position, focus: boolean): Promise { - return this._contrib ? this._contrib.showHover(position, focus) : Promise.resolve(); - } - - addLaunchConfiguration(): Promise { - return this._contrib ? this._contrib.addLaunchConfiguration() : Promise.resolve(); - } - - closeExceptionWidget(): void { - this._contrib?.closeExceptionWidget(); - } -} - export class DebugEditorContribution implements IDebugEditorContribution { private toDispose: IDisposable[];