-
-
Notifications
You must be signed in to change notification settings - Fork 397
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: patched the Theia debug functionality
Patch for: - eclipse-theia/theia#11871 - eclipse-theia/theia#11879 - eclipse-theia/theia#11880 - eclipse-theia/theia#11885 - eclipse-theia/theia#11886 - eclipse-theia/theia#11916 Closes #1582 Signed-off-by: Akos Kitta <[email protected]>
- Loading branch information
Showing
15 changed files
with
895 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import '../../src/browser/style/index.css'; | ||
import { ContainerModule } from '@theia/core/shared/inversify'; | ||
import { Container, ContainerModule } from '@theia/core/shared/inversify'; | ||
import { WidgetFactory } from '@theia/core/lib/browser/widget-manager'; | ||
import { CommandContribution } from '@theia/core/lib/common/command'; | ||
import { bindViewContribution } from '@theia/core/lib/browser/shell/view-contribution'; | ||
|
@@ -331,6 +331,18 @@ import { TypeHierarchyServiceProvider } from './theia/typehierarchy/type-hierarc | |
import { TypeHierarchyServiceProvider as TheiaTypeHierarchyServiceProvider } from '@theia/typehierarchy/lib/browser/typehierarchy-service'; | ||
import { TypeHierarchyContribution } from './theia/typehierarchy/type-hierarchy-contribution'; | ||
import { TypeHierarchyContribution as TheiaTypeHierarchyContribution } from '@theia/typehierarchy/lib/browser/typehierarchy-contribution'; | ||
import { DefaultDebugSessionFactory } from './theia/debug/debug-session-contribution'; | ||
import { DebugSessionFactory } from '@theia/debug/lib/browser/debug-session-contribution'; | ||
import { DebugToolbar } from './theia/debug/debug-toolbar-widget'; | ||
import { DebugToolBar as TheiaDebugToolbar } from '@theia/debug/lib/browser/view/debug-toolbar-widget'; | ||
import { PluginMenuCommandAdapter } from './theia/plugin-ext/plugin-menu-command-adapter'; | ||
import { PluginMenuCommandAdapter as TheiaPluginMenuCommandAdapter } from '@theia/plugin-ext/lib/main/browser/menus/plugin-menu-command-adapter'; | ||
import { DebugSessionManager } from './theia/debug/debug-session-manager'; | ||
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager'; | ||
import { DebugWidget } from '@theia/debug/lib/browser/view/debug-widget'; | ||
import { DebugViewModel } from '@theia/debug/lib/browser/view/debug-view-model'; | ||
import { DebugSessionWidget } from '@theia/debug/lib/browser/view/debug-session-widget'; | ||
import { DebugConfigurationWidget } from '@theia/debug/lib/browser/view/debug-configuration-widget'; | ||
|
||
export default new ContainerModule((bind, unbind, isBound, rebind) => { | ||
// Commands and toolbar items | ||
|
@@ -960,4 +972,36 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => { | |
); | ||
bind(TypeHierarchyContribution).toSelf().inSingletonScope(); | ||
rebind(TheiaTypeHierarchyContribution).toService(TypeHierarchyContribution); | ||
|
||
// patched the debugger for `[email protected]` | ||
// https://github.com/eclipse-theia/theia/issues/11871 | ||
// https://github.com/eclipse-theia/theia/issues/11879 | ||
// https://github.com/eclipse-theia/theia/issues/11880 | ||
// https://github.com/eclipse-theia/theia/issues/11885 | ||
// https://github.com/eclipse-theia/theia/issues/11886 | ||
// https://github.com/eclipse-theia/theia/issues/11916 | ||
// based on: https://github.com/eclipse-theia/theia/compare/master...kittaakos:theia:%2311871 | ||
bind(DefaultDebugSessionFactory).toSelf().inSingletonScope(); | ||
rebind(DebugSessionFactory).toService(DefaultDebugSessionFactory); | ||
bind(DebugSessionManager).toSelf().inSingletonScope(); | ||
rebind(TheiaDebugSessionManager).toService(DebugSessionManager); | ||
bind(DebugToolbar).toSelf().inSingletonScope(); | ||
rebind(TheiaDebugToolbar).toService(DebugToolbar); | ||
bind(PluginMenuCommandAdapter).toSelf().inSingletonScope(); | ||
rebind(TheiaPluginMenuCommandAdapter).toService(PluginMenuCommandAdapter); | ||
bind(WidgetFactory) | ||
.toDynamicValue(({ container }) => ({ | ||
id: DebugWidget.ID, | ||
createWidget: () => { | ||
const child = new Container({ defaultScope: 'Singleton' }); | ||
child.parent = container; | ||
child.bind(DebugViewModel).toSelf(); | ||
child.bind(DebugToolbar).toSelf(); // patched toolbar | ||
child.bind(DebugSessionWidget).toSelf(); | ||
child.bind(DebugConfigurationWidget).toSelf(); | ||
child.bind(DebugWidget).toSelf(); | ||
return child.get(DebugWidget); | ||
}, | ||
})) | ||
.inSingletonScope(); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
29 changes: 29 additions & 0 deletions
29
arduino-ide-extension/src/browser/theia/debug/debug-action.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as React from '@theia/core/shared/react'; | ||
import { DebugAction as TheiaDebugAction } from '@theia/debug/lib/browser/view/debug-action'; | ||
import { | ||
codiconArray, | ||
DISABLED_CLASS, | ||
} from '@theia/core/lib/browser/widgets/widget'; | ||
|
||
// customized debug action to show the contributed command's label when there is no icon | ||
export class DebugAction extends TheiaDebugAction { | ||
override render(): React.ReactNode { | ||
const { enabled, label, iconClass } = this.props; | ||
const classNames = ['debug-action', ...codiconArray(iconClass, true)]; | ||
if (enabled === false) { | ||
classNames.push(DISABLED_CLASS); | ||
} | ||
return ( | ||
<span | ||
tabIndex={0} | ||
className={classNames.join(' ')} | ||
title={label} | ||
onClick={this.props.run} | ||
ref={this.setRef} | ||
> | ||
{!iconClass || | ||
(iconClass.match(/plugin-icon-\d+/) && <div>{label}</div>)} | ||
</span> | ||
); | ||
} | ||
} |
49 changes: 49 additions & 0 deletions
49
arduino-ide-extension/src/browser/theia/debug/debug-session-contribution.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { injectable } from '@theia/core/shared/inversify'; | ||
import { DebugSessionConnection } from '@theia/debug/lib/browser/debug-session-connection'; | ||
import { DefaultDebugSessionFactory as TheiaDefaultDebugSessionFactory } from '@theia/debug/lib/browser/debug-session-contribution'; | ||
import { DebugConfigurationSessionOptions } from '@theia/debug/lib/browser/debug-session-options'; | ||
import { | ||
DebugAdapterPath, | ||
DebugChannel, | ||
ForwardingDebugChannel, | ||
} from '@theia/debug/lib/common/debug-service'; | ||
import { DebugSession } from './debug-session'; | ||
|
||
@injectable() | ||
export class DefaultDebugSessionFactory extends TheiaDefaultDebugSessionFactory { | ||
override get( | ||
sessionId: string, | ||
options: DebugConfigurationSessionOptions, | ||
parentSession?: DebugSession | ||
): DebugSession { | ||
const connection = new DebugSessionConnection( | ||
sessionId, | ||
() => | ||
new Promise<DebugChannel>((resolve) => | ||
this.connectionProvider.openChannel( | ||
`${DebugAdapterPath}/${sessionId}`, | ||
(wsChannel) => { | ||
resolve(new ForwardingDebugChannel(wsChannel)); | ||
}, | ||
{ reconnecting: false } | ||
) | ||
), | ||
this.getTraceOutputChannel() | ||
); | ||
// patched debug session | ||
return new DebugSession( | ||
sessionId, | ||
options, | ||
parentSession, | ||
connection, | ||
this.terminalService, | ||
this.editorManager, | ||
this.breakpoints, | ||
this.labelProvider, | ||
this.messages, | ||
this.fileService, | ||
this.debugContributionProvider, | ||
this.workspaceService | ||
); | ||
} | ||
} |
120 changes: 120 additions & 0 deletions
120
arduino-ide-extension/src/browser/theia/debug/debug-session-manager.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import type { ContextKey } from '@theia/core/lib/browser/context-key-service'; | ||
import { injectable, postConstruct } from '@theia/core/shared/inversify'; | ||
import { | ||
DebugSession, | ||
DebugState, | ||
} from '@theia/debug/lib/browser/debug-session'; | ||
import { DebugSessionManager as TheiaDebugSessionManager } from '@theia/debug/lib/browser/debug-session-manager'; | ||
import type { DebugConfigurationSessionOptions } from '@theia/debug/lib/browser/debug-session-options'; | ||
|
||
function debugStateLabel(state: DebugState): string { | ||
switch (state) { | ||
case DebugState.Initializing: | ||
return 'initializing'; | ||
case DebugState.Stopped: | ||
return 'stopped'; | ||
case DebugState.Running: | ||
return 'running'; | ||
default: | ||
return 'inactive'; | ||
} | ||
} | ||
|
||
@injectable() | ||
export class DebugSessionManager extends TheiaDebugSessionManager { | ||
protected debugStateKey: ContextKey<string>; | ||
|
||
@postConstruct() | ||
protected override init(): void { | ||
this.debugStateKey = this.contextKeyService.createKey<string>( | ||
'debugState', | ||
debugStateLabel(this.state) | ||
); | ||
super.init(); | ||
} | ||
|
||
protected override fireDidChange(current: DebugSession | undefined): void { | ||
this.debugTypeKey.set(current?.configuration.type); | ||
this.inDebugModeKey.set(this.inDebugMode); | ||
this.debugStateKey.set(debugStateLabel(this.state)); | ||
this.onDidChangeEmitter.fire(current); | ||
} | ||
|
||
protected override async doStart( | ||
sessionId: string, | ||
options: DebugConfigurationSessionOptions | ||
): Promise<DebugSession> { | ||
const parentSession = | ||
options.configuration.parentSession && | ||
this._sessions.get(options.configuration.parentSession.id); | ||
const contrib = this.sessionContributionRegistry.get( | ||
options.configuration.type | ||
); | ||
const sessionFactory = contrib | ||
? contrib.debugSessionFactory() | ||
: this.debugSessionFactory; | ||
const session = sessionFactory.get(sessionId, options, parentSession); | ||
this._sessions.set(sessionId, session); | ||
|
||
this.debugTypeKey.set(session.configuration.type); | ||
// this.onDidCreateDebugSessionEmitter.fire(session); // defer the didCreate event after start https://github.com/eclipse-theia/theia/issues/11916 | ||
|
||
let state = DebugState.Inactive; | ||
session.onDidChange(() => { | ||
if (state !== session.state) { | ||
state = session.state; | ||
if (state === DebugState.Stopped) { | ||
this.onDidStopDebugSessionEmitter.fire(session); | ||
} | ||
} | ||
this.updateCurrentSession(session); | ||
}); | ||
session.onDidChangeBreakpoints((uri) => | ||
this.fireDidChangeBreakpoints({ session, uri }) | ||
); | ||
session.on('terminated', async (event) => { | ||
const restart = event.body && event.body.restart; | ||
if (restart) { | ||
// postDebugTask isn't run in case of auto restart as well as preLaunchTask | ||
this.doRestart(session, !!restart); | ||
} else { | ||
await session.disconnect(false, () => | ||
this.debug.terminateDebugSession(session.id) | ||
); | ||
await this.runTask( | ||
session.options.workspaceFolderUri, | ||
session.configuration.postDebugTask | ||
); | ||
} | ||
}); | ||
|
||
// eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars | ||
session.on('exited', async (event) => { | ||
await session.disconnect(false, () => | ||
this.debug.terminateDebugSession(session.id) | ||
); | ||
}); | ||
|
||
session.onDispose(() => this.cleanup(session)); | ||
session | ||
.start() | ||
.then(() => { | ||
this.onDidCreateDebugSessionEmitter.fire(session); // now fire the didCreate event | ||
this.onDidStartDebugSessionEmitter.fire(session); | ||
}) | ||
// eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars | ||
.catch((e) => { | ||
session.stop(false, () => { | ||
this.debug.terminateDebugSession(session.id); | ||
}); | ||
}); | ||
session.onDidCustomEvent(({ event, body }) => | ||
this.onDidReceiveDebugSessionCustomEventEmitter.fire({ | ||
event, | ||
body, | ||
session, | ||
}) | ||
); | ||
return session; | ||
} | ||
} |
Oops, something went wrong.