提交 dfeffb55 编写于 作者: A Andre Weinand

properly register debug types

上级 b8df1293
......@@ -6,7 +6,7 @@
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
import uri from 'vs/base/common/uri';
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable, ITerminalLauncher, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug';
import { IDebugService, IConfig, IDebugConfigurationProvider, IBreakpoint, IFunctionBreakpoint, IBreakpointData, IAdapterExecutable, ITerminalSettings, IDebugAdapter } from 'vs/workbench/parts/debug/common/debug';
import { TPromise } from 'vs/base/common/winjs.base';
import {
ExtHostContext, ExtHostDebugServiceShape, MainThreadDebugServiceShape, DebugSessionUUID, MainContext,
......@@ -24,8 +24,7 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape {
private _proxy: ExtHostDebugServiceShape;
private _toDispose: IDisposable[];
private _breakpointEventsActive: boolean;
private _debugAdapters: Map<number, ExtensionHostDebugAdapter>;
private _debugAdaptersHandleCounter = 1;
private _extensionHostDebugAdapterProvider: ExtensionHostDebugAdapterProvider;
constructor(
extHostContext: IExtHostContext,
......@@ -52,20 +51,11 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape {
}
}));
this._debugAdapters = new Map<number, ExtensionHostDebugAdapter>();
// register a default EH DA provider
debugService.getConfigurationManager().registerDebugAdapterProvider('*', {
createDebugAdapter: (debugType, adapterInfo) => {
const handle = this._debugAdaptersHandleCounter++;
const da = new ExtensionHostDebugAdapter(handle, this._proxy, debugType, adapterInfo);
this._debugAdapters.set(handle, da);
return da;
}
});
this._extensionHostDebugAdapterProvider = new ExtensionHostDebugAdapterProvider(this._proxy);
}
// register a default EH terminal launcher
debugService.getConfigurationManager().registerEHTerminalLauncher(new ExtensionHostTerminalLauncher(this._proxy));
public $registerDebugTypes(debugTypes: string[]) {
this._toDispose.push(this.debugService.getConfigurationManager().registerDebugAdapterProvider(debugTypes, this._extensionHostDebugAdapterProvider));
}
public dispose(): void {
......@@ -237,15 +227,15 @@ export class MainThreadDebugService implements MainThreadDebugServiceShape {
}
});
this._debugAdapters.get(handle).acceptMessage(message);
this._extensionHostDebugAdapterProvider.acceptMessage(handle, message);
}
public $acceptDAError(handle: number, name: string, message: string, stack: string) {
this._debugAdapters.get(handle).fireError(handle, new Error(`${name}: ${message}\n${stack}`));
this._extensionHostDebugAdapterProvider.acceptDAError(handle, new Error(`${name}: ${message}\n${stack}`));
}
public $acceptDAExit(handle: number, code: number, signal: string) {
this._debugAdapters.get(handle).fireExit(handle, code, signal);
this._extensionHostDebugAdapterProvider.acceptDAExit(handle, code, signal);
}
}
......@@ -285,9 +275,32 @@ class ExtensionHostDebugAdapter extends AbstractDebugAdapter {
}
}
class ExtensionHostTerminalLauncher implements ITerminalLauncher {
class ExtensionHostDebugAdapterProvider {
private _debugAdapters: Map<number, ExtensionHostDebugAdapter>;
private _debugAdaptersHandleCounter = 1;
constructor(private _proxy: ExtHostDebugServiceShape) {
this._debugAdapters = new Map<number, ExtensionHostDebugAdapter>();
}
acceptMessage(handle: number, message: DebugProtocol.ProtocolMessage) {
this._debugAdapters.get(handle).acceptMessage(message);
}
acceptDAError(handle: number, error: Error) {
this._debugAdapters.get(handle).fireError(handle, error);
}
acceptDAExit(handle: number, code: number, signal: string) {
this._debugAdapters.get(handle).fireExit(handle, code, signal);
}
createDebugAdapter(debugType: string, adapterInfo): IDebugAdapter {
const handle = this._debugAdaptersHandleCounter++;
const da = new ExtensionHostDebugAdapter(handle, this._proxy, debugType, adapterInfo);
this._debugAdapters.set(handle, da);
return da;
}
runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
......
......@@ -463,6 +463,7 @@ export interface MainThreadSCMShape extends IDisposable {
export type DebugSessionUUID = string;
export interface MainThreadDebugServiceShape extends IDisposable {
$registerDebugTypes(debugTypes: string[]);
$acceptDAMessage(handle: number, message: DebugProtocol.ProtocolMessage);
$acceptDAError(handle: number, name: string, message: string, stack: string);
$acceptDAExit(handle: number, code: number, signal: string);
......
......@@ -19,7 +19,7 @@ import { generateUuid } from 'vs/base/common/uuid';
import { DebugAdapter, convertToVSCPaths, convertToDAPaths } from 'vs/workbench/parts/debug/node/debugAdapter';
import * as paths from 'vs/base/common/paths';
import { ExtHostExtensionService } from 'vs/workbench/api/node/extHostExtensionService';
import { IAdapterExecutable, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug';
import { IAdapterExecutable, ITerminalSettings, IDebuggerContribution } from 'vs/workbench/parts/debug/common/debug';
import { getTerminalLauncher } from 'vs/workbench/parts/debug/node/terminals';
......@@ -81,10 +81,33 @@ export class ExtHostDebugService implements ExtHostDebugServiceShape {
this._breakpointEventsActive = false;
this._debugAdapters = new Map<number, DebugAdapter>();
// register all debug extensions
const debugTypes: string[] = [];
for (const ed of this._extensionService.getAllExtensionDescriptions()) {
if (ed.contributes) {
const debuggers = <IDebuggerContribution[]>ed.contributes['debuggers'];
if (debuggers && debuggers.length > 0) {
for (const dbg of debuggers) {
// only debugger contributions with a "label" are considered a "main" debugger contribution
if (dbg.type && dbg.label) {
debugTypes.push(dbg.type);
}
}
}
}
}
if (debugTypes.length > 0) {
this._debugServiceProxy.$registerDebugTypes(debugTypes);
}
}
public $runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
return getTerminalLauncher().runInTerminal(args, config);
const terminalLauncher = getTerminalLauncher();
if (terminalLauncher) {
return terminalLauncher.runInTerminal(args, config);
}
return void 0;
}
public $startDASession(handle: number, debugType: string, adpaterExecutable: IAdapterExecutable | null): TPromise<void> {
......
......@@ -394,7 +394,7 @@ export interface IDebugAdapter extends IDisposable {
stopSession(): TPromise<void>;
}
export interface IDebugAdapterProvider {
export interface IDebugAdapterProvider extends ITerminalLauncher {
createDebugAdapter(debugType: string, adapterInfo: IAdapterExecutable | null): IDebugAdapter;
}
......@@ -496,11 +496,9 @@ export interface IConfigurationManager {
resolveConfigurationByProviders(folderUri: uri | undefined, type: string | undefined, debugConfiguration: any): TPromise<any>;
debugAdapterExecutable(folderUri: uri | undefined, type: string): TPromise<IAdapterExecutable | undefined>;
registerDebugAdapterProvider(debugType: string, debugAdapterLauncher: IDebugAdapterProvider);
createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable | null): IDebugAdapter;
registerEHTerminalLauncher(launcher: ITerminalLauncher): void;
runInTerminal(extensionHost: boolean, args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void>;
registerDebugAdapterProvider(debugTypes: string[], debugAdapterLauncher: IDebugAdapterProvider): IDisposable;
createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable | null): IDebugAdapter | undefined;
runInTerminal(debugType: string, args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void>;
}
export interface ILaunch {
......
......@@ -26,7 +26,7 @@ import { IFileService } from 'vs/platform/files/common/files';
import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/platform/workspace/common/workspace';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ICommandService } from 'vs/platform/commands/common/commands';
import { IDebugConfigurationProvider, IDebuggerContribution, ICompound, IDebugConfiguration, IConfig, IEnvConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter, ITerminalLauncher, ITerminalSettings } from 'vs/workbench/parts/debug/common/debug';
import { IDebugConfigurationProvider, IDebuggerContribution, ICompound, IDebugConfiguration, IConfig, IEnvConfig, IGlobalConfig, IConfigurationManager, ILaunch, IAdapterExecutable, IDebugAdapterProvider, IDebugAdapter, ITerminalSettings, ITerminalLauncher } from 'vs/workbench/parts/debug/common/debug';
import { Debugger } from 'vs/workbench/parts/debug/node/debugger';
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen';
......@@ -231,8 +231,7 @@ export class ConfigurationManager implements IConfigurationManager {
private _onDidSelectConfigurationName = new Emitter<void>();
private providers: IDebugConfigurationProvider[];
private debugAdapterProviders: Map<string, IDebugAdapterProvider>;
private _terminalLauncher: ITerminalLauncher;
private _ehTerminalLauncher: ITerminalLauncher;
private terminalLauncher: ITerminalLauncher;
constructor(
......@@ -266,10 +265,10 @@ export class ConfigurationManager implements IConfigurationManager {
debugConfigurationProvider.handle = handle;
this.providers = this.providers.filter(p => p.handle !== handle);
this.providers.push(debugConfigurationProvider);
const adapter = this.getDebugger(debugConfigurationProvider.type);
const dbg = this.getDebugger(debugConfigurationProvider.type);
// Check if the provider contributes provideDebugConfigurations method
if (adapter && debugConfigurationProvider.provideDebugConfigurations) {
adapter.hasConfigurationProvider = true;
if (dbg && debugConfigurationProvider.provideDebugConfigurations) {
dbg.hasConfigurationProvider = true;
}
}
......@@ -306,32 +305,37 @@ export class ConfigurationManager implements IConfigurationManager {
return TPromise.as(undefined);
}
public registerDebugAdapterProvider(debugType: string, debugAdapterLauncher: IDebugAdapterProvider) {
this.debugAdapterProviders.set(debugType, debugAdapterLauncher);
public registerDebugAdapterProvider(debugTypes: string[], debugAdapterLauncher: IDebugAdapterProvider): IDisposable {
debugTypes.forEach(debugType => this.debugAdapterProviders.set(debugType, debugAdapterLauncher));
return {
dispose: () => {
debugTypes.forEach(debugType => this.debugAdapterProviders.delete(debugType));
}
};
}
public createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable): IDebugAdapter {
let dap = this.debugAdapterProviders.get(debugType);
if (!dap) {
dap = this.debugAdapterProviders.get('*');
}
return dap.createDebugAdapter(debugType, adapterExecutable);
private getDebugAdapterProvider(type: string): IDebugAdapterProvider | undefined {
return this.debugAdapterProviders.get(type);
}
public registerEHTerminalLauncher(launcher: ITerminalLauncher): void {
this._ehTerminalLauncher = launcher;
public createDebugAdapter(debugType: string, adapterExecutable: IAdapterExecutable): IDebugAdapter | undefined {
let dap = this.getDebugAdapterProvider(debugType);
if (dap) {
return dap.createDebugAdapter(debugType, adapterExecutable);
}
return undefined;
}
public runInTerminal(extensionHost: boolean, args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
public runInTerminal(debugType: string, args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
if (extensionHost && this._ehTerminalLauncher) {
return this._ehTerminalLauncher.runInTerminal(args, config);
} else {
if (!this._terminalLauncher) {
this._terminalLauncher = this.instantiationService.createInstance(TerminalLauncher);
let tl: ITerminalLauncher = this.getDebugAdapterProvider(debugType);
if (!tl) {
if (!this.terminalLauncher) {
this.terminalLauncher = this.instantiationService.createInstance(TerminalLauncher);
}
return this._terminalLauncher.runInTerminal(args, config);
tl = this.terminalLauncher;
}
return tl.runInTerminal(args, config);
}
private registerListeners(lifecycleService: ILifecycleService): void {
......
......@@ -249,7 +249,7 @@ export class DebugAdapter extends StreamDebugAdapter {
"Cannot determine executable for debug adapter '{0}'.", this._debugType)));
}
if (this._adapterExecutable.command === 'node' /*&& this.outputService*/) {
if (this._adapterExecutable.command === 'node' && this._outputService) {
if (Array.isArray(this._adapterExecutable.args) && this._adapterExecutable.args.length > 0) {
stdfork.fork(this._adapterExecutable.args[0], this._adapterExecutable.args.slice(1), {}, (err, child) => {
if (err) {
......
......@@ -62,7 +62,8 @@ export class Debugger {
public runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments): TPromise<void> {
const debugConfigs = this.configurationService.getValue<IDebugConfiguration>('debug');
const config = this.configurationService.getValue<ITerminalSettings>('terminal');
return this.configurationManager.runInTerminal(debugConfigs && debugConfigs.extensionHostDebugAdapter, args, config);
const type = debugConfigs.extensionHostDebugAdapter ? this.type : '*';
return this.configurationManager.runInTerminal(type, args, config);
}
public get aiKey(): string {
......
......@@ -64,14 +64,14 @@ let _DEFAULT_TERMINAL_WINDOWS: string = null;
export function getDefaultTerminalWindows(): string {
if (!_DEFAULT_TERMINAL_WINDOWS) {
const isWoW64 = !!process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
_DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
_DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:\\Windows'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
}
return _DEFAULT_TERMINAL_WINDOWS;
}
abstract class TerminalLauncher implements ITerminalLauncher {
public runInTerminal(args: DebugProtocol.RunInTerminalRequestArguments, config: ITerminalSettings): TPromise<void> {
return this.runInTerminal0(args.title, args.cwd, args.args, args.env, config);
return this.runInTerminal0(args.title, args.cwd, args.args, args.env || {}, config);
}
runInTerminal0(title: string, dir: string, args: string[], envVars: env.IProcessEnvironment, config): TPromise<void> {
return void 0;
......
......@@ -43,7 +43,7 @@ let _DEFAULT_TERMINAL_WINDOWS: string = null;
export function getDefaultTerminalWindows(): string {
if (!_DEFAULT_TERMINAL_WINDOWS) {
const isWoW64 = !!process.env.hasOwnProperty('PROCESSOR_ARCHITEW6432');
_DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
_DEFAULT_TERMINAL_WINDOWS = `${process.env.windir ? process.env.windir : 'C:\\Windows'}\\${isWoW64 ? 'Sysnative' : 'System32'}\\cmd.exe`;
}
return _DEFAULT_TERMINAL_WINDOWS;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册