Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use node debugger as a plugin #3902

Merged
merged 1 commit into from
Jan 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
********************************************************************************/

import { ContainerModule } from 'inversify';
import { NodeDebugAdapterContribution, Node2DebugAdapterContribution } from './node-debug-adapter-contribution';
import { DebugAdapterContribution } from '@theia/debug/lib/common/debug-model';
import { NodeDebugAdapterContribution, Node2DebugAdapterContribution } from './node-debug-adapter-contribution';

export default new ContainerModule(bind => {
bind(DebugAdapterContribution).to(NodeDebugAdapterContribution).inSingletonScope();
Expand Down
1 change: 0 additions & 1 deletion packages/plugin-ext/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
"typings": "lib/common/index.d.ts",
"dependencies": {
"@theia/core": "^0.3.18",
"@theia/debug-nodejs": "^0.3.18",
"@theia/editor": "^0.3.18",
"@theia/filesystem": "^0.3.18",
"@theia/monaco": "^0.3.18",
Expand Down
17 changes: 8 additions & 9 deletions packages/plugin-ext/src/api/plugin-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ import { CancellationToken, Progress, ProgressOptions } from '@theia/plugin';
import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema';
import { DebuggerDescription } from '@theia/debug/lib/common/debug-service';
import { DebugProtocol } from 'vscode-debugprotocol';

import { SymbolInformation } from 'vscode-languageserver-types';

export interface PluginInitData {
Expand Down Expand Up @@ -945,20 +944,20 @@ export interface DebugExt {
$sessionDidCreate(sessionId: string): void;
$sessionDidDestroy(sessionId: string): void;
$sessionDidChange(sessionId: string | undefined): void;
$provideDebugConfigurations(contributionId: string, folder: string | undefined): Promise<theia.DebugConfiguration[]>;
$resolveDebugConfigurations(contributionId: string, debugConfiguration: theia.DebugConfiguration, folder: string | undefined): Promise<theia.DebugConfiguration | undefined>;
$getSupportedLanguages(contributionId: string): Promise<string[]>;
$getSchemaAttributes(contributionId: string): Promise<IJSONSchema[]>;
$getConfigurationSnippets(contributionId: string): Promise<IJSONSchemaSnippet[]>;
$createDebugSession(contributionId: string, debugConfiguration: theia.DebugConfiguration): Promise<string>;
$provideDebugConfigurations(debugType: string, workspaceFolder: string | undefined): Promise<theia.DebugConfiguration[]>;
$resolveDebugConfigurations(debugConfiguration: theia.DebugConfiguration, workspaceFolder: string | undefined): Promise<theia.DebugConfiguration | undefined>;
$getSupportedLanguages(debugType: string): Promise<string[]>;
$getSchemaAttributes(debugType: string): Promise<IJSONSchema[]>;
$getConfigurationSnippets(debugType: string): Promise<IJSONSchemaSnippet[]>;
$createDebugSession(debugConfiguration: theia.DebugConfiguration): Promise<string>;
$terminateDebugSession(sessionId: string): Promise<void>;
}

export interface DebugMain {
$appendToDebugConsole(value: string): Promise<void>;
$appendLineToDebugConsole(value: string): Promise<void>;
$registerDebugConfigurationProvider(contributorId: string, description: DebuggerDescription): Promise<void>;
$unregisterDebugConfigurationProvider(contributorId: string): Promise<void>;
$registerDebuggerContribution(description: DebuggerDescription): Promise<void>;
$unregisterDebuggerConfiguration(debugType: string): Promise<void>;
$addBreakpoints(breakpoints: Breakpoint[]): Promise<void>;
$removeBreakpoints(breakpoints: Breakpoint[]): Promise<void>;
$startDebugging(folder: theia.WorkspaceFolder | undefined, nameOrConfiguration: string | theia.DebugConfiguration): Promise<boolean>;
Expand Down
35 changes: 14 additions & 21 deletions packages/plugin-ext/src/main/browser/debug/debug-main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ export class DebugMainImpl implements DebugMain {
private readonly adapterContributionRegistrator: PluginDebugAdapterContributionRegistrator;
private readonly debugSchemaUpdater: DebugSchemaUpdater;

// registered plugins per contributorId
private readonly toDispose = new Map<string, DisposableCollection>();

constructor(rpc: RPCProtocol, readonly connectionMain: ConnectionMainImpl, container: interfaces.Container) {
Expand Down Expand Up @@ -106,16 +105,9 @@ export class DebugMainImpl implements DebugMain {
this.debugConsoleSession.appendLine(value);
}

async $registerDebugConfigurationProvider(contributorId: string, description: DebuggerDescription): Promise<void> {
async $registerDebuggerContribution(description: DebuggerDescription): Promise<void> {
const disposable = new DisposableCollection();
this.toDispose.set(contributorId, disposable);

const debugAdapterContributor = new PluginDebugAdapterContribution(
description.type,
description.label,
this.debugExt.$getSupportedLanguages(contributorId),
contributorId,
this.debugExt);
this.toDispose.set(description.type, disposable);

const debugSessionFactory = new PluginDebugSessionFactory(
this.terminalService,
Expand All @@ -131,23 +123,24 @@ export class DebugMainImpl implements DebugMain {
}
);

disposable.push(this.adapterContributionRegistrator.registerDebugAdapterContribution(debugAdapterContributor));
disposable.push(
this.sessionContributionRegistrator.registerDebugSessionContribution(
{
debugType: description.type,
debugSessionFactory: () => debugSessionFactory
})
);
disposable.pushAll([
this.adapterContributionRegistrator.registerDebugAdapterContribution(
new PluginDebugAdapterContribution(description, this.debugExt)
),
this.sessionContributionRegistrator.registerDebugSessionContribution({
debugType: description.type,
debugSessionFactory: () => debugSessionFactory
})
]);

this.debugSchemaUpdater.update();
}

async $unregisterDebugConfigurationProvider(contributorId: string): Promise<void> {
const disposable = this.toDispose.get(contributorId);
async $unregisterDebuggerConfiguration(debugType: string): Promise<void> {
const disposable = this.toDispose.get(debugType);
if (disposable) {
disposable.dispose();
this.toDispose.delete(contributorId);
this.toDispose.delete(debugType);
this.debugSchemaUpdater.update();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,41 +18,49 @@ import { DebugExt, } from '../../../api/plugin-api';
import { DebugConfiguration } from '@theia/debug/lib/common/debug-configuration';
import { IJSONSchemaSnippet, IJSONSchema } from '@theia/core/lib/common/json-schema';
import { MaybePromise } from '@theia/core/lib/common/types';
import { DebugAdapterContribution } from '@theia/debug/lib/common/debug-model';
import { DebuggerDescription } from '@theia/debug/lib/common/debug-service';

/**
* Plugin [DebugAdapterContribution](#DebugAdapterContribution) with functionality
* to create / terminated debug adapter session.
* Plugin [DebugAdapterContribution](#DebugAdapterContribution).
*/
export class PluginDebugAdapterContribution implements DebugAdapterContribution {
export class PluginDebugAdapterContribution {
constructor(
readonly type: string,
readonly label: MaybePromise<string | undefined>,
readonly languages: MaybePromise<string[] | undefined>,
protected readonly contributorId: string,
protected readonly description: DebuggerDescription,
protected readonly debugExt: DebugExt) { }

async provideDebugConfigurations(workspaceFolderUri: string | undefined): Promise<DebugConfiguration[]> {
return this.debugExt.$provideDebugConfigurations(this.contributorId, workspaceFolderUri);
get type(): string {
return this.description.type;
}

async resolveDebugConfiguration(config: DebugConfiguration, workspaceFolderUri: string | undefined): Promise<DebugConfiguration | undefined> {
return this.debugExt.$resolveDebugConfigurations(this.contributorId, config, workspaceFolderUri);
get label(): MaybePromise<string | undefined> {
return this.description.label;
}

get languages(): MaybePromise<string[] | undefined> {
return this.debugExt.$getSupportedLanguages(this.type);
}

async getSchemaAttributes(): Promise<IJSONSchema[]> {
return this.debugExt.$getSchemaAttributes(this.contributorId);
return this.debugExt.$getSchemaAttributes(this.type);
}

async getConfigurationSnippets(): Promise<IJSONSchemaSnippet[]> {
return this.debugExt.$getConfigurationSnippets(this.contributorId);
return this.debugExt.$getConfigurationSnippets(this.type);
}

async provideDebugConfigurations(workspaceFolderUri: string | undefined): Promise<DebugConfiguration[]> {
return this.debugExt.$provideDebugConfigurations(this.type, workspaceFolderUri);
}

async resolveDebugConfiguration(config: DebugConfiguration, workspaceFolderUri: string | undefined): Promise<DebugConfiguration | undefined> {
return this.debugExt.$resolveDebugConfigurations(config, workspaceFolderUri);
}

async createDebugSession(debugConfiguration: DebugConfiguration): Promise<string> {
return this.debugExt.$createDebugSession(this.contributorId, debugConfiguration);
async createDebugSession(config: DebugConfiguration): Promise<string> {
return this.debugExt.$createDebugSession(config);
}

async terminateDebugSession(sessionId: string): Promise<void> {
return this.debugExt.$terminateDebugSession(sessionId);
this.debugExt.$terminateDebugSession(sessionId);
}
}
32 changes: 16 additions & 16 deletions packages/plugin-ext/src/main/browser/debug/plugin-debug-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-sch
import { PluginDebugAdapterContribution } from './plugin-debug-adapter-contribution';
import { injectable, inject, postConstruct } from 'inversify';
import { WebSocketConnectionProvider } from '@theia/core/lib/browser/messaging/ws-connection-provider';
import { WorkspaceService } from '@theia/workspace/lib/browser';

/**
* Debug adapter contribution registrator.
Expand All @@ -47,23 +48,27 @@ export class PluginDebugService implements DebugService, PluginDebugAdapterContr
protected readonly contributors = new Map<string, PluginDebugAdapterContribution>();
protected readonly toDispose = new DisposableCollection();

// maps session and contribution identifiers.
// maps session and contribution
protected readonly sessionId2contrib = new Map<string, PluginDebugAdapterContribution>();
protected delegated: DebugService;

@inject(WebSocketConnectionProvider)
protected readonly connectionProvider: WebSocketConnectionProvider;
@inject(WorkspaceService)
protected readonly workspaceService: WorkspaceService;

@postConstruct()
protected init(): void {
this.delegated = this.connectionProvider.createProxy<DebugService>(DebugPath);
this.toDispose.push(Disposable.create(() => this.delegated.dispose()));
this.toDispose.push(Disposable.create(() => {
for (const sessionId of this.sessionId2contrib.keys()) {
const contrib = this.sessionId2contrib.get(sessionId)!;
contrib.terminateDebugSession(sessionId);
}
}));
this.toDispose.pushAll([
Disposable.create(() => this.delegated.dispose()),
Disposable.create(() => {
for (const sessionId of this.sessionId2contrib.keys()) {
const contrib = this.sessionId2contrib.get(sessionId)!;
contrib.terminateDebugSession(sessionId);
}
this.sessionId2contrib.clear();
})]);
}

registerDebugAdapterContribution(contrib: PluginDebugAdapterContribution): Disposable {
Expand Down Expand Up @@ -99,14 +104,9 @@ export class PluginDebugService implements DebugService, PluginDebugAdapterContr
async resolveDebugConfiguration(config: DebugConfiguration, workspaceFolderUri: string | undefined): Promise<DebugConfiguration> {
let resolved = config;

for (const contributor of this.contributors.values()) {
if (contributor.resolveDebugConfiguration) {
try {
resolved = await contributor.resolveDebugConfiguration(config, workspaceFolderUri) || resolved;
} catch (e) {
console.error(e);
}
}
const contributor = this.contributors.get(config.type);
if (contributor && contributor.resolveDebugConfiguration) {
resolved = await contributor.resolveDebugConfiguration(resolved, workspaceFolderUri) || resolved;
}

return this.delegated.resolveDebugConfiguration(resolved, workspaceFolderUri);
Expand Down
9 changes: 3 additions & 6 deletions packages/plugin-ext/src/main/browser/main-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,15 @@ export function setUpPluginApi(rpc: RPCProtocol, container: interfaces.Container
const storageMain = new StorageMainImpl(container);
rpc.set(PLUGIN_RPC_CONTEXT.STORAGE_MAIN, storageMain);

const pluginConnection = new ConnectionMainImpl(rpc);
rpc.set(PLUGIN_RPC_CONTEXT.CONNECTION_MAIN, pluginConnection);
const connectionMain = new ConnectionMainImpl(rpc);
rpc.set(PLUGIN_RPC_CONTEXT.CONNECTION_MAIN, connectionMain);

const tasksMain = new TasksMainImpl(rpc, container);
rpc.set(PLUGIN_RPC_CONTEXT.TASKS_MAIN, tasksMain);

const languagesContribution = new LanguagesContributionMainImpl(rpc, container, pluginConnection);
const languagesContribution = new LanguagesContributionMainImpl(rpc, container, connectionMain);
rpc.set(PLUGIN_RPC_CONTEXT.LANGUAGES_CONTRIBUTION_MAIN, languagesContribution);

const connectionMain = new ConnectionMainImpl(rpc);
rpc.set(PLUGIN_RPC_CONTEXT.CONNECTION_MAIN, connectionMain);

const debugMain = new DebugMainImpl(rpc, connectionMain, container);
rpc.set(PLUGIN_RPC_CONTEXT.DEBUG_MAIN, debugMain);
}
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {

bind(PluginDebugService).toSelf().inSingletonScope();
rebind(DebugService).toService(PluginDebugService);

bind(PluginDebugSessionContributionRegistry).toSelf().inSingletonScope();
rebind(DebugSessionContributionRegistry).toService(PluginDebugSessionContributionRegistry);
});
Loading