-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
Plugin API for debug #3804
Plugin API for debug #3804
Conversation
8d6d29b
to
d289124
Compare
.vscode/launch.json
Outdated
@@ -4,6 +4,7 @@ | |||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | |||
"version": "0.2.0", | |||
"configurations": [ | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove this useless change ?
@@ -97,7 +96,7 @@ export abstract class AbstractVSCodeDebugAdapterContribution implements DebugAda | |||
} | |||
|
|||
protected async parse(): Promise<VSCodeExtensionPackage> { | |||
let text = (await fs.readFile(this.pckPath)).toString(); | |||
let text = (await fs.readFileSync(this.pckPath)).toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hello, quick question: why fs-extra/readFile has been replaced by fs/readFileSync ?
} | ||
|
||
get onDidReceiveDebugSessionCustomEvent(): theia.Event<theia.DebugSessionCustomEvent> { | ||
throw new Error('Debug API works only in plugin container'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe call a method that throw this message everywhere ? or to use a proxy instead as all methods are throwing errors ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What are the benefits?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if new methods are added, then proxy will always be up-to-date and it's avoid 100 exact same lines
constructor(rpc: RPCProtocol) { | ||
this.proxy = rpc.getProxy(Ext.COMMAND_REGISTRY_MAIN); | ||
this.converter = new CommandsConverter(this); | ||
|
||
// register internal VS Code commands |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c++ extension use this command to show release notes.
We need to register this command at least with fake handler.
If you have any suggestion you are welcome.
@@ -50,6 +56,7 @@ export class CommandRegistryImpl implements CommandRegistryExt { | |||
this.proxy.$registerCommand(command); | |||
|
|||
return Disposable.create(() => { | |||
this.commands.delete(command.id); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't have to keep command if it is disposed.
some extension (c++ in particular) register/dispose/register the same commands.
If we don't delete command we will fail.
packages/plugin/src/theia.d.ts
Outdated
* @param nameOrConfiguration Either the name of a debug or compound configuration or a [DebugConfiguration](#DebugConfiguration) object. | ||
* @return A thenable that resolves when debugging could be successfully started. | ||
*/ | ||
export function startDebugging(folder: WorkspaceFolder | undefined, nameOrConfiguration: string | DebugConfiguration): Thenable<boolean>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromiseLike
packages/plugin/src/theia.d.ts
Outdated
* @param key A string. | ||
* @param value A value. MUST not contain cyclic references. | ||
*/ | ||
update(key: string, value: any): Thenable<void>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromiseLike
throw new Error('Debug API works only in plugin container'); | ||
} | ||
|
||
startDebugging(folder: theia.WorkspaceFolder | undefined, nameOrConfiguration: string | theia.DebugConfiguration): Thenable<boolean> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromiseLike
this.proxy.$removeBreakpoints(breakpoints); | ||
} | ||
|
||
startDebugging(folder: theia.WorkspaceFolder | undefined, nameOrConfiguration: string | theia.DebugConfiguration): Thenable<boolean> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromiseLike
return value || defaultValue; | ||
} | ||
|
||
update(key: string, value: T): Thenable<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PromiseLike
/** | ||
* Describes what plugin contribution has to provide for a client. | ||
*/ | ||
export interface DebugPluginContributor { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
debug extension should not have notion of plugins
plugins should be encapsulated into @theia/plugin-ext
import { WebSocketChannel } from '@theia/core/lib/common/messaging/web-socket-channel'; | ||
import { DebugConfiguration } from '../common/debug-configuration'; | ||
import { IJSONSchema, IJSONSchemaSnippet } from '@theia/core/lib/common/json-schema'; | ||
import { Disposable } from '@theia/core/lib/common/disposable'; | ||
import { MaybePromise } from '@theia/core/src/common/types'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
always import from lib
|
||
export const INSPECTOR_PORT_DEFAULT = 9229; | ||
export const LEGACY_PORT_DEFAULT = 5858; | ||
|
||
@injectable() | ||
export class NodeDebugAdapterContribution extends AbstractVSCodeDebugAdapterContribution { | ||
export class NodeDebugAdapterContribution implements DebugAdapterContribution { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you elaborate why it cannot extend VSCodeDebugAdapterContribution
? the same for node2 and java
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In case of extension I have to use inversify.
But in this case I can't use it in plugin-ext
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think VsCodePluginScanner
should be improved to handle vscode extension localization generally and support debugger relevant contributions. The plugin extension then should use PluginModel
to provide DebugAdapterContribution
. Maybe some code should be copied there from VSCodeDebugAdapterContribution
to achieve it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akosyakov resolved
2aa725a
protected readonly debugPreferences: DebugPreferences; | ||
|
||
protected readonly onDidContributionAddEmitter = new Emitter<string>(); | ||
readonly onDidContributionAdd: Event<string> = this.onDidContributionAddEmitter.event; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the pattern is on[Will|Did]VerbNoun?
- https://code.visualstudio.com/docs/extensionAPI/patterns-and-principles#_events
* Session factory for a client debug session that communicates with debug adapter contributed as plugin. | ||
* The main difference is to use a connection factory that creates [IWebSocket](#IWebSocket) over Rpc channel. | ||
*/ | ||
class PluginDebugSessionFactory implements DebugSessionFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a class should go to its own file, a file name should be a class name
we try not to put several classes in one file with a random name, also we try to avoid classes with the same name in the repo
it is to easy navigation
It introduces implicit dependencies from the debug to the plugin extension. Dependencies should be only in on direction from the plugin to debug extension. The debug extension should not have notion of plugins or plugin contributions. The plugin extension can rebind and customize services from the debug extension to add this notion. |
Functional-wise, after battling with g++/gdb I was able to run it eventually :) It works for me nicely and I did not find any breaking behavior changes. |
} | ||
|
||
async resolveDebugConfiguration(config: DebugConfiguration, workspaceFolderUri: string | undefined): Promise<DebugConfiguration> { | ||
const contributor = this.pluginContributors.get(config.type); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is bogus, all debug providers should participate in the resolution of any DebugConfiguration
, regardless of whether they come from extensions or plugins. Like in DebugAdapterContributionRegistry.resolveDebugConfiguration
. I think the whole integration should happen behind DebugService
on the level of debug adapter contributions that the code in DebugService
and DebugAdapterContributionRegistry
is reused.
} | ||
} | ||
|
||
class DebugPluginContribution extends VSCodeDebugAdapterContribution { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it looks strange, plugins should not rely on VSCodeDebugAdapterContribution
from the debug extension, but should read metadata from plugins, the same way as metadata for commands and menu items and so on, read by the plugin extension.
I hoped that this PR will fix #3771 (comment) by improving localization of metadata from VS Code extensions.
@akosyakov I've addressed all your remarks. |
2aa725a
to
a805e75
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, whatever Anton's concern was can be fixed after merge as well. There is . a missing ,
in plugin-api.ts
and would be good if you could squash the commits.
385dd3f
to
45dfe07
Compare
Signed-off-by: Anatoliy Bazko <abazko@redhat.com>
6dd99d0
to
c20b224
Compare
This PR provides implementation of plugin API for debug
How to test
~/theia-plugins
folder.THEIA_DEFAULT_PLUGINS="local-dir:///home/$USER/theia-plugins"
Prepare test file
-g
option, for instance:g++ -g test.c++
"program": "${workspaceFolder}/a.out"
"stopAtEntry": true
Know issues
1 . Debug adapter sends events in such sequence: 'exited', 'terminated', 'telemetry'.
Since we dispose `debug-session-connection' on 'exited' event we can see some traces in console: