Path: blob/main/src/vs/workbench/contrib/debug/common/debugSource.ts
3296 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as nls from '../../../../nls.js';6import { URI } from '../../../../base/common/uri.js';7import { normalize, isAbsolute } from '../../../../base/common/path.js';8import * as resources from '../../../../base/common/resources.js';9import { DEBUG_SCHEME } from './debug.js';10import { IRange } from '../../../../editor/common/core/range.js';11import { IEditorService, SIDE_GROUP, ACTIVE_GROUP } from '../../../services/editor/common/editorService.js';12import { Schemas } from '../../../../base/common/network.js';13import { isUri } from './debugUtils.js';14import { IEditorPane } from '../../../common/editor.js';15import { TextEditorSelectionRevealType } from '../../../../platform/editor/common/editor.js';16import { IUriIdentityService } from '../../../../platform/uriIdentity/common/uriIdentity.js';17import { ILogService } from '../../../../platform/log/common/log.js';1819export const UNKNOWN_SOURCE_LABEL = nls.localize('unknownSource', "Unknown Source");2021/**22* Debug URI format23*24* a debug URI represents a Source object and the debug session where the Source comes from.25*26* debug:arbitrary_path?session=123e4567-e89b-12d3-a456-426655440000&ref=101627* \___/ \____________/ \__________________________________________/ \______/28* | | | |29* scheme source.path session id source.reference30*31*32*/3334export class Source {3536readonly uri: URI;37available: boolean;38raw: DebugProtocol.Source;3940constructor(raw_: DebugProtocol.Source | undefined, sessionId: string, uriIdentityService: IUriIdentityService, logService: ILogService) {41let path: string;42if (raw_) {43this.raw = raw_;44path = this.raw.path || this.raw.name || '';45this.available = true;46} else {47this.raw = { name: UNKNOWN_SOURCE_LABEL };48this.available = false;49path = `${DEBUG_SCHEME}:${UNKNOWN_SOURCE_LABEL}`;50}5152this.uri = getUriFromSource(this.raw, path, sessionId, uriIdentityService, logService);53}5455get name() {56return this.raw.name || resources.basenameOrAuthority(this.uri);57}5859get origin() {60return this.raw.origin;61}6263get presentationHint() {64return this.raw.presentationHint;65}6667get reference() {68return this.raw.sourceReference;69}7071get inMemory() {72return this.uri.scheme === DEBUG_SCHEME;73}7475openInEditor(editorService: IEditorService, selection: IRange, preserveFocus?: boolean, sideBySide?: boolean, pinned?: boolean): Promise<IEditorPane | undefined> {76return !this.available ? Promise.resolve(undefined) : editorService.openEditor({77resource: this.uri,78description: this.origin,79options: {80preserveFocus,81selection,82revealIfOpened: true,83selectionRevealType: TextEditorSelectionRevealType.CenterIfOutsideViewport,84pinned85}86}, sideBySide ? SIDE_GROUP : ACTIVE_GROUP);87}8889static getEncodedDebugData(modelUri: URI): { name: string; path: string; sessionId?: string; sourceReference?: number } {90let path: string;91let sourceReference: number | undefined;92let sessionId: string | undefined;9394switch (modelUri.scheme) {95case Schemas.file:96path = normalize(modelUri.fsPath);97break;98case DEBUG_SCHEME:99path = modelUri.path;100if (modelUri.query) {101const keyvalues = modelUri.query.split('&');102for (const keyvalue of keyvalues) {103const pair = keyvalue.split('=');104if (pair.length === 2) {105switch (pair[0]) {106case 'session':107sessionId = pair[1];108break;109case 'ref':110sourceReference = parseInt(pair[1]);111break;112}113}114}115}116break;117default:118path = modelUri.toString();119break;120}121122return {123name: resources.basenameOrAuthority(modelUri),124path,125sourceReference,126sessionId127};128}129}130131export function getUriFromSource(raw: DebugProtocol.Source, path: string | undefined, sessionId: string, uriIdentityService: IUriIdentityService, logService: ILogService): URI {132const _getUriFromSource = (path: string | undefined) => {133if (typeof raw.sourceReference === 'number' && raw.sourceReference > 0) {134return URI.from({135scheme: DEBUG_SCHEME,136path: path?.replace(/^\/+/g, '/'), // #174054137query: `session=${sessionId}&ref=${raw.sourceReference}`138});139}140141if (path && isUri(path)) { // path looks like a uri142return uriIdentityService.asCanonicalUri(URI.parse(path));143}144// assume a filesystem path145if (path && isAbsolute(path)) {146return uriIdentityService.asCanonicalUri(URI.file(path));147}148// path is relative: since VS Code cannot deal with this by itself149// create a debug url that will result in a DAP 'source' request when the url is resolved.150return uriIdentityService.asCanonicalUri(URI.from({151scheme: DEBUG_SCHEME,152path,153query: `session=${sessionId}`154}));155};156157158try {159return _getUriFromSource(path);160} catch (err) {161logService.error('Invalid path from debug adapter: ' + path);162return _getUriFromSource('/invalidDebugSource');163}164}165166167