diff --git a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts index a99f1bec5a1e3..40526614fff97 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointEditorContribution.ts @@ -12,10 +12,10 @@ import { IAction, Action, SubmenuAction, Separator } from 'vs/base/common/action import { Range } from 'vs/editor/common/core/range'; import { ICodeEditor, IEditorMouseEvent, MouseTargetType, IContentWidget, IActiveCodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; import { IModelDecorationOptions, TrackedRangeStickiness, ITextModel, OverviewRulerLane, IModelDecorationOverviewRulerOptions } from 'vs/editor/common/model'; -import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; +import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation'; import { IContextKeyService, IContextKey } from 'vs/platform/contextkey/common/contextkey'; import { IContextMenuService } from 'vs/platform/contextview/browser/contextView'; -import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession } from 'vs/workbench/contrib/debug/common/debug'; +import { IDebugService, IBreakpoint, CONTEXT_BREAKPOINT_WIDGET_VISIBLE, BreakpointWidgetContext, IBreakpointEditorContribution, IBreakpointUpdateData, IDebugConfiguration, State, IDebugSession, DebuggerUiMessage } from 'vs/workbench/contrib/debug/common/debug'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { BreakpointWidget } from 'vs/workbench/contrib/debug/browser/breakpointWidget'; import { IDisposable, dispose } from 'vs/base/common/lifecycle'; @@ -36,6 +36,8 @@ import { ILabelService } from 'vs/platform/label/common/label'; import * as icons from 'vs/workbench/contrib/debug/browser/debugIcons'; import { onUnexpectedError } from 'vs/base/common/errors'; import { noBreakWhitespace } from 'vs/base/common/strings'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { withNullAsUndefined } from 'vs/base/common/types'; const $ = dom.$; @@ -52,7 +54,7 @@ const breakpointHelperDecoration: IModelDecorationOptions = { stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges }; -export function createBreakpointDecorations(model: ITextModel, breakpoints: ReadonlyArray, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): { range: Range; options: IModelDecorationOptions }[] { +export function createBreakpointDecorations(accessor: ServicesAccessor, model: ITextModel, breakpoints: ReadonlyArray, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): { range: Range; options: IModelDecorationOptions }[] { const result: { range: Range; options: IModelDecorationOptions }[] = []; breakpoints.forEach((breakpoint) => { if (breakpoint.lineNumber > model.getLineCount()) { @@ -65,7 +67,7 @@ export function createBreakpointDecorations(model: ITextModel, breakpoints: Read ); result.push({ - options: getBreakpointDecorationOptions(model, breakpoint, state, breakpointsActivated, showBreakpointsInOverviewRuler), + options: getBreakpointDecorationOptions(accessor, model, breakpoint, state, breakpointsActivated, showBreakpointsInOverviewRuler), range }); }); @@ -73,17 +75,47 @@ export function createBreakpointDecorations(model: ITextModel, breakpoints: Read return result; } -function getBreakpointDecorationOptions(model: ITextModel, breakpoint: IBreakpoint, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): IModelDecorationOptions { - const { icon, message } = getBreakpointMessageAndIcon(state, breakpointsActivated, breakpoint, undefined); +function getBreakpointDecorationOptions(accessor: ServicesAccessor, model: ITextModel, breakpoint: IBreakpoint, state: State, breakpointsActivated: boolean, showBreakpointsInOverviewRuler: boolean): IModelDecorationOptions { + const debugService = accessor.get(IDebugService); + const languageService = accessor.get(ILanguageService); + const { icon, message, showAdapterUnverifiedMessage } = getBreakpointMessageAndIcon(state, breakpointsActivated, breakpoint, undefined); let glyphMarginHoverMessage: MarkdownString | undefined; + let unverifiedMessage: string | undefined; + if (showAdapterUnverifiedMessage) { + let langId: string | undefined; + unverifiedMessage = debugService.getModel().getSessions().map(s => { + const dbg = debugService.getAdapterManager().getDebugger(s.configuration.type); + const message = dbg?.uiMessages?.[DebuggerUiMessage.UnverifiedBreakpoints]; + if (message) { + if (!langId) { + // Lazily compute this, only if needed for some debug adapter + langId = withNullAsUndefined(languageService.guessLanguageIdByFilepathOrFirstLine(breakpoint.uri)); + } + return langId && dbg.interestedInLanguage(langId) ? message : undefined; + } + + return undefined; + }) + .find(messages => !!messages); + } + if (message) { + glyphMarginHoverMessage = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }); if (breakpoint.condition || breakpoint.hitCondition) { const languageId = model.getLanguageId(); - glyphMarginHoverMessage = new MarkdownString().appendCodeblock(languageId, message); + glyphMarginHoverMessage.appendCodeblock(languageId, message); + if (unverifiedMessage) { + glyphMarginHoverMessage.appendMarkdown('$(warning) ' + unverifiedMessage); + } } else { - glyphMarginHoverMessage = new MarkdownString().appendText(message); + glyphMarginHoverMessage.appendText(message); + if (unverifiedMessage) { + glyphMarginHoverMessage.appendMarkdown('\n\n$(warning) ' + unverifiedMessage); + } } + } else if (unverifiedMessage) { + glyphMarginHoverMessage = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }).appendMarkdown(unverifiedMessage); } let overviewRulerDecoration: IModelDecorationOverviewRulerOptions | null = null; @@ -469,7 +501,7 @@ export class BreakpointEditorContribution implements IBreakpointEditorContributi const model = activeCodeEditor.getModel(); const breakpoints = this.debugService.getModel().getBreakpoints({ uri: model.uri }); const debugSettings = this.configurationService.getValue('debug'); - const desiredBreakpointDecorations = createBreakpointDecorations(model, breakpoints, this.debugService.state, this.debugService.getModel().areBreakpointsActivated(), debugSettings.showBreakpointsInOverviewRuler); + const desiredBreakpointDecorations = this.instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, model, breakpoints, this.debugService.state, this.debugService.getModel().areBreakpointsActivated(), debugSettings.showBreakpointsInOverviewRuler)); try { this.ignoreDecorationsChangedEvent = true; diff --git a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts index 1b14740bef4df..2e020ea8fa625 100644 --- a/src/vs/workbench/contrib/debug/browser/breakpointsView.ts +++ b/src/vs/workbench/contrib/debug/browser/breakpointsView.ts @@ -23,6 +23,7 @@ import * as resources from 'vs/base/common/resources'; import { Constants } from 'vs/base/common/uint'; import { isCodeEditor } from 'vs/editor/browser/editorBrowser'; import { ServicesAccessor } from 'vs/editor/browser/editorExtensions'; +import { ILanguageService } from 'vs/editor/common/languages/language'; import { localize } from 'vs/nls'; import { createAndFillInActionBarActions, createAndFillInContextMenuActions } from 'vs/platform/actions/browser/menuEntryActionViewItem'; import { Action2, IMenu, IMenuService, MenuId, registerAction2 } from 'vs/platform/actions/common/actions'; @@ -106,6 +107,7 @@ export class BreakpointsView extends ViewPane { @ILabelService private readonly labelService: ILabelService, @IMenuService menuService: IMenuService, @IHoverService private readonly hoverService: IHoverService, + @ILanguageService private readonly languageService: ILanguageService, ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService); @@ -285,12 +287,19 @@ export class BreakpointsView extends ViewPane { return; } - const hasSomeUnverified = this.debugService.getModel().getBreakpoints().some(bp => !bp.verified); - const currentType = this.debugService.getViewModel().focusedSession?.configuration.type; - const message = currentType && this.debugService.getAdapterManager().getDebuggerUiMessages(currentType)[DebuggerUiMessage.UnverifiedBreakpoints]; + const dbg = currentType ? this.debugService.getAdapterManager().getDebugger(currentType) : undefined; + const message = dbg?.uiMessages && dbg.uiMessages[DebuggerUiMessage.UnverifiedBreakpoints]; + const debuggerHasUnverifiedBps = message && this.debugService.getModel().getBreakpoints().filter(bp => { + if (bp.verified) { + return false; + } + + const langId = this.languageService.guessLanguageIdByFilepathOrFirstLine(bp.uri); + return langId && dbg.interestedInLanguage(langId); + }); - if (message && hasSomeUnverified) { + if (message && debuggerHasUnverifiedBps?.length) { if (delayed) { const mdown = new MarkdownString(undefined, { isTrusted: true }).appendMarkdown(message); this.hintContainer.setLabel('$(warning)', undefined, { title: { markdown: mdown, markdownNotSupportedFallback: message } }); @@ -1075,7 +1084,7 @@ export function openBreakpointSource(breakpoint: IBreakpoint, sideBySide: boolea }, sideBySide ? SIDE_GROUP : ACTIVE_GROUP); } -export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: boolean, breakpoint: BreakpointItem, labelService?: ILabelService): { message?: string; icon: ThemeIcon } { +export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: boolean, breakpoint: BreakpointItem, labelService?: ILabelService): { message?: string; icon: ThemeIcon; showAdapterUnverifiedMessage?: boolean } { const debugActive = state === State.Running || state === State.Stopped; const breakpointIcon = breakpoint instanceof DataBreakpoint ? icons.dataBreakpoint : breakpoint instanceof FunctionBreakpoint ? icons.functionBreakpoint : breakpoint.logMessage ? icons.logBreakpoint : icons.breakpoint; @@ -1094,6 +1103,7 @@ export function getBreakpointMessageAndIcon(state: State, breakpointsActivated: return { icon: breakpointIcon.unverified, message: ('message' in breakpoint && breakpoint.message) ? breakpoint.message : (breakpoint.logMessage ? localize('unverifiedLogpoint', "Unverified Logpoint") : localize('unverifiedBreakpoint', "Unverified Breakpoint")), + showAdapterUnverifiedMessage: true }; } diff --git a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts index 8ec920693454a..c4fbab00e3a66 100644 --- a/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts +++ b/src/vs/workbench/contrib/debug/browser/debugAdapterManager.ts @@ -23,7 +23,7 @@ import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput'; import { Registry } from 'vs/platform/registry/common/platform'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; import { Breakpoints } from 'vs/workbench/contrib/debug/common/breakpoints'; -import { CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_EXTENSION_AVAILABLE, DebuggerUiMessage, IAdapterDescriptor, IAdapterManager, IConfig, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugAdapterFactory, IDebugConfiguration, IDebugSession, INTERNAL_CONSOLE_OPTIONS_SCHEMA } from 'vs/workbench/contrib/debug/common/debug'; +import { CONTEXT_DEBUGGERS_AVAILABLE, CONTEXT_DEBUG_EXTENSION_AVAILABLE, IAdapterDescriptor, IAdapterManager, IConfig, IDebugAdapter, IDebugAdapterDescriptorFactory, IDebugAdapterFactory, IDebugConfiguration, IDebugSession, INTERNAL_CONSOLE_OPTIONS_SCHEMA } from 'vs/workbench/contrib/debug/common/debug'; import { Debugger } from 'vs/workbench/contrib/debug/common/debugger'; import { breakpointsExtPoint, debuggersExtPoint, launchSchema, presentationSchema } from 'vs/workbench/contrib/debug/common/debugSchemas'; import { TaskDefinitionRegistry } from 'vs/workbench/contrib/tasks/common/taskDefinitionRegistry'; @@ -273,15 +273,6 @@ export class AdapterManager extends Disposable implements IAdapterManager { return undefined; } - getDebuggerUiMessages(type: string): { [key in DebuggerUiMessage]?: string } { - const dbgr = this.getDebugger(type); - if (dbgr) { - return dbgr.uiMessages || {}; - } - - return {}; - } - get onDidRegisterDebugger(): Event { return this._onDidRegisterDebugger.event; } @@ -312,10 +303,10 @@ export class AdapterManager extends Disposable implements IAdapterManager { return adapter && adapter.enabled ? adapter : undefined; } - isDebuggerInterestedInLanguage(language: string): boolean { + someDebuggerInterestedInLanguage(languageId: string): boolean { return !!this.debuggers .filter(d => d.enabled) - .find(a => language && a.languages && a.languages.indexOf(language) >= 0); + .find(a => a.interestedInLanguage(languageId)); } async guessDebugger(gettingConfigurations: boolean): Promise { @@ -331,7 +322,7 @@ export class AdapterManager extends Disposable implements IAdapterManager { } const adapters = this.debuggers .filter(a => a.enabled) - .filter(a => language && a.languages && a.languages.indexOf(language) >= 0); + .filter(a => language && a.interestedInLanguage(language)); if (adapters.length === 1) { return adapters[0]; } diff --git a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts index cc58a507c364b..682133ef7bd3e 100644 --- a/src/vs/workbench/contrib/debug/browser/disassemblyView.ts +++ b/src/vs/workbench/contrib/debug/browser/disassemblyView.ts @@ -800,10 +800,10 @@ export class DisassemblyViewContribution implements IWorkbenchContribution { const language = activeTextEditorControl.getModel()?.getLanguageId(); // TODO: instead of using idDebuggerInterestedInLanguage, have a specific ext point for languages // support disassembly - this._languageSupportsDisassemleRequest?.set(!!language && debugService.getAdapterManager().isDebuggerInterestedInLanguage(language)); + this._languageSupportsDisassemleRequest?.set(!!language && debugService.getAdapterManager().someDebuggerInterestedInLanguage(language)); this._onDidChangeModelLanguage = activeTextEditorControl.onDidChangeModelLanguage(e => { - this._languageSupportsDisassemleRequest?.set(debugService.getAdapterManager().isDebuggerInterestedInLanguage(e.newLanguage)); + this._languageSupportsDisassemleRequest?.set(debugService.getAdapterManager().someDebuggerInterestedInLanguage(e.newLanguage)); }); } else { this._languageSupportsDisassemleRequest?.set(false); diff --git a/src/vs/workbench/contrib/debug/browser/welcomeView.ts b/src/vs/workbench/contrib/debug/browser/welcomeView.ts index c936f453d3243..28ca270995d92 100644 --- a/src/vs/workbench/contrib/debug/browser/welcomeView.ts +++ b/src/vs/workbench/contrib/debug/browser/welcomeView.ts @@ -65,7 +65,7 @@ export class WelcomeView extends ViewPane { if (isCodeEditor(editorControl)) { const model = editorControl.getModel(); const language = model ? model.getLanguageId() : undefined; - if (language && this.debugService.getAdapterManager().isDebuggerInterestedInLanguage(language)) { + if (language && this.debugService.getAdapterManager().someDebuggerInterestedInLanguage(language)) { this.debugStartLanguageContext.set(language); this.debuggerInterestedContext.set(true); storageSevice.store(debugStartLanguageKey, language, StorageScope.WORKSPACE, StorageTarget.MACHINE); diff --git a/src/vs/workbench/contrib/debug/common/debug.ts b/src/vs/workbench/contrib/debug/common/debug.ts index 74160cd516640..0fcf306db351d 100644 --- a/src/vs/workbench/contrib/debug/common/debug.ts +++ b/src/vs/workbench/contrib/debug/common/debug.ts @@ -159,6 +159,13 @@ export interface IDebugger { getCustomTelemetryEndpoint(): ITelemetryEndpoint | undefined; } +export interface IDebuggerMetadata { + label: string; + type: string; + uiMessages?: { [key in DebuggerUiMessage]: string }; + interestedInLanguage(languageId: string): boolean; +} + export const enum State { Inactive, Initializing, @@ -859,8 +866,8 @@ export interface IAdapterManager { hasEnabledDebuggers(): boolean; getDebugAdapterDescriptor(session: IDebugSession): Promise; getDebuggerLabel(type: string): string | undefined; - isDebuggerInterestedInLanguage(language: string): boolean; - getDebuggerUiMessages(type: string): { [key in DebuggerUiMessage]?: string }; + someDebuggerInterestedInLanguage(language: string): boolean; + getDebugger(type: string): IDebuggerMetadata | undefined; activateDebuggers(activationEvent: string, debugType?: string): Promise; registerDebugAdapterFactory(debugTypes: string[], debugAdapterFactory: IDebugAdapterFactory): IDisposable; diff --git a/src/vs/workbench/contrib/debug/common/debugger.ts b/src/vs/workbench/contrib/debug/common/debugger.ts index 6345e41bf8d98..072c6795e3377 100644 --- a/src/vs/workbench/contrib/debug/common/debugger.ts +++ b/src/vs/workbench/contrib/debug/common/debugger.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { isObject } from 'vs/base/common/types'; import { IJSONSchema, IJSONSchemaMap, IJSONSchemaSnippet } from 'vs/base/common/jsonSchema'; import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace'; -import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage } from 'vs/workbench/contrib/debug/common/debug'; +import { IConfig, IDebuggerContribution, IDebugAdapter, IDebugger, IDebugSession, IAdapterManager, IDebugService, debuggerDisabledMessage, IDebuggerMetadata } from 'vs/workbench/contrib/debug/common/debug'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { IConfigurationResolverService } from 'vs/workbench/services/configurationResolver/common/configurationResolver'; import * as ConfigurationResolverUtils from 'vs/workbench/services/configurationResolver/common/configurationResolverUtils'; @@ -21,7 +21,7 @@ import { cleanRemoteAuthority } from 'vs/platform/telemetry/common/telemetryUtil import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ContextKeyExpr, ContextKeyExpression, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; -export class Debugger implements IDebugger { +export class Debugger implements IDebugger, IDebuggerMetadata { private debuggerContribution: IDebuggerContribution; private mergedExtensionDescriptions: IExtensionDescription[] = []; @@ -151,6 +151,10 @@ export class Debugger implements IDebugger { return this.debuggerContribution.uiMessages; } + interestedInLanguage(languageId: string): boolean { + return !!(this.languages && this.languages.indexOf(languageId) >= 0); + } + hasInitialConfiguration(): boolean { return !!this.debuggerContribution.initialConfigurations; } diff --git a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts index e8d88ddaf01b3..8dd479109ddcb 100644 --- a/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts +++ b/src/vs/workbench/contrib/debug/test/browser/breakpoints.test.ts @@ -7,15 +7,18 @@ import * as assert from 'assert'; import { URI as uri } from 'vs/base/common/uri'; import { DebugModel, Breakpoint } from 'vs/workbench/contrib/debug/common/debugModel'; import { getExpandedBodySize, getBreakpointMessageAndIcon } from 'vs/workbench/contrib/debug/browser/breakpointsView'; -import { dispose } from 'vs/base/common/lifecycle'; +import { DisposableStore, dispose } from 'vs/base/common/lifecycle'; import { Range } from 'vs/editor/common/core/range'; -import { IBreakpointData, IBreakpointUpdateData, State } from 'vs/workbench/contrib/debug/common/debug'; +import { IBreakpointData, IBreakpointUpdateData, IDebugService, State } from 'vs/workbench/contrib/debug/common/debug'; import { createBreakpointDecorations } from 'vs/workbench/contrib/debug/browser/breakpointEditorContribution'; import { OverviewRulerLane } from 'vs/editor/common/model'; import { MarkdownString } from 'vs/base/common/htmlContent'; import { createTextModel } from 'vs/editor/test/common/testTextModel'; import { createMockSession } from 'vs/workbench/contrib/debug/test/browser/callStack.test'; -import { createMockDebugModel } from 'vs/workbench/contrib/debug/test/browser/mockDebug'; +import { createMockDebugModel, MockDebugService } from 'vs/workbench/contrib/debug/test/browser/mockDebug'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; +import { ILanguageService } from 'vs/editor/common/languages/language'; +import { LanguageService } from 'vs/editor/common/services/languageService'; function addBreakpointsAndCheckEvents(model: DebugModel, uri: uri, data: IBreakpointData[]): void { let eventCount = 0; @@ -39,11 +42,16 @@ function addBreakpointsAndCheckEvents(model: DebugModel, uri: uri, data: IBreakp suite('Debug - Breakpoints', () => { let model: DebugModel; + const disposables = new DisposableStore(); setup(() => { model = createMockDebugModel(); }); + teardown(() => { + disposables.clear(); + }); + // Breakpoints test('simple', () => { @@ -350,7 +358,10 @@ suite('Debug - Breakpoints', () => { ]); const breakpoints = model.getBreakpoints(); - let decorations = createBreakpointDecorations(textModel, breakpoints, State.Running, true, true); + const instantiationService = new TestInstantiationService(); + instantiationService.stub(IDebugService, new MockDebugService()); + instantiationService.stub(ILanguageService, disposables.add(new LanguageService())); + let decorations = instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, textModel, breakpoints, State.Running, true, true)); assert.strictEqual(decorations.length, 3); // last breakpoint filtered out since it has a large line number assert.deepStrictEqual(decorations[0].range, new Range(1, 1, 1, 2)); assert.deepStrictEqual(decorations[1].range, new Range(2, 4, 2, 5)); @@ -358,10 +369,10 @@ suite('Debug - Breakpoints', () => { assert.strictEqual(decorations[0].options.beforeContentClassName, undefined); assert.strictEqual(decorations[1].options.before?.inlineClassName, `debug-breakpoint-placeholder`); assert.strictEqual(decorations[0].options.overviewRuler?.position, OverviewRulerLane.Left); - const expected = new MarkdownString().appendCodeblock(languageId, 'Expression condition: x > 5'); + const expected = new MarkdownString(undefined, { isTrusted: true, supportThemeIcons: true }).appendCodeblock(languageId, 'Expression condition: x > 5'); assert.deepStrictEqual(decorations[0].options.glyphMarginHoverMessage, expected); - decorations = createBreakpointDecorations(textModel, breakpoints, State.Running, true, false); + decorations = instantiationService.invokeFunction(accessor => createBreakpointDecorations(accessor, textModel, breakpoints, State.Running, true, false)); assert.strictEqual(decorations[0].options.overviewRuler, null); textModel.dispose();