@codingame/monaco-vscode-debug-service-override 4.1.0 → 4.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/debug.js +4 -4
- package/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
- package/external/tslib/tslib.es6.js +11 -0
- package/override/vs/platform/dialogs/common/dialogs.js +10 -0
- package/package.json +2 -2
- package/vscode/src/vs/platform/debug/common/extensionHostDebugIpc.js +73 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/callStackView.js +1026 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debug.contribution.js +1004 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugANSIHandling.js +347 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugActionViewItems.js +337 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugAdapterManager.js +432 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugCommands.js +1039 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugConfigurationManager.js +649 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugConsoleQuickAccess.js +64 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugEditorActions.js +636 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugEditorContribution.js +740 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugHover.js +408 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugMemory.js +206 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugProgress.js +80 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugQuickAccess.js +169 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugService.js +1271 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugSession.js +1330 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugSessionPicker.js +115 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugStatus.js +77 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugTaskRunner.js +307 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugTitle.js +31 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugToolBar.js +387 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/debugViewlet.js +267 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/disassemblyView.js +817 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/exceptionWidget.js +131 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/extensionHostDebugService.js +142 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/linkDetector.js +262 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/loadedScriptsView.js +669 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/debug.contribution.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/debugHover.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/debugToolBar.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/debugViewlet.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/exceptionWidget.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/media/repl.css.js +6 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/rawDebugSession.js +709 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/repl.js +1002 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/replFilter.js +48 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/replViewer.js +352 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/statusbarColorProvider.js +129 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/variablesView.js +734 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/watchExpressionsView.js +501 -0
- package/vscode/src/vs/workbench/contrib/debug/browser/welcomeView.js +162 -0
- package/vscode/src/vs/workbench/contrib/debug/common/breakpoints.js +21 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugCompoundRoot.js +17 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugContentProvider.js +110 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugLifecycle.js +62 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugSchemas.js +460 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugStorage.js +166 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugTelemetry.js +36 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugViewModel.js +150 -0
- package/vscode/src/vs/workbench/contrib/debug/common/debugger.js +289 -0
- package/vscode/src/vs/workbench/contrib/debug/common/loadedScriptsPicker.js +87 -0
- package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/notebookVariables/notebookVariableCommands.js +64 -0
- package/vscode/src/vs/workbench/services/configurationResolver/browser/baseConfigurationResolverService.js +311 -0
- package/vscode/src/vs/workbench/services/configurationResolver/browser/configurationResolverService.js +29 -0
|
@@ -0,0 +1,1271 @@
|
|
|
1
|
+
import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
|
|
2
|
+
import { alert, status } from 'vscode/vscode/vs/base/browser/ui/aria/aria';
|
|
3
|
+
import { Action } from 'vscode/vscode/vs/base/common/actions';
|
|
4
|
+
import { distinct } from 'vscode/vscode/vs/base/common/arrays';
|
|
5
|
+
import { RunOnceScheduler, raceTimeout } from 'vscode/vscode/vs/base/common/async';
|
|
6
|
+
import { CancellationTokenSource } from 'vscode/vscode/vs/base/common/cancellation';
|
|
7
|
+
import { isErrorWithActions } from 'vscode/vscode/vs/base/common/errorMessage';
|
|
8
|
+
import { isCancellationError } from 'vscode/vscode/vs/base/common/errors';
|
|
9
|
+
import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
|
|
10
|
+
import { DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
|
|
11
|
+
import { deepClone, equals } from 'vscode/vscode/vs/base/common/objects';
|
|
12
|
+
import Severity$1 from 'vscode/vscode/vs/base/common/severity';
|
|
13
|
+
import { URI } from 'vscode/vscode/vs/base/common/uri';
|
|
14
|
+
import { generateUuid } from 'vscode/vscode/vs/base/common/uuid';
|
|
15
|
+
import { isCodeEditor } from 'vscode/vscode/vs/editor/browser/editorBrowser';
|
|
16
|
+
import { localizeWithPath } from 'vscode/vscode/vs/nls';
|
|
17
|
+
import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands';
|
|
18
|
+
import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
|
|
19
|
+
import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
|
|
20
|
+
import { IExtensionHostDebugService } from 'vscode/vscode/vs/platform/debug/common/extensionHostDebug';
|
|
21
|
+
import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
|
|
22
|
+
import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
|
|
23
|
+
import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
|
|
24
|
+
import { INotificationService } from 'vscode/vscode/vs/platform/notification/common/notification';
|
|
25
|
+
import { IQuickInputService } from 'vscode/vscode/vs/platform/quickinput/common/quickInput';
|
|
26
|
+
import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
|
|
27
|
+
import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace';
|
|
28
|
+
import { IWorkspaceTrustRequestService } from 'vscode/vscode/vs/platform/workspace/common/workspaceTrust';
|
|
29
|
+
import { IViewDescriptorService } from 'vscode/vscode/vs/workbench/common/views';
|
|
30
|
+
import { AdapterManager } from './debugAdapterManager.js';
|
|
31
|
+
import { DEBUG_CONFIGURE_COMMAND_ID, DEBUG_CONFIGURE_LABEL } from './debugCommands.js';
|
|
32
|
+
import { ConfigurationManager } from './debugConfigurationManager.js';
|
|
33
|
+
import { DebugMemoryFileSystemProvider } from './debugMemory.js';
|
|
34
|
+
import { DebugSession } from './debugSession.js';
|
|
35
|
+
import { DebugTaskRunner } from './debugTaskRunner.js';
|
|
36
|
+
import { CALLSTACK_VIEW_ID, DEBUG_MEMORY_SCHEME, CONTEXT_DEBUG_TYPE, CONTEXT_DEBUG_STATE, CONTEXT_HAS_DEBUGGED, CONTEXT_IN_DEBUG_MODE, CONTEXT_DEBUG_UX, CONTEXT_BREAKPOINTS_EXIST, CONTEXT_DISASSEMBLY_VIEW_FOCUS, getStateLabel, debuggerDisabledMessage, VIEWLET_ID, REPL_VIEW_ID, DEBUG_SCHEME } from 'vscode/vscode/vs/workbench/contrib/debug/common/debug';
|
|
37
|
+
import { DebugCompoundRoot } from '../common/debugCompoundRoot.js';
|
|
38
|
+
import { DebugModel, Breakpoint, FunctionBreakpoint, DataBreakpoint, InstructionBreakpoint } from 'vscode/vscode/vs/workbench/contrib/debug/common/debugModel';
|
|
39
|
+
import { Source } from 'vscode/vscode/vs/workbench/contrib/debug/common/debugSource';
|
|
40
|
+
import { DebugStorage } from '../common/debugStorage.js';
|
|
41
|
+
import { DebugTelemetry } from '../common/debugTelemetry.js';
|
|
42
|
+
import { saveAllBeforeDebugStart, getExtensionHostDebugSession } from 'vscode/vscode/vs/workbench/contrib/debug/common/debugUtils';
|
|
43
|
+
import { ViewModel } from '../common/debugViewModel.js';
|
|
44
|
+
import { DisassemblyViewInput } from 'vscode/vscode/vs/workbench/contrib/debug/common/disassemblyViewInput';
|
|
45
|
+
import { VIEWLET_ID as VIEWLET_ID$1 } from 'vscode/vscode/vs/workbench/contrib/files/common/files';
|
|
46
|
+
import { NumberBadge, IActivityService } from 'vscode/vscode/vs/workbench/services/activity/common/activity';
|
|
47
|
+
import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
|
|
48
|
+
import { IExtensionService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensions';
|
|
49
|
+
import { IWorkbenchLayoutService } from 'vscode/vscode/vs/workbench/services/layout/browser/layoutService';
|
|
50
|
+
import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
|
|
51
|
+
import { IPaneCompositePartService } from 'vscode/vscode/vs/workbench/services/panecomposite/browser/panecomposite';
|
|
52
|
+
import { IViewsService } from 'vscode/vscode/vs/workbench/services/views/common/viewsService';
|
|
53
|
+
import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
|
|
54
|
+
|
|
55
|
+
let DebugService = class DebugService {
|
|
56
|
+
constructor(editorService, paneCompositeService, viewsService, viewDescriptorService, notificationService, dialogService, layoutService, contextService, contextKeyService, lifecycleService, instantiationService, extensionService, fileService, configurationService, extensionHostDebugService, activityService, commandService, quickInputService, workspaceTrustRequestService, uriIdentityService) {
|
|
57
|
+
this.editorService = editorService;
|
|
58
|
+
this.paneCompositeService = paneCompositeService;
|
|
59
|
+
this.viewsService = viewsService;
|
|
60
|
+
this.viewDescriptorService = viewDescriptorService;
|
|
61
|
+
this.notificationService = notificationService;
|
|
62
|
+
this.dialogService = dialogService;
|
|
63
|
+
this.layoutService = layoutService;
|
|
64
|
+
this.contextService = contextService;
|
|
65
|
+
this.contextKeyService = contextKeyService;
|
|
66
|
+
this.lifecycleService = lifecycleService;
|
|
67
|
+
this.instantiationService = instantiationService;
|
|
68
|
+
this.extensionService = extensionService;
|
|
69
|
+
this.fileService = fileService;
|
|
70
|
+
this.configurationService = configurationService;
|
|
71
|
+
this.extensionHostDebugService = extensionHostDebugService;
|
|
72
|
+
this.activityService = activityService;
|
|
73
|
+
this.commandService = commandService;
|
|
74
|
+
this.quickInputService = quickInputService;
|
|
75
|
+
this.workspaceTrustRequestService = workspaceTrustRequestService;
|
|
76
|
+
this.uriIdentityService = uriIdentityService;
|
|
77
|
+
this.restartingSessions = ( new Set());
|
|
78
|
+
this.disposables = ( new DisposableStore());
|
|
79
|
+
this.initializing = false;
|
|
80
|
+
this.sessionCancellationTokens = ( new Map());
|
|
81
|
+
this.haveDoneLazySetup = false;
|
|
82
|
+
this.breakpointsToSendOnResourceSaved = ( new Set());
|
|
83
|
+
this._onDidChangeState = ( new Emitter());
|
|
84
|
+
this._onDidNewSession = ( new Emitter());
|
|
85
|
+
this._onWillNewSession = ( new Emitter());
|
|
86
|
+
this._onDidEndSession = ( new Emitter());
|
|
87
|
+
this.adapterManager = this.instantiationService.createInstance(AdapterManager, { onDidNewSession: this.onDidNewSession });
|
|
88
|
+
this.disposables.add(this.adapterManager);
|
|
89
|
+
this.configurationManager = this.instantiationService.createInstance(ConfigurationManager, this.adapterManager);
|
|
90
|
+
this.disposables.add(this.configurationManager);
|
|
91
|
+
this.debugStorage = this.disposables.add(this.instantiationService.createInstance(DebugStorage));
|
|
92
|
+
this.chosenEnvironments = this.debugStorage.loadChosenEnvironments();
|
|
93
|
+
this.model = this.instantiationService.createInstance(DebugModel, this.debugStorage);
|
|
94
|
+
this.telemetry = this.instantiationService.createInstance(DebugTelemetry, this.model);
|
|
95
|
+
this.viewModel = ( new ViewModel(contextKeyService));
|
|
96
|
+
this.taskRunner = this.instantiationService.createInstance(DebugTaskRunner);
|
|
97
|
+
this.disposables.add(this.fileService.onDidFilesChange(e => this.onFileChanges(e)));
|
|
98
|
+
this.disposables.add(this.lifecycleService.onWillShutdown(this.dispose, this));
|
|
99
|
+
this.disposables.add(this.extensionHostDebugService.onAttachSession(event => {
|
|
100
|
+
const session = this.model.getSession(event.sessionId, true);
|
|
101
|
+
if (session) {
|
|
102
|
+
session.configuration.request = 'attach';
|
|
103
|
+
session.configuration.port = event.port;
|
|
104
|
+
session.setSubId(event.subId);
|
|
105
|
+
this.launchOrAttachToSession(session);
|
|
106
|
+
}
|
|
107
|
+
}));
|
|
108
|
+
this.disposables.add(this.extensionHostDebugService.onTerminateSession(event => {
|
|
109
|
+
const session = this.model.getSession(event.sessionId);
|
|
110
|
+
if (session && session.subId === event.subId) {
|
|
111
|
+
session.disconnect();
|
|
112
|
+
}
|
|
113
|
+
}));
|
|
114
|
+
this.disposables.add(this.viewModel.onDidFocusStackFrame(() => {
|
|
115
|
+
this.onStateChange();
|
|
116
|
+
}));
|
|
117
|
+
this.disposables.add(this.viewModel.onDidFocusSession((session) => {
|
|
118
|
+
this.onStateChange();
|
|
119
|
+
if (session) {
|
|
120
|
+
this.setExceptionBreakpointFallbackSession(session.getId());
|
|
121
|
+
}
|
|
122
|
+
}));
|
|
123
|
+
this.disposables.add(Event.any(this.adapterManager.onDidRegisterDebugger, this.configurationManager.onDidSelectConfiguration)(() => {
|
|
124
|
+
const debugUxValue = (this.state !== 0 || (this.configurationManager.getAllConfigurations().length > 0 && this.adapterManager.hasEnabledDebuggers())) ? 'default' : 'simple';
|
|
125
|
+
this.debugUx.set(debugUxValue);
|
|
126
|
+
this.debugStorage.storeDebugUxState(debugUxValue);
|
|
127
|
+
}));
|
|
128
|
+
this.disposables.add(this.model.onDidChangeCallStack(() => {
|
|
129
|
+
const numberOfSessions = this.model.getSessions().filter(s => !s.parentSession).length;
|
|
130
|
+
this.activity?.dispose();
|
|
131
|
+
if (numberOfSessions > 0) {
|
|
132
|
+
const viewContainer = this.viewDescriptorService.getViewContainerByViewId(CALLSTACK_VIEW_ID);
|
|
133
|
+
if (viewContainer) {
|
|
134
|
+
this.activity = this.activityService.showViewContainerActivity(viewContainer.id, { badge: ( new NumberBadge(numberOfSessions, n => n === 1 ? ( localizeWithPath(
|
|
135
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
136
|
+
'1activeSession',
|
|
137
|
+
"1 active session"
|
|
138
|
+
)) : ( localizeWithPath(
|
|
139
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
140
|
+
'nActiveSessions',
|
|
141
|
+
"{0} active sessions",
|
|
142
|
+
n
|
|
143
|
+
)))) });
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}));
|
|
147
|
+
this.disposables.add(editorService.onDidActiveEditorChange(() => {
|
|
148
|
+
this.contextKeyService.bufferChangeEvents(() => {
|
|
149
|
+
if (editorService.activeEditor === DisassemblyViewInput.instance) {
|
|
150
|
+
this.disassemblyViewFocus.set(true);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
this.disassemblyViewFocus?.reset();
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
}));
|
|
157
|
+
this.disposables.add(this.lifecycleService.onBeforeShutdown(() => {
|
|
158
|
+
for (const editor of editorService.editors) {
|
|
159
|
+
if (editor.resource?.scheme === DEBUG_MEMORY_SCHEME) {
|
|
160
|
+
editor.dispose();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}));
|
|
164
|
+
this.initContextKeys(contextKeyService);
|
|
165
|
+
}
|
|
166
|
+
initContextKeys(contextKeyService) {
|
|
167
|
+
queueMicrotask(() => {
|
|
168
|
+
contextKeyService.bufferChangeEvents(() => {
|
|
169
|
+
this.debugType = CONTEXT_DEBUG_TYPE.bindTo(contextKeyService);
|
|
170
|
+
this.debugState = CONTEXT_DEBUG_STATE.bindTo(contextKeyService);
|
|
171
|
+
this.hasDebugged = CONTEXT_HAS_DEBUGGED.bindTo(contextKeyService);
|
|
172
|
+
this.inDebugMode = CONTEXT_IN_DEBUG_MODE.bindTo(contextKeyService);
|
|
173
|
+
this.debugUx = CONTEXT_DEBUG_UX.bindTo(contextKeyService);
|
|
174
|
+
this.debugUx.set(this.debugStorage.loadDebugUxState());
|
|
175
|
+
this.breakpointsExist = CONTEXT_BREAKPOINTS_EXIST.bindTo(contextKeyService);
|
|
176
|
+
this.disassemblyViewFocus = CONTEXT_DISASSEMBLY_VIEW_FOCUS.bindTo(contextKeyService);
|
|
177
|
+
});
|
|
178
|
+
const setBreakpointsExistContext = () => this.breakpointsExist.set(!!(this.model.getBreakpoints().length || this.model.getDataBreakpoints().length || this.model.getFunctionBreakpoints().length));
|
|
179
|
+
setBreakpointsExistContext();
|
|
180
|
+
this.disposables.add(this.model.onDidChangeBreakpoints(() => setBreakpointsExistContext()));
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
getModel() {
|
|
184
|
+
return this.model;
|
|
185
|
+
}
|
|
186
|
+
getViewModel() {
|
|
187
|
+
return this.viewModel;
|
|
188
|
+
}
|
|
189
|
+
getConfigurationManager() {
|
|
190
|
+
return this.configurationManager;
|
|
191
|
+
}
|
|
192
|
+
getAdapterManager() {
|
|
193
|
+
return this.adapterManager;
|
|
194
|
+
}
|
|
195
|
+
sourceIsNotAvailable(uri) {
|
|
196
|
+
this.model.sourceIsNotAvailable(uri);
|
|
197
|
+
}
|
|
198
|
+
dispose() {
|
|
199
|
+
this.disposables.dispose();
|
|
200
|
+
}
|
|
201
|
+
get state() {
|
|
202
|
+
const focusedSession = this.viewModel.focusedSession;
|
|
203
|
+
if (focusedSession) {
|
|
204
|
+
return focusedSession.state;
|
|
205
|
+
}
|
|
206
|
+
return this.initializing ? 1 : 0 ;
|
|
207
|
+
}
|
|
208
|
+
get initializingOptions() {
|
|
209
|
+
return this._initializingOptions;
|
|
210
|
+
}
|
|
211
|
+
startInitializingState(options) {
|
|
212
|
+
if (!this.initializing) {
|
|
213
|
+
this.initializing = true;
|
|
214
|
+
this._initializingOptions = options;
|
|
215
|
+
this.onStateChange();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
endInitializingState() {
|
|
219
|
+
if (this.initializing) {
|
|
220
|
+
this.initializing = false;
|
|
221
|
+
this._initializingOptions = undefined;
|
|
222
|
+
this.onStateChange();
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
cancelTokens(id) {
|
|
226
|
+
if (id) {
|
|
227
|
+
const token = this.sessionCancellationTokens.get(id);
|
|
228
|
+
if (token) {
|
|
229
|
+
token.cancel();
|
|
230
|
+
this.sessionCancellationTokens.delete(id);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
this.sessionCancellationTokens.forEach(t => t.cancel());
|
|
235
|
+
this.sessionCancellationTokens.clear();
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
onStateChange() {
|
|
239
|
+
const state = this.state;
|
|
240
|
+
if (this.previousState !== state) {
|
|
241
|
+
this.contextKeyService.bufferChangeEvents(() => {
|
|
242
|
+
this.debugState.set(getStateLabel(state));
|
|
243
|
+
this.inDebugMode.set(state !== 0 );
|
|
244
|
+
const debugUxValue = (((state !== 0 && state !== 1) ) || (this.adapterManager.hasEnabledDebuggers() && this.configurationManager.selectedConfiguration.name)) ? 'default' : 'simple';
|
|
245
|
+
this.debugUx.set(debugUxValue);
|
|
246
|
+
this.debugStorage.storeDebugUxState(debugUxValue);
|
|
247
|
+
});
|
|
248
|
+
this.previousState = state;
|
|
249
|
+
this._onDidChangeState.fire(state);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
get onDidChangeState() {
|
|
253
|
+
return this._onDidChangeState.event;
|
|
254
|
+
}
|
|
255
|
+
get onDidNewSession() {
|
|
256
|
+
return this._onDidNewSession.event;
|
|
257
|
+
}
|
|
258
|
+
get onWillNewSession() {
|
|
259
|
+
return this._onWillNewSession.event;
|
|
260
|
+
}
|
|
261
|
+
get onDidEndSession() {
|
|
262
|
+
return this._onDidEndSession.event;
|
|
263
|
+
}
|
|
264
|
+
lazySetup() {
|
|
265
|
+
if (!this.haveDoneLazySetup) {
|
|
266
|
+
this.disposables.add(this.fileService.registerProvider(DEBUG_MEMORY_SCHEME, ( new DebugMemoryFileSystemProvider(this))));
|
|
267
|
+
this.haveDoneLazySetup = true;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
async startDebugging(launch, configOrName, options, saveBeforeStart = !options?.parentSession) {
|
|
271
|
+
const message = options && options.noDebug ? ( localizeWithPath(
|
|
272
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
273
|
+
'runTrust',
|
|
274
|
+
"Running executes build tasks and program code from your workspace."
|
|
275
|
+
)) : ( localizeWithPath(
|
|
276
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
277
|
+
'debugTrust',
|
|
278
|
+
"Debugging executes build tasks and program code from your workspace."
|
|
279
|
+
));
|
|
280
|
+
const trust = await this.workspaceTrustRequestService.requestWorkspaceTrust({ message });
|
|
281
|
+
if (!trust) {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
this.lazySetup();
|
|
285
|
+
this.startInitializingState(options);
|
|
286
|
+
this.hasDebugged.set(true);
|
|
287
|
+
try {
|
|
288
|
+
await this.extensionService.activateByEvent('onDebug');
|
|
289
|
+
if (saveBeforeStart) {
|
|
290
|
+
await saveAllBeforeDebugStart(this.configurationService, this.editorService);
|
|
291
|
+
}
|
|
292
|
+
await this.extensionService.whenInstalledExtensionsRegistered();
|
|
293
|
+
let config;
|
|
294
|
+
let compound;
|
|
295
|
+
if (!configOrName) {
|
|
296
|
+
configOrName = this.configurationManager.selectedConfiguration.name;
|
|
297
|
+
}
|
|
298
|
+
if (typeof configOrName === 'string' && launch) {
|
|
299
|
+
config = launch.getConfiguration(configOrName);
|
|
300
|
+
compound = launch.getCompound(configOrName);
|
|
301
|
+
}
|
|
302
|
+
else if (typeof configOrName !== 'string') {
|
|
303
|
+
config = configOrName;
|
|
304
|
+
}
|
|
305
|
+
if (compound) {
|
|
306
|
+
if (!compound.configurations) {
|
|
307
|
+
throw new Error(localizeWithPath('vs/workbench/contrib/debug/browser/debugService', { key: 'compoundMustHaveConfigurations', comment: ['compound indicates a "compounds" configuration item', '"configurations" is an attribute and should not be localized'] }, "Compound must have \"configurations\" attribute set in order to start multiple configurations."));
|
|
308
|
+
}
|
|
309
|
+
if (compound.preLaunchTask) {
|
|
310
|
+
const taskResult = await this.taskRunner.runTaskAndCheckErrors(launch?.workspace || this.contextService.getWorkspace(), compound.preLaunchTask);
|
|
311
|
+
if (taskResult === 0 ) {
|
|
312
|
+
this.endInitializingState();
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
if (compound.stopAll) {
|
|
317
|
+
options = { ...options, compoundRoot: ( new DebugCompoundRoot()) };
|
|
318
|
+
}
|
|
319
|
+
const values = await Promise.all(( compound.configurations.map(configData => {
|
|
320
|
+
const name = typeof configData === 'string' ? configData : configData.name;
|
|
321
|
+
if (name === compound.name) {
|
|
322
|
+
return Promise.resolve(false);
|
|
323
|
+
}
|
|
324
|
+
let launchForName;
|
|
325
|
+
if (typeof configData === 'string') {
|
|
326
|
+
const launchesContainingName = this.configurationManager.getLaunches().filter(l => !!l.getConfiguration(name));
|
|
327
|
+
if (launchesContainingName.length === 1) {
|
|
328
|
+
launchForName = launchesContainingName[0];
|
|
329
|
+
}
|
|
330
|
+
else if (launch && launchesContainingName.length > 1 && launchesContainingName.indexOf(launch) >= 0) {
|
|
331
|
+
launchForName = launch;
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
throw new Error(launchesContainingName.length === 0 ? localizeWithPath('vs/workbench/contrib/debug/browser/debugService', 'noConfigurationNameInWorkspace', "Could not find launch configuration '{0}' in the workspace.", name)
|
|
335
|
+
: localizeWithPath('vs/workbench/contrib/debug/browser/debugService', 'multipleConfigurationNamesInWorkspace', "There are multiple launch configurations '{0}' in the workspace. Use folder name to qualify the configuration.", name));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else if (configData.folder) {
|
|
339
|
+
const launchesMatchingConfigData = this.configurationManager.getLaunches().filter(l => l.workspace && l.workspace.name === configData.folder && !!l.getConfiguration(configData.name));
|
|
340
|
+
if (launchesMatchingConfigData.length === 1) {
|
|
341
|
+
launchForName = launchesMatchingConfigData[0];
|
|
342
|
+
}
|
|
343
|
+
else {
|
|
344
|
+
throw new Error(localizeWithPath('vs/workbench/contrib/debug/browser/debugService', 'noFolderWithName', "Can not find folder with name '{0}' for configuration '{1}' in compound '{2}'.", configData.folder, configData.name, compound.name));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return this.createSession(launchForName, launchForName.getConfiguration(name), options);
|
|
348
|
+
})));
|
|
349
|
+
const result = values.every(success => !!success);
|
|
350
|
+
this.endInitializingState();
|
|
351
|
+
return result;
|
|
352
|
+
}
|
|
353
|
+
if (configOrName && !config) {
|
|
354
|
+
const message = !!launch ? ( localizeWithPath(
|
|
355
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
356
|
+
'configMissing',
|
|
357
|
+
"Configuration '{0}' is missing in 'launch.json'.",
|
|
358
|
+
typeof configOrName === 'string' ? configOrName : configOrName.name
|
|
359
|
+
)) :
|
|
360
|
+
( localizeWithPath(
|
|
361
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
362
|
+
'launchJsonDoesNotExist',
|
|
363
|
+
"'launch.json' does not exist for passed workspace folder."
|
|
364
|
+
));
|
|
365
|
+
throw new Error(message);
|
|
366
|
+
}
|
|
367
|
+
const result = await this.createSession(launch, config, options);
|
|
368
|
+
this.endInitializingState();
|
|
369
|
+
return result;
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
this.notificationService.error(err);
|
|
373
|
+
this.endInitializingState();
|
|
374
|
+
return Promise.reject(err);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
async createSession(launch, config, options) {
|
|
378
|
+
let type;
|
|
379
|
+
if (config) {
|
|
380
|
+
type = config.type;
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
config = Object.create(null);
|
|
384
|
+
}
|
|
385
|
+
if (options && options.noDebug) {
|
|
386
|
+
config.noDebug = true;
|
|
387
|
+
}
|
|
388
|
+
else if (options && typeof options.noDebug === 'undefined' && options.parentSession && options.parentSession.configuration.noDebug) {
|
|
389
|
+
config.noDebug = true;
|
|
390
|
+
}
|
|
391
|
+
const unresolvedConfig = deepClone(config);
|
|
392
|
+
let guess;
|
|
393
|
+
let activeEditor;
|
|
394
|
+
if (!type) {
|
|
395
|
+
activeEditor = this.editorService.activeEditor;
|
|
396
|
+
if (activeEditor && activeEditor.resource) {
|
|
397
|
+
type = this.chosenEnvironments[( activeEditor.resource.toString())];
|
|
398
|
+
}
|
|
399
|
+
if (!type) {
|
|
400
|
+
guess = await this.adapterManager.guessDebugger(false);
|
|
401
|
+
if (guess) {
|
|
402
|
+
type = guess.type;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
const initCancellationToken = ( new CancellationTokenSource());
|
|
407
|
+
const sessionId = generateUuid();
|
|
408
|
+
this.sessionCancellationTokens.set(sessionId, initCancellationToken);
|
|
409
|
+
const configByProviders = await this.configurationManager.resolveConfigurationByProviders(launch && launch.workspace ? launch.workspace.uri : undefined, type, config, initCancellationToken.token);
|
|
410
|
+
if (configByProviders && configByProviders.type) {
|
|
411
|
+
try {
|
|
412
|
+
let resolvedConfig = await this.substituteVariables(launch, configByProviders);
|
|
413
|
+
if (!resolvedConfig) {
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
if (initCancellationToken.token.isCancellationRequested) {
|
|
417
|
+
return false;
|
|
418
|
+
}
|
|
419
|
+
const workspace = launch?.workspace || this.contextService.getWorkspace();
|
|
420
|
+
const taskResult = await this.taskRunner.runTaskAndCheckErrors(workspace, resolvedConfig.preLaunchTask);
|
|
421
|
+
if (taskResult === 0 ) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
const cfg = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, resolvedConfig.type, resolvedConfig, initCancellationToken.token);
|
|
425
|
+
if (!cfg) {
|
|
426
|
+
if (launch && type && cfg === null && !initCancellationToken.token.isCancellationRequested) {
|
|
427
|
+
await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token);
|
|
428
|
+
}
|
|
429
|
+
return false;
|
|
430
|
+
}
|
|
431
|
+
resolvedConfig = cfg;
|
|
432
|
+
const dbg = this.adapterManager.getDebugger(resolvedConfig.type);
|
|
433
|
+
if (!dbg || (configByProviders.request !== 'attach' && configByProviders.request !== 'launch')) {
|
|
434
|
+
let message;
|
|
435
|
+
if (configByProviders.request !== 'attach' && configByProviders.request !== 'launch') {
|
|
436
|
+
message = configByProviders.request ? ( localizeWithPath(
|
|
437
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
438
|
+
'debugRequestNotSupported',
|
|
439
|
+
"Attribute '{0}' has an unsupported value '{1}' in the chosen debug configuration.",
|
|
440
|
+
'request',
|
|
441
|
+
configByProviders.request
|
|
442
|
+
))
|
|
443
|
+
: ( localizeWithPath(
|
|
444
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
445
|
+
'debugRequesMissing',
|
|
446
|
+
"Attribute '{0}' is missing from the chosen debug configuration.",
|
|
447
|
+
'request'
|
|
448
|
+
));
|
|
449
|
+
}
|
|
450
|
+
else {
|
|
451
|
+
message = resolvedConfig.type ? ( localizeWithPath(
|
|
452
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
453
|
+
'debugTypeNotSupported',
|
|
454
|
+
"Configured debug type '{0}' is not supported.",
|
|
455
|
+
resolvedConfig.type
|
|
456
|
+
)) :
|
|
457
|
+
( localizeWithPath(
|
|
458
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
459
|
+
'debugTypeMissing',
|
|
460
|
+
"Missing property 'type' for the chosen launch configuration."
|
|
461
|
+
));
|
|
462
|
+
}
|
|
463
|
+
const actionList = [];
|
|
464
|
+
actionList.push(( new Action('installAdditionalDebuggers', ( localizeWithPath(
|
|
465
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
466
|
+
{ key: 'installAdditionalDebuggers', comment: ['Placeholder is the debug type, so for example "node", "python"'] },
|
|
467
|
+
"Install {0} Extension",
|
|
468
|
+
resolvedConfig.type
|
|
469
|
+
)), undefined, true, async () => this.commandService.executeCommand('debug.installAdditionalDebuggers', resolvedConfig?.type))));
|
|
470
|
+
await this.showError(message, actionList);
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
if (!dbg.enabled) {
|
|
474
|
+
await this.showError(debuggerDisabledMessage(dbg.type), []);
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
const result = await this.doCreateSession(sessionId, launch?.workspace, { resolved: resolvedConfig, unresolved: unresolvedConfig }, options);
|
|
478
|
+
if (result && guess && activeEditor && activeEditor.resource) {
|
|
479
|
+
this.chosenEnvironments[( activeEditor.resource.toString())] = guess.type;
|
|
480
|
+
this.debugStorage.storeChosenEnvironments(this.chosenEnvironments);
|
|
481
|
+
}
|
|
482
|
+
return result;
|
|
483
|
+
}
|
|
484
|
+
catch (err) {
|
|
485
|
+
if (err && err.message) {
|
|
486
|
+
await this.showError(err.message);
|
|
487
|
+
}
|
|
488
|
+
else if (this.contextService.getWorkbenchState() === 1 ) {
|
|
489
|
+
await this.showError(( localizeWithPath(
|
|
490
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
491
|
+
'noFolderWorkspaceDebugError',
|
|
492
|
+
"The active file can not be debugged. Make sure it is saved and that you have a debug extension installed for that file type."
|
|
493
|
+
)));
|
|
494
|
+
}
|
|
495
|
+
if (launch && !initCancellationToken.token.isCancellationRequested) {
|
|
496
|
+
await launch.openConfigFile({ preserveFocus: true }, initCancellationToken.token);
|
|
497
|
+
}
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
if (launch && type && configByProviders === null && !initCancellationToken.token.isCancellationRequested) {
|
|
502
|
+
await launch.openConfigFile({ preserveFocus: true, type }, initCancellationToken.token);
|
|
503
|
+
}
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
async doCreateSession(sessionId, root, configuration, options) {
|
|
507
|
+
const session = this.instantiationService.createInstance(DebugSession, sessionId, configuration, root, this.model, options);
|
|
508
|
+
if (options?.startedByUser && ( this.model.getSessions().some(s => s.getLabel() === session.getLabel())) && configuration.resolved.suppressMultipleSessionWarning !== true) {
|
|
509
|
+
const result = await this.dialogService.confirm({ message: ( localizeWithPath(
|
|
510
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
511
|
+
'multipleSession',
|
|
512
|
+
"'{0}' is already running. Do you want to start another instance?",
|
|
513
|
+
session.getLabel()
|
|
514
|
+
)) });
|
|
515
|
+
if (!result.confirmed) {
|
|
516
|
+
return false;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
this.model.addSession(session);
|
|
520
|
+
this.registerSessionListeners(session);
|
|
521
|
+
this._onWillNewSession.fire(session);
|
|
522
|
+
const openDebug = this.configurationService.getValue('debug').openDebug;
|
|
523
|
+
if (!configuration.resolved.noDebug && (openDebug === 'openOnSessionStart' || (openDebug !== 'neverOpen' && this.viewModel.firstSessionStart)) && !session.suppressDebugView) {
|
|
524
|
+
await this.paneCompositeService.openPaneComposite(VIEWLET_ID, 0 );
|
|
525
|
+
}
|
|
526
|
+
try {
|
|
527
|
+
await this.launchOrAttachToSession(session);
|
|
528
|
+
const internalConsoleOptions = session.configuration.internalConsoleOptions || this.configurationService.getValue('debug').internalConsoleOptions;
|
|
529
|
+
if (internalConsoleOptions === 'openOnSessionStart' || (this.viewModel.firstSessionStart && internalConsoleOptions === 'openOnFirstSessionStart')) {
|
|
530
|
+
this.viewsService.openView(REPL_VIEW_ID, false);
|
|
531
|
+
}
|
|
532
|
+
this.viewModel.firstSessionStart = false;
|
|
533
|
+
const showSubSessions = this.configurationService.getValue('debug').showSubSessionsInToolBar;
|
|
534
|
+
const sessions = this.model.getSessions();
|
|
535
|
+
const shownSessions = showSubSessions ? sessions : sessions.filter(s => !s.parentSession);
|
|
536
|
+
if (shownSessions.length > 1) {
|
|
537
|
+
this.viewModel.setMultiSessionView(true);
|
|
538
|
+
}
|
|
539
|
+
this._onDidNewSession.fire(session);
|
|
540
|
+
return true;
|
|
541
|
+
}
|
|
542
|
+
catch (error) {
|
|
543
|
+
if (isCancellationError(error)) {
|
|
544
|
+
return false;
|
|
545
|
+
}
|
|
546
|
+
if (session && session.getReplElements().length > 0) {
|
|
547
|
+
this.viewsService.openView(REPL_VIEW_ID, false);
|
|
548
|
+
}
|
|
549
|
+
if (session.configuration && session.configuration.request === 'attach' && session.configuration.__autoAttach) {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
const errorMessage = error instanceof Error ? error.message : error;
|
|
553
|
+
if (error.showUser !== false) {
|
|
554
|
+
await this.showError(errorMessage, isErrorWithActions(error) ? error.actions : []);
|
|
555
|
+
}
|
|
556
|
+
return false;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
async launchOrAttachToSession(session, forceFocus = false) {
|
|
560
|
+
const dbgr = this.adapterManager.getDebugger(session.configuration.type);
|
|
561
|
+
try {
|
|
562
|
+
await session.initialize(dbgr);
|
|
563
|
+
await session.launchOrAttach(session.configuration);
|
|
564
|
+
const launchJsonExists = !!session.root && !!this.configurationService.getValue('launch', { resource: session.root.uri });
|
|
565
|
+
await this.telemetry.logDebugSessionStart(dbgr, launchJsonExists);
|
|
566
|
+
if (forceFocus || !this.viewModel.focusedSession || (session.parentSession === this.viewModel.focusedSession && session.compact)) {
|
|
567
|
+
await this.focusStackFrame(undefined, undefined, session);
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
catch (err) {
|
|
571
|
+
if (this.viewModel.focusedSession === session) {
|
|
572
|
+
await this.focusStackFrame(undefined);
|
|
573
|
+
}
|
|
574
|
+
return Promise.reject(err);
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
registerSessionListeners(session) {
|
|
578
|
+
const listenerDisposables = ( new DisposableStore());
|
|
579
|
+
this.disposables.add(listenerDisposables);
|
|
580
|
+
const sessionRunningScheduler = listenerDisposables.add(( new RunOnceScheduler(() => {
|
|
581
|
+
if (session.state === 3 && this.viewModel.focusedSession === session) {
|
|
582
|
+
this.viewModel.setFocus(undefined, this.viewModel.focusedThread, session, false);
|
|
583
|
+
}
|
|
584
|
+
}, 200)));
|
|
585
|
+
listenerDisposables.add(session.onDidChangeState(() => {
|
|
586
|
+
if (session.state === 3 && this.viewModel.focusedSession === session) {
|
|
587
|
+
sessionRunningScheduler.schedule();
|
|
588
|
+
}
|
|
589
|
+
if (session === this.viewModel.focusedSession) {
|
|
590
|
+
this.onStateChange();
|
|
591
|
+
}
|
|
592
|
+
}));
|
|
593
|
+
listenerDisposables.add(this.onDidEndSession(e => {
|
|
594
|
+
if (e.session === session && !e.restart) {
|
|
595
|
+
this.disposables.delete(listenerDisposables);
|
|
596
|
+
}
|
|
597
|
+
}));
|
|
598
|
+
listenerDisposables.add(session.onDidEndAdapter(async (adapterExitEvent) => {
|
|
599
|
+
if (adapterExitEvent) {
|
|
600
|
+
if (adapterExitEvent.error) {
|
|
601
|
+
this.notificationService.error(( localizeWithPath(
|
|
602
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
603
|
+
'debugAdapterCrash',
|
|
604
|
+
"Debug adapter process has terminated unexpectedly ({0})",
|
|
605
|
+
adapterExitEvent.error.message || ( adapterExitEvent.error.toString())
|
|
606
|
+
)));
|
|
607
|
+
}
|
|
608
|
+
this.telemetry.logDebugSessionStop(session, adapterExitEvent);
|
|
609
|
+
}
|
|
610
|
+
const extensionDebugSession = getExtensionHostDebugSession(session);
|
|
611
|
+
if (extensionDebugSession && extensionDebugSession.state === 3 && extensionDebugSession.configuration.noDebug) {
|
|
612
|
+
this.extensionHostDebugService.close(extensionDebugSession.getId());
|
|
613
|
+
}
|
|
614
|
+
if (session.configuration.postDebugTask) {
|
|
615
|
+
const root = session.root ?? this.contextService.getWorkspace();
|
|
616
|
+
try {
|
|
617
|
+
await this.taskRunner.runTask(root, session.configuration.postDebugTask);
|
|
618
|
+
}
|
|
619
|
+
catch (err) {
|
|
620
|
+
this.notificationService.error(err);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
this.endInitializingState();
|
|
624
|
+
this.cancelTokens(session.getId());
|
|
625
|
+
if (this.configurationService.getValue('debug').closeReadonlyTabsOnEnd) {
|
|
626
|
+
const editorsToClose = this.editorService.getEditors(1 ).filter(({ editor }) => {
|
|
627
|
+
return editor.resource?.scheme === DEBUG_SCHEME && session.getId() === Source.getEncodedDebugData(editor.resource).sessionId;
|
|
628
|
+
});
|
|
629
|
+
this.editorService.closeEditors(editorsToClose);
|
|
630
|
+
}
|
|
631
|
+
this._onDidEndSession.fire({ session, restart: ( this.restartingSessions.has(session)) });
|
|
632
|
+
const focusedSession = this.viewModel.focusedSession;
|
|
633
|
+
if (focusedSession && focusedSession.getId() === session.getId()) {
|
|
634
|
+
const { session, thread, stackFrame } = getStackFrameThreadAndSessionToFocus(this.model, undefined, undefined, undefined, focusedSession);
|
|
635
|
+
this.viewModel.setFocus(stackFrame, thread, session, false);
|
|
636
|
+
}
|
|
637
|
+
if (this.model.getSessions().length === 0) {
|
|
638
|
+
this.viewModel.setMultiSessionView(false);
|
|
639
|
+
if (this.layoutService.isVisible("workbench.parts.sidebar" ) && this.configurationService.getValue('debug').openExplorerOnEnd) {
|
|
640
|
+
this.paneCompositeService.openPaneComposite(VIEWLET_ID$1, 0 );
|
|
641
|
+
}
|
|
642
|
+
const dataBreakpoints = this.model.getDataBreakpoints().filter(dbp => !dbp.canPersist);
|
|
643
|
+
dataBreakpoints.forEach(dbp => this.model.removeDataBreakpoints(dbp.getId()));
|
|
644
|
+
if (this.configurationService.getValue('debug').console.closeOnEnd) {
|
|
645
|
+
const debugConsoleContainer = this.viewDescriptorService.getViewContainerByViewId(REPL_VIEW_ID);
|
|
646
|
+
if (debugConsoleContainer && this.viewsService.isViewContainerVisible(debugConsoleContainer.id)) {
|
|
647
|
+
this.viewsService.closeViewContainer(debugConsoleContainer.id);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
this.model.removeExceptionBreakpointsForSession(session.getId());
|
|
652
|
+
}));
|
|
653
|
+
}
|
|
654
|
+
async restartSession(session, restartData) {
|
|
655
|
+
if (session.saveBeforeRestart) {
|
|
656
|
+
await saveAllBeforeDebugStart(this.configurationService, this.editorService);
|
|
657
|
+
}
|
|
658
|
+
const isAutoRestart = !!restartData;
|
|
659
|
+
const runTasks = async () => {
|
|
660
|
+
if (isAutoRestart) {
|
|
661
|
+
return Promise.resolve(1 );
|
|
662
|
+
}
|
|
663
|
+
const root = session.root || this.contextService.getWorkspace();
|
|
664
|
+
await this.taskRunner.runTask(root, session.configuration.preRestartTask);
|
|
665
|
+
await this.taskRunner.runTask(root, session.configuration.postDebugTask);
|
|
666
|
+
const taskResult1 = await this.taskRunner.runTaskAndCheckErrors(root, session.configuration.preLaunchTask);
|
|
667
|
+
if (taskResult1 !== 1 ) {
|
|
668
|
+
return taskResult1;
|
|
669
|
+
}
|
|
670
|
+
return this.taskRunner.runTaskAndCheckErrors(root, session.configuration.postRestartTask);
|
|
671
|
+
};
|
|
672
|
+
const extensionDebugSession = getExtensionHostDebugSession(session);
|
|
673
|
+
if (extensionDebugSession) {
|
|
674
|
+
const taskResult = await runTasks();
|
|
675
|
+
if (taskResult === 1 ) {
|
|
676
|
+
this.extensionHostDebugService.reload(extensionDebugSession.getId());
|
|
677
|
+
}
|
|
678
|
+
return;
|
|
679
|
+
}
|
|
680
|
+
let needsToSubstitute = false;
|
|
681
|
+
let unresolved;
|
|
682
|
+
const launch = session.root ? this.configurationManager.getLaunch(session.root.uri) : undefined;
|
|
683
|
+
if (launch) {
|
|
684
|
+
unresolved = launch.getConfiguration(session.configuration.name);
|
|
685
|
+
if (unresolved && !equals(unresolved, session.unresolvedConfiguration)) {
|
|
686
|
+
unresolved.type = session.configuration.type;
|
|
687
|
+
unresolved.noDebug = session.configuration.noDebug;
|
|
688
|
+
needsToSubstitute = true;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
let resolved = session.configuration;
|
|
692
|
+
if (launch && needsToSubstitute && unresolved) {
|
|
693
|
+
const initCancellationToken = ( new CancellationTokenSource());
|
|
694
|
+
this.sessionCancellationTokens.set(session.getId(), initCancellationToken);
|
|
695
|
+
const resolvedByProviders = await this.configurationManager.resolveConfigurationByProviders(launch.workspace ? launch.workspace.uri : undefined, unresolved.type, unresolved, initCancellationToken.token);
|
|
696
|
+
if (resolvedByProviders) {
|
|
697
|
+
resolved = await this.substituteVariables(launch, resolvedByProviders);
|
|
698
|
+
if (resolved && !initCancellationToken.token.isCancellationRequested) {
|
|
699
|
+
resolved = await this.configurationManager.resolveDebugConfigurationWithSubstitutedVariables(launch && launch.workspace ? launch.workspace.uri : undefined, unresolved.type, resolved, initCancellationToken.token);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
else {
|
|
703
|
+
resolved = resolvedByProviders;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
if (resolved) {
|
|
707
|
+
session.setConfiguration({ resolved, unresolved });
|
|
708
|
+
}
|
|
709
|
+
session.configuration.__restart = restartData;
|
|
710
|
+
const doRestart = async (fn) => {
|
|
711
|
+
this.restartingSessions.add(session);
|
|
712
|
+
let didRestart = false;
|
|
713
|
+
try {
|
|
714
|
+
didRestart = (await fn()) !== false;
|
|
715
|
+
}
|
|
716
|
+
catch (e) {
|
|
717
|
+
didRestart = false;
|
|
718
|
+
throw e;
|
|
719
|
+
}
|
|
720
|
+
finally {
|
|
721
|
+
this.restartingSessions.delete(session);
|
|
722
|
+
if (!didRestart) {
|
|
723
|
+
this._onDidEndSession.fire({ session, restart: false });
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
if (session.capabilities.supportsRestartRequest) {
|
|
728
|
+
const taskResult = await runTasks();
|
|
729
|
+
if (taskResult === 1 ) {
|
|
730
|
+
await doRestart(async () => {
|
|
731
|
+
await session.restart();
|
|
732
|
+
return true;
|
|
733
|
+
});
|
|
734
|
+
}
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const shouldFocus = !!this.viewModel.focusedSession && session.getId() === this.viewModel.focusedSession.getId();
|
|
738
|
+
return doRestart(async () => {
|
|
739
|
+
if (isAutoRestart) {
|
|
740
|
+
await session.disconnect(true);
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
743
|
+
await session.terminate(true);
|
|
744
|
+
}
|
|
745
|
+
return ( new Promise((c, e) => {
|
|
746
|
+
setTimeout(async () => {
|
|
747
|
+
const taskResult = await runTasks();
|
|
748
|
+
if (taskResult !== 1 ) {
|
|
749
|
+
return c(false);
|
|
750
|
+
}
|
|
751
|
+
if (!resolved) {
|
|
752
|
+
return c(false);
|
|
753
|
+
}
|
|
754
|
+
try {
|
|
755
|
+
await this.launchOrAttachToSession(session, shouldFocus);
|
|
756
|
+
this._onDidNewSession.fire(session);
|
|
757
|
+
c(true);
|
|
758
|
+
}
|
|
759
|
+
catch (error) {
|
|
760
|
+
e(error);
|
|
761
|
+
}
|
|
762
|
+
}, 300);
|
|
763
|
+
}));
|
|
764
|
+
});
|
|
765
|
+
}
|
|
766
|
+
async stopSession(session, disconnect = false, suspend = false) {
|
|
767
|
+
if (session) {
|
|
768
|
+
return disconnect ? session.disconnect(undefined, suspend) : session.terminate();
|
|
769
|
+
}
|
|
770
|
+
const sessions = this.model.getSessions();
|
|
771
|
+
if (sessions.length === 0) {
|
|
772
|
+
this.taskRunner.cancel();
|
|
773
|
+
await this.quickInputService.cancel();
|
|
774
|
+
this.endInitializingState();
|
|
775
|
+
this.cancelTokens(undefined);
|
|
776
|
+
}
|
|
777
|
+
return Promise.all(( sessions.map(s => disconnect ? s.disconnect(undefined, suspend) : s.terminate())));
|
|
778
|
+
}
|
|
779
|
+
async substituteVariables(launch, config) {
|
|
780
|
+
const dbg = this.adapterManager.getDebugger(config.type);
|
|
781
|
+
if (dbg) {
|
|
782
|
+
let folder = undefined;
|
|
783
|
+
if (launch && launch.workspace) {
|
|
784
|
+
folder = launch.workspace;
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
const folders = this.contextService.getWorkspace().folders;
|
|
788
|
+
if (folders.length === 1) {
|
|
789
|
+
folder = folders[0];
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
try {
|
|
793
|
+
return await dbg.substituteVariables(folder, config);
|
|
794
|
+
}
|
|
795
|
+
catch (err) {
|
|
796
|
+
this.showError(err.message, undefined, !!launch?.getConfiguration(config.name));
|
|
797
|
+
return undefined;
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
return Promise.resolve(config);
|
|
801
|
+
}
|
|
802
|
+
async showError(message, errorActions = [], promptLaunchJson = true) {
|
|
803
|
+
const configureAction = ( new Action(
|
|
804
|
+
DEBUG_CONFIGURE_COMMAND_ID,
|
|
805
|
+
DEBUG_CONFIGURE_LABEL,
|
|
806
|
+
undefined,
|
|
807
|
+
true,
|
|
808
|
+
() => this.commandService.executeCommand(DEBUG_CONFIGURE_COMMAND_ID)
|
|
809
|
+
));
|
|
810
|
+
const actions = errorActions.filter((action) => action.id.endsWith('.command')).length > 0 ?
|
|
811
|
+
errorActions :
|
|
812
|
+
[...errorActions, ...(promptLaunchJson ? [configureAction] : [])];
|
|
813
|
+
await this.dialogService.prompt({
|
|
814
|
+
type: Severity$1.Error,
|
|
815
|
+
message,
|
|
816
|
+
buttons: ( actions.map(action => ({
|
|
817
|
+
label: action.label,
|
|
818
|
+
run: () => action.run()
|
|
819
|
+
}))),
|
|
820
|
+
cancelButton: true
|
|
821
|
+
});
|
|
822
|
+
}
|
|
823
|
+
async focusStackFrame(_stackFrame, _thread, _session, options) {
|
|
824
|
+
const { stackFrame, thread, session } = getStackFrameThreadAndSessionToFocus(this.model, _stackFrame, _thread, _session);
|
|
825
|
+
if (stackFrame) {
|
|
826
|
+
const editor = await stackFrame.openInEditor(this.editorService, options?.preserveFocus ?? true, options?.sideBySide, options?.pinned);
|
|
827
|
+
if (editor) {
|
|
828
|
+
if (editor.input === DisassemblyViewInput.instance) ;
|
|
829
|
+
else {
|
|
830
|
+
const control = editor.getControl();
|
|
831
|
+
if (stackFrame && isCodeEditor(control) && control.hasModel()) {
|
|
832
|
+
const model = control.getModel();
|
|
833
|
+
const lineNumber = stackFrame.range.startLineNumber;
|
|
834
|
+
if (lineNumber >= 1 && lineNumber <= model.getLineCount()) {
|
|
835
|
+
const lineContent = control.getModel().getLineContent(lineNumber);
|
|
836
|
+
alert(( localizeWithPath(
|
|
837
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
838
|
+
{ key: 'debuggingPaused', comment: ['First placeholder is the file line content, second placeholder is the reason why debugging is stopped, for example "breakpoint", third is the stack frame name, and last is the line number.'] },
|
|
839
|
+
"{0}, debugging paused {1}, {2}:{3}",
|
|
840
|
+
lineContent,
|
|
841
|
+
thread && thread.stoppedDetails ? `, reason ${thread.stoppedDetails.reason}` : '',
|
|
842
|
+
stackFrame.source ? stackFrame.source.name : '',
|
|
843
|
+
stackFrame.range.startLineNumber
|
|
844
|
+
)));
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
if (session) {
|
|
851
|
+
this.debugType.set(session.configuration.type);
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
this.debugType.reset();
|
|
855
|
+
}
|
|
856
|
+
this.viewModel.setFocus(stackFrame, thread, session, !!options?.explicit);
|
|
857
|
+
}
|
|
858
|
+
addWatchExpression(name) {
|
|
859
|
+
const we = this.model.addWatchExpression(name);
|
|
860
|
+
if (!name) {
|
|
861
|
+
this.viewModel.setSelectedExpression(we, false);
|
|
862
|
+
}
|
|
863
|
+
this.debugStorage.storeWatchExpressions(this.model.getWatchExpressions());
|
|
864
|
+
}
|
|
865
|
+
renameWatchExpression(id, newName) {
|
|
866
|
+
this.model.renameWatchExpression(id, newName);
|
|
867
|
+
this.debugStorage.storeWatchExpressions(this.model.getWatchExpressions());
|
|
868
|
+
}
|
|
869
|
+
moveWatchExpression(id, position) {
|
|
870
|
+
this.model.moveWatchExpression(id, position);
|
|
871
|
+
this.debugStorage.storeWatchExpressions(this.model.getWatchExpressions());
|
|
872
|
+
}
|
|
873
|
+
removeWatchExpressions(id) {
|
|
874
|
+
this.model.removeWatchExpressions(id);
|
|
875
|
+
this.debugStorage.storeWatchExpressions(this.model.getWatchExpressions());
|
|
876
|
+
}
|
|
877
|
+
canSetBreakpointsIn(model) {
|
|
878
|
+
return this.adapterManager.canSetBreakpointsIn(model);
|
|
879
|
+
}
|
|
880
|
+
async enableOrDisableBreakpoints(enable, breakpoint) {
|
|
881
|
+
if (breakpoint) {
|
|
882
|
+
this.model.setEnablement(breakpoint, enable);
|
|
883
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
884
|
+
if (breakpoint instanceof Breakpoint) {
|
|
885
|
+
await this.makeTriggeredBreakpointsMatchEnablement(enable, breakpoint);
|
|
886
|
+
await this.sendBreakpoints(breakpoint.originalUri);
|
|
887
|
+
}
|
|
888
|
+
else if (breakpoint instanceof FunctionBreakpoint) {
|
|
889
|
+
await this.sendFunctionBreakpoints();
|
|
890
|
+
}
|
|
891
|
+
else if (breakpoint instanceof DataBreakpoint) {
|
|
892
|
+
await this.sendDataBreakpoints();
|
|
893
|
+
}
|
|
894
|
+
else if (breakpoint instanceof InstructionBreakpoint) {
|
|
895
|
+
await this.sendInstructionBreakpoints();
|
|
896
|
+
}
|
|
897
|
+
else {
|
|
898
|
+
await this.sendExceptionBreakpoints();
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
else {
|
|
902
|
+
this.model.enableOrDisableAllBreakpoints(enable);
|
|
903
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
904
|
+
await this.sendAllBreakpoints();
|
|
905
|
+
}
|
|
906
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
907
|
+
}
|
|
908
|
+
async addBreakpoints(uri, rawBreakpoints, ariaAnnounce = true) {
|
|
909
|
+
const breakpoints = this.model.addBreakpoints(uri, rawBreakpoints);
|
|
910
|
+
if (ariaAnnounce) {
|
|
911
|
+
breakpoints.forEach(bp => status(( localizeWithPath(
|
|
912
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
913
|
+
'breakpointAdded',
|
|
914
|
+
"Added breakpoint, line {0}, file {1}",
|
|
915
|
+
bp.lineNumber,
|
|
916
|
+
uri.fsPath
|
|
917
|
+
))));
|
|
918
|
+
}
|
|
919
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
920
|
+
await this.sendBreakpoints(uri);
|
|
921
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
922
|
+
return breakpoints;
|
|
923
|
+
}
|
|
924
|
+
async updateBreakpoints(uri, data, sendOnResourceSaved) {
|
|
925
|
+
this.model.updateBreakpoints(data);
|
|
926
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
927
|
+
if (sendOnResourceSaved) {
|
|
928
|
+
this.breakpointsToSendOnResourceSaved.add(uri);
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
await this.sendBreakpoints(uri);
|
|
932
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
async removeBreakpoints(id) {
|
|
936
|
+
const breakpoints = this.model.getBreakpoints();
|
|
937
|
+
const toRemove = breakpoints.filter(bp => !id || bp.getId() === id);
|
|
938
|
+
toRemove.forEach(bp => status(( localizeWithPath(
|
|
939
|
+
'vs/workbench/contrib/debug/browser/debugService',
|
|
940
|
+
'breakpointRemoved',
|
|
941
|
+
"Removed breakpoint, line {0}, file {1}",
|
|
942
|
+
bp.lineNumber,
|
|
943
|
+
bp.uri.fsPath
|
|
944
|
+
))));
|
|
945
|
+
const urisToClear = ( new Set(( toRemove.map(bp => ( bp.originalUri.toString())))));
|
|
946
|
+
this.model.removeBreakpoints(toRemove);
|
|
947
|
+
this.unlinkTriggeredBreakpoints(breakpoints, toRemove).forEach(uri => urisToClear.add(( uri.toString())));
|
|
948
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
949
|
+
await Promise.all(( [...urisToClear].map(uri => this.sendBreakpoints(( URI.parse(uri))))));
|
|
950
|
+
}
|
|
951
|
+
setBreakpointsActivated(activated) {
|
|
952
|
+
this.model.setBreakpointsActivated(activated);
|
|
953
|
+
return this.sendAllBreakpoints();
|
|
954
|
+
}
|
|
955
|
+
addFunctionBreakpoint(name, id, mode) {
|
|
956
|
+
this.model.addFunctionBreakpoint(name || '', id, mode);
|
|
957
|
+
}
|
|
958
|
+
async updateFunctionBreakpoint(id, update) {
|
|
959
|
+
this.model.updateFunctionBreakpoint(id, update);
|
|
960
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
961
|
+
await this.sendFunctionBreakpoints();
|
|
962
|
+
}
|
|
963
|
+
async removeFunctionBreakpoints(id) {
|
|
964
|
+
this.model.removeFunctionBreakpoints(id);
|
|
965
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
966
|
+
await this.sendFunctionBreakpoints();
|
|
967
|
+
}
|
|
968
|
+
async addDataBreakpoint(opts) {
|
|
969
|
+
this.model.addDataBreakpoint(opts);
|
|
970
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
971
|
+
await this.sendDataBreakpoints();
|
|
972
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
973
|
+
}
|
|
974
|
+
async updateDataBreakpoint(id, update) {
|
|
975
|
+
this.model.updateDataBreakpoint(id, update);
|
|
976
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
977
|
+
await this.sendDataBreakpoints();
|
|
978
|
+
}
|
|
979
|
+
async removeDataBreakpoints(id) {
|
|
980
|
+
this.model.removeDataBreakpoints(id);
|
|
981
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
982
|
+
await this.sendDataBreakpoints();
|
|
983
|
+
}
|
|
984
|
+
async addInstructionBreakpoint(opts) {
|
|
985
|
+
this.model.addInstructionBreakpoint(opts);
|
|
986
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
987
|
+
await this.sendInstructionBreakpoints();
|
|
988
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
989
|
+
}
|
|
990
|
+
async removeInstructionBreakpoints(instructionReference, offset) {
|
|
991
|
+
this.model.removeInstructionBreakpoints(instructionReference, offset);
|
|
992
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
993
|
+
await this.sendInstructionBreakpoints();
|
|
994
|
+
}
|
|
995
|
+
setExceptionBreakpointFallbackSession(sessionId) {
|
|
996
|
+
this.model.setExceptionBreakpointFallbackSession(sessionId);
|
|
997
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
998
|
+
}
|
|
999
|
+
setExceptionBreakpointsForSession(session, filters) {
|
|
1000
|
+
this.model.setExceptionBreakpointsForSession(session.getId(), filters);
|
|
1001
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
1002
|
+
}
|
|
1003
|
+
async setExceptionBreakpointCondition(exceptionBreakpoint, condition) {
|
|
1004
|
+
this.model.setExceptionBreakpointCondition(exceptionBreakpoint, condition);
|
|
1005
|
+
this.debugStorage.storeBreakpoints(this.model);
|
|
1006
|
+
await this.sendExceptionBreakpoints();
|
|
1007
|
+
}
|
|
1008
|
+
async sendAllBreakpoints(session) {
|
|
1009
|
+
const setBreakpointsPromises = ( distinct(this.model.getBreakpoints(), bp => ( bp.originalUri.toString()))
|
|
1010
|
+
.map(bp => this.sendBreakpoints(bp.originalUri, false, session)));
|
|
1011
|
+
if (session?.capabilities.supportsConfigurationDoneRequest) {
|
|
1012
|
+
await Promise.all([
|
|
1013
|
+
...setBreakpointsPromises,
|
|
1014
|
+
this.sendFunctionBreakpoints(session),
|
|
1015
|
+
this.sendDataBreakpoints(session),
|
|
1016
|
+
this.sendInstructionBreakpoints(session),
|
|
1017
|
+
this.sendExceptionBreakpoints(session),
|
|
1018
|
+
]);
|
|
1019
|
+
}
|
|
1020
|
+
else {
|
|
1021
|
+
await Promise.all(setBreakpointsPromises);
|
|
1022
|
+
await this.sendFunctionBreakpoints(session);
|
|
1023
|
+
await this.sendDataBreakpoints(session);
|
|
1024
|
+
await this.sendInstructionBreakpoints(session);
|
|
1025
|
+
await this.sendExceptionBreakpoints(session);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
unlinkTriggeredBreakpoints(allBreakpoints, removedBreakpoints) {
|
|
1029
|
+
const affectedUris = [];
|
|
1030
|
+
for (const removed of removedBreakpoints) {
|
|
1031
|
+
for (const existing of allBreakpoints) {
|
|
1032
|
+
if (!removedBreakpoints.includes(existing) && existing.triggeredBy === removed.getId()) {
|
|
1033
|
+
this.model.updateBreakpoints(( new Map([[existing.getId(), { triggeredBy: undefined }]])));
|
|
1034
|
+
affectedUris.push(existing.originalUri);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
return affectedUris;
|
|
1039
|
+
}
|
|
1040
|
+
async makeTriggeredBreakpointsMatchEnablement(enable, breakpoint) {
|
|
1041
|
+
if (enable) {
|
|
1042
|
+
if (breakpoint.triggeredBy) {
|
|
1043
|
+
const trigger = this.model.getBreakpoints().find(bp => breakpoint.triggeredBy === bp.getId());
|
|
1044
|
+
if (trigger && !trigger.enabled) {
|
|
1045
|
+
await this.enableOrDisableBreakpoints(enable, trigger);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
1049
|
+
await Promise.all(( this.model.getBreakpoints()
|
|
1050
|
+
.filter(bp => bp.triggeredBy === breakpoint.getId() && bp.enabled !== enable)
|
|
1051
|
+
.map(bp => this.enableOrDisableBreakpoints(enable, bp))));
|
|
1052
|
+
}
|
|
1053
|
+
async sendBreakpoints(modelUri, sourceModified = false, session) {
|
|
1054
|
+
const breakpointsToSend = this.model.getBreakpoints({ originalUri: modelUri, enabledOnly: true });
|
|
1055
|
+
await sendToOneOrAllSessions(this.model, session, async (s) => {
|
|
1056
|
+
if (!s.configuration.noDebug) {
|
|
1057
|
+
const sessionBps = breakpointsToSend.filter(bp => !bp.triggeredBy || bp.getSessionDidTrigger(s.getId()));
|
|
1058
|
+
await s.sendBreakpoints(modelUri, sessionBps, sourceModified);
|
|
1059
|
+
}
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
async sendFunctionBreakpoints(session) {
|
|
1063
|
+
const breakpointsToSend = this.model.getFunctionBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
|
1064
|
+
await sendToOneOrAllSessions(this.model, session, async (s) => {
|
|
1065
|
+
if (s.capabilities.supportsFunctionBreakpoints && !s.configuration.noDebug) {
|
|
1066
|
+
await s.sendFunctionBreakpoints(breakpointsToSend);
|
|
1067
|
+
}
|
|
1068
|
+
});
|
|
1069
|
+
}
|
|
1070
|
+
async sendDataBreakpoints(session) {
|
|
1071
|
+
const breakpointsToSend = this.model.getDataBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
|
1072
|
+
await sendToOneOrAllSessions(this.model, session, async (s) => {
|
|
1073
|
+
if (s.capabilities.supportsDataBreakpoints && !s.configuration.noDebug) {
|
|
1074
|
+
await s.sendDataBreakpoints(breakpointsToSend);
|
|
1075
|
+
}
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
async sendInstructionBreakpoints(session) {
|
|
1079
|
+
const breakpointsToSend = this.model.getInstructionBreakpoints().filter(fbp => fbp.enabled && this.model.areBreakpointsActivated());
|
|
1080
|
+
await sendToOneOrAllSessions(this.model, session, async (s) => {
|
|
1081
|
+
if (s.capabilities.supportsInstructionBreakpoints && !s.configuration.noDebug) {
|
|
1082
|
+
await s.sendInstructionBreakpoints(breakpointsToSend);
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1085
|
+
}
|
|
1086
|
+
sendExceptionBreakpoints(session) {
|
|
1087
|
+
return sendToOneOrAllSessions(this.model, session, async (s) => {
|
|
1088
|
+
const enabledExceptionBps = this.model.getExceptionBreakpointsForSession(s.getId()).filter(exb => exb.enabled);
|
|
1089
|
+
if (s.capabilities.supportsConfigurationDoneRequest && (!s.capabilities.exceptionBreakpointFilters || s.capabilities.exceptionBreakpointFilters.length === 0)) {
|
|
1090
|
+
return;
|
|
1091
|
+
}
|
|
1092
|
+
if (!s.configuration.noDebug) {
|
|
1093
|
+
await s.sendExceptionBreakpoints(enabledExceptionBps);
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
}
|
|
1097
|
+
onFileChanges(fileChangesEvent) {
|
|
1098
|
+
const toRemove = this.model.getBreakpoints().filter(bp => fileChangesEvent.contains(bp.originalUri, 2 ));
|
|
1099
|
+
if (toRemove.length) {
|
|
1100
|
+
this.model.removeBreakpoints(toRemove);
|
|
1101
|
+
}
|
|
1102
|
+
const toSend = [];
|
|
1103
|
+
for (const uri of this.breakpointsToSendOnResourceSaved) {
|
|
1104
|
+
if (fileChangesEvent.contains(uri, 0 )) {
|
|
1105
|
+
toSend.push(uri);
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
for (const uri of toSend) {
|
|
1109
|
+
this.breakpointsToSendOnResourceSaved.delete(uri);
|
|
1110
|
+
this.sendBreakpoints(uri, true);
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
async runTo(uri, lineNumber, column) {
|
|
1114
|
+
let breakpointToRemove;
|
|
1115
|
+
let threadToContinue = this.getViewModel().focusedThread;
|
|
1116
|
+
const addTempBreakPoint = async () => {
|
|
1117
|
+
const bpExists = !!(this.getModel().getBreakpoints({ column, lineNumber, uri }).length);
|
|
1118
|
+
if (!bpExists) {
|
|
1119
|
+
const addResult = await this.addAndValidateBreakpoints(uri, lineNumber, column);
|
|
1120
|
+
if (addResult.thread) {
|
|
1121
|
+
threadToContinue = addResult.thread;
|
|
1122
|
+
}
|
|
1123
|
+
if (addResult.breakpoint) {
|
|
1124
|
+
breakpointToRemove = addResult.breakpoint;
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
return { threadToContinue, breakpointToRemove };
|
|
1128
|
+
};
|
|
1129
|
+
const removeTempBreakPoint = (state) => {
|
|
1130
|
+
if (state === 2 || state === 0 ) {
|
|
1131
|
+
if (breakpointToRemove) {
|
|
1132
|
+
this.removeBreakpoints(breakpointToRemove.getId());
|
|
1133
|
+
}
|
|
1134
|
+
return true;
|
|
1135
|
+
}
|
|
1136
|
+
return false;
|
|
1137
|
+
};
|
|
1138
|
+
await addTempBreakPoint();
|
|
1139
|
+
if (this.state === 0 ) {
|
|
1140
|
+
const { launch, name, getConfig } = this.getConfigurationManager().selectedConfiguration;
|
|
1141
|
+
const config = await getConfig();
|
|
1142
|
+
const configOrName = config ? Object.assign(deepClone(config), {}) : name;
|
|
1143
|
+
const listener = this.onDidChangeState(state => {
|
|
1144
|
+
if (removeTempBreakPoint(state)) {
|
|
1145
|
+
listener.dispose();
|
|
1146
|
+
}
|
|
1147
|
+
});
|
|
1148
|
+
await this.startDebugging(launch, configOrName, undefined, true);
|
|
1149
|
+
}
|
|
1150
|
+
if (this.state === 2 ) {
|
|
1151
|
+
const focusedSession = this.getViewModel().focusedSession;
|
|
1152
|
+
if (!focusedSession || !threadToContinue) {
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
const listener = threadToContinue.session.onDidChangeState(() => {
|
|
1156
|
+
if (removeTempBreakPoint(focusedSession.state)) {
|
|
1157
|
+
listener.dispose();
|
|
1158
|
+
}
|
|
1159
|
+
});
|
|
1160
|
+
await threadToContinue.continue();
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
async addAndValidateBreakpoints(uri, lineNumber, column) {
|
|
1164
|
+
const debugModel = this.getModel();
|
|
1165
|
+
const viewModel = this.getViewModel();
|
|
1166
|
+
const breakpoints = await this.addBreakpoints(uri, [{ lineNumber, column }], false);
|
|
1167
|
+
const breakpoint = breakpoints?.[0];
|
|
1168
|
+
if (!breakpoint) {
|
|
1169
|
+
return { breakpoint: undefined, thread: viewModel.focusedThread };
|
|
1170
|
+
}
|
|
1171
|
+
if (!breakpoint.verified) {
|
|
1172
|
+
let listener;
|
|
1173
|
+
await raceTimeout(( new Promise(resolve => {
|
|
1174
|
+
listener = debugModel.onDidChangeBreakpoints(() => {
|
|
1175
|
+
if (breakpoint.verified) {
|
|
1176
|
+
resolve();
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
})), 2000);
|
|
1180
|
+
listener.dispose();
|
|
1181
|
+
}
|
|
1182
|
+
let bestThread = viewModel.focusedThread;
|
|
1183
|
+
let bestScore = 0 ;
|
|
1184
|
+
for (const sessionId of breakpoint.sessionsThatVerified) {
|
|
1185
|
+
const session = debugModel.getSession(sessionId);
|
|
1186
|
+
if (!session) {
|
|
1187
|
+
continue;
|
|
1188
|
+
}
|
|
1189
|
+
const threads = session.getAllThreads().filter(t => t.stopped);
|
|
1190
|
+
if (bestScore < 3 ) {
|
|
1191
|
+
if (viewModel.focusedThread && threads.includes(viewModel.focusedThread)) {
|
|
1192
|
+
bestThread = viewModel.focusedThread;
|
|
1193
|
+
bestScore = 3 ;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
if (bestScore < 2 ) {
|
|
1197
|
+
const pausedInThisFile = threads.find(t => {
|
|
1198
|
+
const top = t.getTopStackFrame();
|
|
1199
|
+
return top && this.uriIdentityService.extUri.isEqual(top.source.uri, uri);
|
|
1200
|
+
});
|
|
1201
|
+
if (pausedInThisFile) {
|
|
1202
|
+
bestThread = pausedInThisFile;
|
|
1203
|
+
bestScore = 2 ;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
if (bestScore < 1 ) {
|
|
1207
|
+
bestThread = threads[0];
|
|
1208
|
+
bestScore = 2 ;
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
return { thread: bestThread, breakpoint };
|
|
1212
|
+
}
|
|
1213
|
+
};
|
|
1214
|
+
DebugService = ( __decorate([
|
|
1215
|
+
( __param(0, IEditorService)),
|
|
1216
|
+
( __param(1, IPaneCompositePartService)),
|
|
1217
|
+
( __param(2, IViewsService)),
|
|
1218
|
+
( __param(3, IViewDescriptorService)),
|
|
1219
|
+
( __param(4, INotificationService)),
|
|
1220
|
+
( __param(5, IDialogService)),
|
|
1221
|
+
( __param(6, IWorkbenchLayoutService)),
|
|
1222
|
+
( __param(7, IWorkspaceContextService)),
|
|
1223
|
+
( __param(8, IContextKeyService)),
|
|
1224
|
+
( __param(9, ILifecycleService)),
|
|
1225
|
+
( __param(10, IInstantiationService)),
|
|
1226
|
+
( __param(11, IExtensionService)),
|
|
1227
|
+
( __param(12, IFileService)),
|
|
1228
|
+
( __param(13, IConfigurationService)),
|
|
1229
|
+
( __param(14, IExtensionHostDebugService)),
|
|
1230
|
+
( __param(15, IActivityService)),
|
|
1231
|
+
( __param(16, ICommandService)),
|
|
1232
|
+
( __param(17, IQuickInputService)),
|
|
1233
|
+
( __param(18, IWorkspaceTrustRequestService)),
|
|
1234
|
+
( __param(19, IUriIdentityService))
|
|
1235
|
+
], DebugService));
|
|
1236
|
+
function getStackFrameThreadAndSessionToFocus(model, stackFrame, thread, session, avoidSession) {
|
|
1237
|
+
if (!session) {
|
|
1238
|
+
if (stackFrame || thread) {
|
|
1239
|
+
session = stackFrame ? stackFrame.thread.session : thread.session;
|
|
1240
|
+
}
|
|
1241
|
+
else {
|
|
1242
|
+
const sessions = model.getSessions();
|
|
1243
|
+
const stoppedSession = sessions.find(s => s.state === 2 );
|
|
1244
|
+
session = stoppedSession || sessions.find(s => s !== avoidSession && s !== avoidSession?.parentSession) || (sessions.length ? sessions[0] : undefined);
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
if (!thread) {
|
|
1248
|
+
if (stackFrame) {
|
|
1249
|
+
thread = stackFrame.thread;
|
|
1250
|
+
}
|
|
1251
|
+
else {
|
|
1252
|
+
const threads = session ? session.getAllThreads() : undefined;
|
|
1253
|
+
const stoppedThread = threads && threads.find(t => t.stopped);
|
|
1254
|
+
thread = stoppedThread || (threads && threads.length ? threads[0] : undefined);
|
|
1255
|
+
}
|
|
1256
|
+
}
|
|
1257
|
+
if (!stackFrame && thread) {
|
|
1258
|
+
stackFrame = thread.getTopStackFrame();
|
|
1259
|
+
}
|
|
1260
|
+
return { session, thread, stackFrame };
|
|
1261
|
+
}
|
|
1262
|
+
async function sendToOneOrAllSessions(model, session, send) {
|
|
1263
|
+
if (session) {
|
|
1264
|
+
await send(session);
|
|
1265
|
+
}
|
|
1266
|
+
else {
|
|
1267
|
+
await Promise.all(( model.getSessions().map(s => send(s))));
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
export { DebugService, getStackFrameThreadAndSessionToFocus };
|