diff options
author | 2023-08-24 22:53:34 -0700 | |
---|---|---|
committer | 2023-08-24 22:53:34 -0700 | |
commit | 1480889205d49cf7221a36608a8896b452967cea (patch) | |
tree | e1427e4041cf19ef1e8e8e0f58cfbbceb4cbbf74 /packages/bun-vscode/src/features/debug.ts | |
parent | f269432d90826ad3e5b66c7685a6e826e0fb05e2 (diff) | |
download | bun-1480889205d49cf7221a36608a8896b452967cea.tar.gz bun-1480889205d49cf7221a36608a8896b452967cea.tar.zst bun-1480889205d49cf7221a36608a8896b452967cea.zip |
Improved support for `debug-adapter-protocol` (#4186)
* Improve support for \`debug-adapter-protocol\`
* More improvements, fix formatting in debug console
* Fix attaching
* Prepare for source maps
* Start of source map support, breakpoints work
* Source map support
* add some package.jsons
* wip
* Update package.json
* More fixes
* Make source maps safer if exception occurs
* Check bun version if it fails
* Fix console.log formatting
* Fix source maps partly
* More source map fixes
* Prepare for extension
* watch mode with dap
* Improve preview code
* Prepare for extension 2
---------
Co-authored-by: Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com>
Diffstat (limited to 'packages/bun-vscode/src/features/debug.ts')
-rw-r--r-- | packages/bun-vscode/src/features/debug.ts | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/packages/bun-vscode/src/features/debug.ts b/packages/bun-vscode/src/features/debug.ts new file mode 100644 index 000000000..3b841ea66 --- /dev/null +++ b/packages/bun-vscode/src/features/debug.ts @@ -0,0 +1,153 @@ +import * as vscode from "vscode"; +import type { CancellationToken, DebugConfiguration, ProviderResult, WorkspaceFolder } from "vscode"; +import type { DAP } from "../../../bun-debug-adapter-protocol"; +import { DebugAdapter } from "../../../bun-debug-adapter-protocol"; +import { DebugSession } from "@vscode/debugadapter"; + +const debugConfiguration: vscode.DebugConfiguration = { + type: "bun", + request: "launch", + name: "Debug Bun", + program: "${file}", + watch: true, +}; + +const runConfiguration: vscode.DebugConfiguration = { + type: "bun", + request: "launch", + name: "Run Bun", + program: "${file}", + watch: true, +}; + +const attachConfiguration: vscode.DebugConfiguration = { + type: "bun", + request: "attach", + name: "Attach to Bun", + url: "ws://localhost:6499/", +}; + +const debugConfigurations: vscode.DebugConfiguration[] = [debugConfiguration, attachConfiguration]; + +export default function (context: vscode.ExtensionContext, factory?: vscode.DebugAdapterDescriptorFactory) { + context.subscriptions.push( + vscode.commands.registerCommand("extension.bun.runFile", (resource: vscode.Uri) => { + let targetResource = resource; + if (!targetResource && vscode.window.activeTextEditor) { + targetResource = vscode.window.activeTextEditor.document.uri; + } + if (targetResource) { + vscode.debug.startDebugging(undefined, runConfiguration, { + noDebug: true, + }); + } + }), + vscode.commands.registerCommand("extension.bun.debugFile", (resource: vscode.Uri) => { + let targetResource = resource; + if (!targetResource && vscode.window.activeTextEditor) { + targetResource = vscode.window.activeTextEditor.document.uri; + } + if (targetResource) { + vscode.debug.startDebugging(undefined, { + ...debugConfiguration, + program: targetResource.fsPath, + }); + } + }), + ); + + const provider = new BunConfigurationProvider(); + context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider("bun", provider)); + + context.subscriptions.push( + vscode.debug.registerDebugConfigurationProvider( + "bun", + { + provideDebugConfigurations(folder: WorkspaceFolder | undefined): ProviderResult<DebugConfiguration[]> { + return debugConfigurations; + }, + }, + vscode.DebugConfigurationProviderTriggerKind.Dynamic, + ), + ); + + if (!factory) { + factory = new InlineDebugAdapterFactory(); + } + context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("bun", factory)); + if ("dispose" in factory && typeof factory.dispose === "function") { + // @ts-ignore + context.subscriptions.push(factory); + } +} + +class BunConfigurationProvider implements vscode.DebugConfigurationProvider { + resolveDebugConfiguration( + folder: WorkspaceFolder | undefined, + config: DebugConfiguration, + token?: CancellationToken, + ): ProviderResult<DebugConfiguration> { + if (!config.type && !config.request && !config.name) { + const editor = vscode.window.activeTextEditor; + if (editor && isJavaScript(editor.document.languageId)) { + Object.assign(config, debugConfiguration); + } + } + return config; + } +} + +class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory { + createDebugAdapterDescriptor(_session: vscode.DebugSession): ProviderResult<vscode.DebugAdapterDescriptor> { + const adapter = new VSCodeAdapter(_session); + return new vscode.DebugAdapterInlineImplementation(adapter); + } +} + +function isJavaScript(languageId: string): boolean { + return ( + languageId === "javascript" || + languageId === "javascriptreact" || + languageId === "typescript" || + languageId === "typescriptreact" + ); +} + +export class VSCodeAdapter extends DebugSession { + #adapter: DebugAdapter; + #dap: vscode.OutputChannel; + + constructor(session: vscode.DebugSession) { + super(); + this.#dap = vscode.window.createOutputChannel("Debug Adapter Protocol"); + this.#adapter = new DebugAdapter({ + sendToAdapter: this.sendMessage.bind(this), + }); + } + + sendMessage(message: DAP.Request | DAP.Response | DAP.Event): void { + console.log("[dap] -->", message); + this.#dap.appendLine("--> " + JSON.stringify(message)); + + const { type } = message; + if (type === "response") { + this.sendResponse(message); + } else if (type === "event") { + this.sendEvent(message); + } else { + throw new Error(`Not supported: ${type}`); + } + } + + handleMessage(message: DAP.Event | DAP.Request | DAP.Response): void { + console.log("[dap] <--", message); + this.#dap.appendLine("<-- " + JSON.stringify(message)); + + this.#adapter.accept(message); + } + + dispose() { + this.#adapter.close(); + this.#dap.dispose(); + } +} |