Skip to content

Commit

Permalink
act-on-terminal-support
Browse files Browse the repository at this point in the history
Signed-off-by: Antoine Tremblay <antoine.tremblay@ericsson.com>
  • Loading branch information
Antoine Tremblay committed Jul 17, 2017
1 parent 0b8c88d commit 587c279
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 55 deletions.
26 changes: 22 additions & 4 deletions src/debug/node/debug-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import { ContainerModule, interfaces } from 'inversify';
import { IDebugSession, IDebugSessionFactory, DebugSession } from './debug-session';
/* FIXME this should be done another way, binding/unbinding rather then a factory? */
import { GDBDebugSession } from '../../gdb/node/gdb-debug-session';
// import { DebugRawProcess } from './debug-raw-process'
import { IDebugProcess } from './debug-process'
import { GDBProbe } from '../../gdb/node/gdb-probe';

import { DebugRawProcess } from './debug-raw-process'
import { IDebugProcessProvider, IDebugProcess } from './debug-process'
import { DebugTerminalProcess } from './debug-terminal-process';
import { DebugSessionManager } from './debug-session-manager';

Expand All @@ -27,7 +29,23 @@ export default new ContainerModule(bind => {
});
bind<IDebugSession>(IDebugSession).to(GDBDebugSession).whenTargetNamed('GDB');
bind<IDebugSession>(IDebugSession).to(DebugSession).whenTargetIsDefault();
bind<IDebugProcess>(IDebugProcess).to(DebugTerminalProcess);
bind<IDebugProcess>(DebugTerminalProcess).toSelf();
bind<IDebugProcessProvider>(IDebugProcessProvider).toProvider<IDebugProcess>((context) => {
return () => {
return new Promise<IDebugProcess>((resolve) => {
const probe = context.container.get<GDBProbe>(GDBProbe);
probe.probeCommand("new-ui").then(result => {
if (result === true) {
resolve(context.container.get<IDebugProcess>(DebugTerminalProcess));
} else {
resolve(context.container.get<IDebugProcess>(DebugRawProcess));
}
})
});
}
});
bind<DebugTerminalProcess>(DebugTerminalProcess).toSelf();
bind<DebugRawProcess>(DebugRawProcess).toSelf();
bind<DebugSessionManager>(DebugSessionManager).toSelf().inSingletonScope();
// FIXME should not be here
bind<GDBProbe>(GDBProbe).toSelf().inSingletonScope();
});
2 changes: 2 additions & 0 deletions src/debug/node/debug-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import * as events from 'events';

export const IDebugProcess = "IDebugProcess";
export const IDebugProcessProvider = "IDebugProcessProvider";
export type IDebugProcessProvider = () => Promise<IDebugProcess>;

export interface IDebugProcess extends events.EventEmitter {
readStream: NodeJS.ReadableStream;
Expand Down
2 changes: 1 addition & 1 deletion src/debug/node/debug-raw-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export class DebugRawProcess extends events.EventEmitter implements IDebugProces
this.path = new Path(path);
this.args = args.split(' ');

this.logger.info(`Starting debugger from: ${this.path.toString()}, with args: ${JSON.stringify(this.args)}`);
this.logger.info(`RAW: Starting debugger from: ${this.path.toString()}, with args: ${JSON.stringify(this.args)}`);
this.process = child.spawn(this.path.toString(), this.args);
this.readStream = this.process.stdout;
this.writeStream = this.process.stdin;
Expand Down
4 changes: 2 additions & 2 deletions src/debug/node/debug-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class DebugSession implements IDebugSession {
public start(options: object): void {
}

public getTerminal(): any {
return undefined;
public getTerminal(): Promise<any> {
return Promise.resolve(undefined);
}
}
38 changes: 20 additions & 18 deletions src/debug/node/debug-terminal-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,29 +69,31 @@ export class DebugTerminalExpressContribution implements BackendApplicationContr
if (!session || !session.getTerminal()) {
return;
}
const term = session.getTerminal();
const termPromise: Promise<any> = session.getTerminal();

const onData = (data: any) => {
try {
ws.send(data)
} catch (ex) {
console.error(ex)
termPromise.then(term => {
const onData = (data: any) => {
try {
ws.send(data)
} catch (ex) {
console.error(ex)
}
}
}

term.on('data', onData);
term.on('data', onData);

ws.on('message', (msg: any) => {
term.write(msg)
})
ws.on('close', (msg: any) => {
term.removeListener('data', onData);
ws.on('message', (msg: any) => {
term.write(msg)
})
ws.on('close', (msg: any) => {
term.removeListener('data', onData);

/* The debug session lifecycle should be the trigger
debugTerm.process.kill()
this.registry.delete(id)
*/
})
/* The debug session lifecycle should be the trigger
debugTerm.process.kill()
this.registry.delete(id)
*/
})
});
})
}
}
2 changes: 1 addition & 1 deletion src/debug/node/debug-terminal-process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export class DebugTerminalProcess extends events.EventEmitter implements IDebugP
this.args.push('-iex');
this.args.push('set pagination off');

this.logger.info(`Starting debugger from: ${this.path.toString()}, with args: ${JSON.stringify(this.args)}`);
this.logger.info(`TERMINAL: Starting debugger from: ${this.path.toString()}, with args: ${JSON.stringify(this.args)}`);
this.terminal = pty.spawn(this.path.toString(), this.args, {
name: 'xterm-color',
cols: 80,
Expand Down
3 changes: 1 addition & 2 deletions src/gdb/node/gdb-backend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import {
IMIDebugger, MIDebugger, MIInterpreter,
IMIParser, MIParser, MIOutputParser
} from './mi';
import { GDBProbe } from './gdb-probe';
// import { GDBProbe } from './gdb-probe';
import { bindGDBPreferences } from './gdb-preferences'

export default new ContainerModule(bind => {
Expand All @@ -19,5 +19,4 @@ export default new ContainerModule(bind => {
bind<MIInterpreter>(MIInterpreter).to(MIInterpreter);
bind<IMIParser>(IMIParser).to(MIParser);
bind<MIOutputParser>(MIOutputParser).toSelf();
bind<GDBProbe>(GDBProbe).toSelf().inSingletonScope();
});
2 changes: 1 addition & 1 deletion src/gdb/node/gdb-debug-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class GDBDebugSession extends DebugSession {
});
}

public getTerminal(): any {
public getTerminal(): Promise<any> {
return this.miDebugger.getTerminal();
}
}
59 changes: 33 additions & 26 deletions src/gdb/node/mi/mi-debugger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
import { injectable, inject } from 'inversify';
import { MIInterpreter } from './mi-interpreter'
import { MIProtocol as MI } from './mi-protocol';
import { IDebugProcess } from '../../../debug/node/debug-process'
import { IDebugProcess, IDebugProcessProvider } from '../../../debug/node/debug-process'
import { ILogger, Path } from '../../../application/common';

export const IMIDebugger = Symbol("IMIDebugger");

export interface IMIDebugger {
start(options: IMIDebuggerOptions): Promise<any>;
getTerminal(): any;
getTerminal(): Promise<any>;
}

export interface IMIDebuggerOptions {
Expand All @@ -32,42 +32,49 @@ export enum ProcessState {
@injectable()
export class MIDebugger implements IMIDebugger {

protected readonly debugProcess: Promise<IDebugProcess>;

constructor(
@inject(MIInterpreter) protected readonly interpreter: MIInterpreter,
@inject(IDebugProcess) protected readonly rawProcess: IDebugProcess,
@inject(IDebugProcessProvider) protected readonly debugProcessProvider: IDebugProcessProvider,
@inject(ILogger) protected readonly logger: ILogger) {
this.debugProcess = this.debugProcessProvider();
}

spawn(path: string, args: string): Promise<any> {
return new Promise((resolve, reject) => {
this.rawProcess.spawn(path, args);
this.rawProcess.on('error', (err: Error) => {
reject(err)
});
this.rawProcess.on('exit', (code: number, signal: string) => {
if (code > 0) {
reject(new Error(`Exited with code: ${code}`));
}
});
this.debugProcess.then(process => {
process.spawn(path, args);
process.on('error', (err: Error) => {
reject(err)
});
process.on('exit', (code: number, signal: string) => {
if (code > 0) {
reject(new Error(`Exited with code: ${code}`));
}
});

this.interpreter.start(this.rawProcess.readStream, this.rawProcess.writeStream);
this.interpreter.once('NotifyAsyncOutput', (input: any) => {
resolve(input);
this.interpreter.start(process.readStream, process.writeStream);
this.interpreter.once('NotifyAsyncOutput', (input: any) => {
resolve(input);
});
});
});
}

start(options: IMIDebuggerOptions): Promise<any> {
let p = new Promise((resolve, reject) => {
this.spawn(options.path.toString(), options.args).then(() => {
this.rawProcess.on('exit', (code: number, signal: string) => { this.onProcessExit(code, signal) });
/* Send command to list capabilities */
let command = new MI.MICommand('list-features');
this.interpreter.sendCommand(command).then((result: MI.ResultRecord) => {
this.logger.debug(`Initialize got GDB features ResultRecord: ${JSON.stringify(result)}`);
resolve(result);
});
}).catch((error) => { reject(error) });
this.debugProcess.then(process => {
this.spawn(options.path.toString(), options.args).then(() => {
process.on('exit', (code: number, signal: string) => { this.onProcessExit(code, signal) });
/* Send command to list capabilities */
let command = new MI.MICommand('list-features');
this.interpreter.sendCommand(command).then((result: MI.ResultRecord) => {
this.logger.debug(`Initialize got GDB features ResultRecord: ${JSON.stringify(result)}`);
resolve(result);
});
}).catch((error) => { reject(error) });
});
});
return p;
}
Expand All @@ -84,7 +91,7 @@ export class MIDebugger implements IMIDebugger {

}

public getTerminal(): any {
return this.rawProcess.terminal;
public getTerminal(): Promise<any> {
return new Promise((resolve) => this.debugProcess.then(process => process.terminal));
}
}

0 comments on commit 587c279

Please sign in to comment.