Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/workbench/contrib/debug/common/debugSource.ts
3296 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as nls from '../../../../nls.js';
7
import { URI } from '../../../../base/common/uri.js';
8
import { normalize, isAbsolute } from '../../../../base/common/path.js';
9
import * as resources from '../../../../base/common/resources.js';
10
import { DEBUG_SCHEME } from './debug.js';
11
import { IRange } from '../../../../editor/common/core/range.js';
12
import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from '../../../services/editor/common/editorService.js';
13
import { Schemas } from '../../../../base/common/network.js';
14
import { isUri } from './debugUtils.js';
15
import { IEditorPane } from '../../../common/editor.js';
16
import { TextEditorSelectionRevealType } from '../../../../platform/editor/common/editor.js';
17
import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';
18
import { ILogService } from '../../../../platform/log/common/log.js';
19
20
export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source");
21
22
/**
23
* Debug URI format
24
*
25
* a debug URI represents a Source object and the debug session where the Source comes from.
26
*
27
* debug:arbitrary_path?session=123e4567-e89b-12d3-a456-426655440000&ref=1016
28
* \___/ \____________/ \__________________________________________/ \______/
29
* | | | |
30
* scheme source.path session id source.reference
31
*
32
*
33
*/
34
35
export class Source {
36
37
readonly uri: URI;
38
available: boolean;
39
raw: DebugProtocol.Source;
40
41
constructor(raw_: DebugProtocol.Source | undefined, sessionId: string, uriIdentityService: IUriIdentityService, logService: ILogService) {
42
let path: string;
43
if (raw_) {
44
this.raw = raw_;
45
path = this.raw.path || this.raw.name || '';
46
this.available = true;
47
} else {
48
this.raw = { name: UNKNOWN_SOURCE_LABEL };
49
this.available = false;
50
path = `${DEBUG_SCHEME}:${UNKNOWN_SOURCE_LABEL}`;
51
}
52
53
this.uri = getUriFromSource(this.raw, path, sessionId, uriIdentityService, logService);
54
}
55
56
get name() {
57
return this.raw.name || resources.basenameOrAuthority(this.uri);
58
}
59
60
get origin() {
61
return this.raw.origin;
62
}
63
64
get presentationHint() {
65
return this.raw.presentationHint;
66
}
67
68
get reference() {
69
return this.raw.sourceReference;
70
}
71
72
get inMemory() {
73
return this.uri.scheme === DEBUG_SCHEME;
74
}
75
76
openInEditor(editorService: IEditorService, selection: IRange, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<IEditorPane | undefined> {
77
return !this.available ? Promise.resolve(undefined) : editorService.openEditor({
78
resource: this.uri,
79
description: this.origin,
80
options: {
81
preserveFocus,
82
selection,
83
revealIfOpened: true,
84
selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,
85
pinned
86
}
87
}, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);
88
}
89
90
static getEncodedDebugData(modelUri: URI): { name: string; path: string; sessionId?: string; sourceReference?: number } {
91
let path: string;
92
let sourceReference: number | undefined;
93
let sessionId: string | undefined;
94
95
switch (modelUri.scheme) {
96
case Schemas.file:
97
path = normalize(modelUri.fsPath);
98
break;
99
case DEBUG_SCHEME:
100
path = modelUri.path;
101
if (modelUri.query) {
102
const keyvalues = modelUri.query.split('&');
103
for (const keyvalue of keyvalues) {
104
const pair = keyvalue.split('=');
105
if (pair.length === 2) {
106
switch (pair[0]) {
107
case 'session':
108
sessionId = pair[1];
109
break;
110
case 'ref':
111
sourceReference = parseInt(pair[1]);
112
break;
113
}
114
}
115
}
116
}
117
break;
118
default:
119
path = modelUri.toString();
120
break;
121
}
122
123
return {
124
name: resources.basenameOrAuthority(modelUri),
125
path,
126
sourceReference,
127
sessionId
128
};
129
}
130
}
131
132
export function getUriFromSource(raw: DebugProtocol.Source, path: string | undefined, sessionId: string, uriIdentityService: IUriIdentityService, logService: ILogService): URI {
133
const _getUriFromSource = (path: string | undefined) => {
134
if (typeof raw.sourceReference === 'number' && raw.sourceReference > 0) {
135
return URI.from({
136
scheme: DEBUG_SCHEME,
137
path: path?.replace(/^\/+/g, '/'), // #174054
138
query: `session=${sessionId}&ref=${raw.sourceReference}`
139
});
140
}
141
142
if (path && isUri(path)) { // path looks like a uri
143
return uriIdentityService.asCanonicalUri(URI.parse(path));
144
}
145
// assume a filesystem path
146
if (path && isAbsolute(path)) {
147
return uriIdentityService.asCanonicalUri(URI.file(path));
148
}
149
// path is relative: since VS Code cannot deal with this by itself
150
// create a debug url that will result in a DAP 'source' request when the url is resolved.
151
return uriIdentityService.asCanonicalUri(URI.from({
152
scheme: DEBUG_SCHEME,
153
path,
154
query: `session=${sessionId}`
155
}));
156
};
157
158
159
try {
160
return _getUriFromSource(path);
161
} catch (err) {
162
logService.error('Invalid path from debug adapter: ' + path);
163
return _getUriFromSource('/invalidDebugSource');
164
}
165
}
166
167