// ***************************************************************************** // Copyright (C) 2018 Red Hat, Inc. and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** import { injectable, inject } from '@theia/core/shared/inversify'; import { DebugConfiguration } from '../common/debug-configuration'; import { DebugService, DebuggerDescription, DynamicDebugConfigurationProvider } from '../common/debug-service'; import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema'; import { CommandIdVariables } from '@theia/variable-resolver/lib/common/variable-types'; import { DebugAdapterSessionManager } from './debug-adapter-session-manager'; import { DebugAdapterContributionRegistry } from '../common/debug-adapter-contribution-registry'; import { Event } from '@theia/core'; /** * DebugService implementation. */ @injectable() export class DebugServiceImpl implements DebugService { @inject(DebugAdapterSessionManager) protected readonly sessionManager: DebugAdapterSessionManager; @inject(DebugAdapterContributionRegistry) protected readonly registry: DebugAdapterContributionRegistry; get onDidChangeDebugConfigurationProviders(): Event { return Event.None; } dispose(): void { this.terminateDebugSession(); } async debugTypes(): Promise { return this.registry.debugTypes(); } getDebuggersForLanguage(language: string): Promise { return this.registry.getDebuggersForLanguage(language); } getSchemaAttributes(debugType: string): Promise { return this.registry.getSchemaAttributes(debugType); } getConfigurationSnippets(): Promise { return this.registry.getConfigurationSnippets(); } async provideDebuggerVariables(debugType: string): Promise { // TODO: Support resolution of variables map through Theia extensions? return {}; } async provideDebugConfigurations(debugType: string, workspaceFolderUri?: string): Promise { return this.registry.provideDebugConfigurations(debugType, workspaceFolderUri); } async provideDynamicDebugConfigurations(): Promise> { // TODO: Support dynamic debug configurations through Theia extensions? return {}; } async provideDynamicDebugConfigurationsByType(type: string, folder?: string): Promise { // TODO: Support dynamic debug configurations through Theia extensions? return []; } getDynamicDebugConfigurationProviders(): DynamicDebugConfigurationProvider[] { // TODO: Support dynamic debug configurations through Theia extensions? return []; } getDynamicDebugConfigurationProviderTypes(): string[] { // TODO: Support dynamic debug configurations through Theia extensions? return []; } fetchDynamicDebugConfiguration(name: string, type: string, folder?: string): Promise { // TODO: Support dynamic debug configurations through Theia extensions? return Promise.resolve(undefined); } async resolveDebugConfiguration(config: DebugConfiguration, workspaceFolderUri?: string): Promise { return this.registry.resolveDebugConfiguration(config, workspaceFolderUri); } async resolveDebugConfigurationWithSubstitutedVariables(config: DebugConfiguration, workspaceFolderUri?: string): Promise { return this.registry.resolveDebugConfigurationWithSubstitutedVariables(config, workspaceFolderUri); } protected readonly sessions = new Set(); async createDebugSession(config: DebugConfiguration, _workspaceFolderUri?: string): Promise { const session = await this.sessionManager.create(config, this.registry); this.sessions.add(session.id); return session.id; } async terminateDebugSession(sessionId?: string): Promise { if (sessionId) { await this.doStop(sessionId); } else { const promises: Promise[] = []; const sessions = [...this.sessions]; this.sessions.clear(); for (const session of sessions) { promises.push((async () => { try { await this.doStop(session); } catch (e) { console.error('terminateDebugSession failed:', e); } })()); } await Promise.all(promises); } } protected async doStop(sessionId: string): Promise { const debugSession = this.sessionManager.find(sessionId); if (debugSession) { this.sessionManager.remove(sessionId); this.sessions.delete(sessionId); await debugSession.stop(); } } }