diff options
author | 2023-08-26 02:34:25 -0700 | |
---|---|---|
committer | 2023-08-26 02:34:25 -0700 | |
commit | 2a9e967fd1c766a718808d5a7fa779d74d44e62c (patch) | |
tree | 3bf4c059c03b9b561bc565ecf7cf21eaceae5353 /packages/bun-vscode | |
parent | 910daeff27ead119e15f35f6c1e0aa09d2aa7562 (diff) | |
download | bun-2a9e967fd1c766a718808d5a7fa779d74d44e62c.tar.gz bun-2a9e967fd1c766a718808d5a7fa779d74d44e62c.tar.zst bun-2a9e967fd1c766a718808d5a7fa779d74d44e62c.zip |
More improvements to debugger support (#4345)
* More fixes for dap
* More changes
* More changes 2
* More fixes
* Fix debugger.ts
* Bun Terminal
Diffstat (limited to 'packages/bun-vscode')
20 files changed, 258 insertions, 253 deletions
diff --git a/packages/bun-vscode/.gitignore b/packages/bun-vscode/.gitignore index 9db2648e4..cafc85cea 100644 --- a/packages/bun-vscode/.gitignore +++ b/packages/bun-vscode/.gitignore @@ -1,2 +1,3 @@ node_modules extension +example/.vscode diff --git a/packages/bun-vscode/.vscode/launch.json b/packages/bun-vscode/.vscode/launch.json index 3ec1574d3..5922fb1b6 100644 --- a/packages/bun-vscode/.vscode/launch.json +++ b/packages/bun-vscode/.vscode/launch.json @@ -5,22 +5,28 @@ "name": "Extension", "type": "extensionHost", "request": "launch", + "env": { + "NODE_ENV": "development" + }, "args": ["--extensionDevelopmentPath=${workspaceFolder}", "${workspaceFolder}/example"], "outFiles": ["${workspaceFolder}/dist/**/*.js"], - "preLaunchTask": "Build (watch)" + "preLaunchTask": "Build" }, { "name": "Extension (web)", "type": "extensionHost", "debugWebWorkerHost": true, "request": "launch", + "env": { + "NODE_ENV": "development" + }, "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionDevelopmentKind=web", "${workspaceFolder}/example" ], "outFiles": ["${workspaceFolder}/dist/**/*.js"], - "preLaunchTask": "Build (watch)" + "preLaunchTask": "Build" } ] } diff --git a/packages/bun-vscode/.vscode/tasks.json b/packages/bun-vscode/.vscode/tasks.json index a471df3ec..8675db611 100644 --- a/packages/bun-vscode/.vscode/tasks.json +++ b/packages/bun-vscode/.vscode/tasks.json @@ -6,13 +6,6 @@ "type": "shell", "command": "bun run build", "problemMatcher": "$esbuild" - }, - { - "label": "Build (watch)", - "type": "shell", - "command": "bun run build:watch", - "isBackground": true, - "problemMatcher": "$esbuild-watch" } ] } diff --git a/packages/bun-vscode/LICENSE b/packages/bun-vscode/LICENSE new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/packages/bun-vscode/LICENSE diff --git a/packages/bun-vscode/src/assets/icon-small.png b/packages/bun-vscode/assets/icon-small.png Binary files differindex 69bc385e8..69bc385e8 100644 --- a/packages/bun-vscode/src/assets/icon-small.png +++ b/packages/bun-vscode/assets/icon-small.png diff --git a/packages/bun-vscode/src/assets/icon.png b/packages/bun-vscode/assets/icon.png Binary files differindex 29cda9124..29cda9124 100644 --- a/packages/bun-vscode/src/assets/icon.png +++ b/packages/bun-vscode/assets/icon.png diff --git a/packages/bun-vscode/src/resources/package.json b/packages/bun-vscode/assets/package.json index 021c8125e..021c8125e 100644 --- a/packages/bun-vscode/src/resources/package.json +++ b/packages/bun-vscode/assets/package.json diff --git a/packages/bun-vscode/bun.lockb b/packages/bun-vscode/bun.lockb Binary files differindex c0949dd2d..599310c25 100755 --- a/packages/bun-vscode/bun.lockb +++ b/packages/bun-vscode/bun.lockb diff --git a/packages/bun-vscode/example/.vscode/launch.json b/packages/bun-vscode/example/.vscode/launch.json deleted file mode 100644 index 7ab446fad..000000000 --- a/packages/bun-vscode/example/.vscode/launch.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "type": "bun", - "request": "launch", - "name": "Debug Bun", - "program": "${file}", - "watch": "hot" - }, - { - "type": "bun", - "request": "attach", - "name": "Attach to Bun", - "url": "ws://localhost:6499/", - } - ] -} diff --git a/packages/bun-vscode/example/bun.lockb b/packages/bun-vscode/example/bun.lockb Binary files differindex b6516d9ed..7153db03e 100755 --- a/packages/bun-vscode/example/bun.lockb +++ b/packages/bun-vscode/example/bun.lockb diff --git a/packages/bun-vscode/example/example-sourcemap.js b/packages/bun-vscode/example/example-sourcemap.js deleted file mode 100644 index 82035bedb..000000000 --- a/packages/bun-vscode/example/example-sourcemap.js +++ /dev/null @@ -1,30 +0,0 @@ -// @bun -// example.ts -var a = function (request) { - b(request); -}; -var b = function (request) { - c(request); -}; -var c = function (request) { - console.log(request); -}; -var example_default = { - async fetch(request, server) { - a(request); - const coolThing = new SuperCoolThing(); - coolThing.doCoolThing(); - debugger; - return new Response(request.url); - }, -}; - -class SuperCoolThing { - doCoolThing() { - console.log("super cool thing!"); - } -} -export { example_default as default }; - -//# debugId=9BB0B773A8E4771564756e2164756e21 -//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiZXhhbXBsZS50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICJpbXBvcnQgdHlwZSB7IFNlcnZlciB9IGZyb20gXCJidW5cIjtcblxuZXhwb3J0IGRlZmF1bHQge1xuICBhc3luYyBmZXRjaChyZXF1ZXN0OiBSZXF1ZXN0LCBzZXJ2ZXI6IFNlcnZlcik6IFByb21pc2U8UmVzcG9uc2U+IHtcbiAgICBhKHJlcXVlc3QpO1xuICAgIGNvbnN0IGNvb2xUaGluZzogQ29vbFRoaW5nID0gbmV3IFN1cGVyQ29vbFRoaW5nKCk7XG4gICAgY29vbFRoaW5nLmRvQ29vbFRoaW5nKCk7XG4gICAgZGVidWdnZXI7XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShyZXF1ZXN0LnVybCk7XG4gIH1cbn07XG5cbi8vIGFcbmZ1bmN0aW9uIGEocmVxdWVzdDogUmVxdWVzdCk6IHZvaWQge1xuICBiKHJlcXVlc3QpO1xufVxuXG4vLyBiXG5mdW5jdGlvbiBiKHJlcXVlc3Q6IFJlcXVlc3QpOiB2b2lkIHtcbiAgYyhyZXF1ZXN0KTtcbn1cblxuLy8gY1xuZnVuY3Rpb24gYyhyZXF1ZXN0OiBSZXF1ZXN0KSB7XG4gIGNvbnNvbGUubG9nKHJlcXVlc3QpO1xufVxuXG5pbnRlcmZhY2UgQ29vbFRoaW5nIHtcbiAgZG9Db29sVGhpbmcoKTogdm9pZDtcbn1cblxuY2xhc3MgU3VwZXJDb29sVGhpbmcgaW1wbGVtZW50cyBDb29sVGhpbmcge1xuICBkb0Nvb2xUaGluZygpOiB2b2lkIHtcbiAgICBjb25zb2xlLmxvZyhcInN1cGVyIGNvb2wgdGhpbmchXCIpO1xuICB9XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiOztBQS8vLy8vZkFhQSxJQUFTLFlBQUMsQ0FBQyxTQUF3QjtBQUNqQyxJQUFFLE9BQU87QUFBQTtBQUlYLElBQVMsWUFBQyxDQUFDLFNBQXdCO0FBQ2pDLElBQUUsT0FBTztBQUFBO0FBSVgsSUFBUyxZQUFDLENBQUMsU0FBa0I7QUFDM0IsVUFBUSxJQUFJLE9BQU87QUFBQTtBQXRCckIsSUFBZTtBQUFBLE9BQ1AsTUFBSyxDQUFDLFNBQWtCLFFBQW1DO0FBQy9ELE1BQUUsT0FBTztBQUNULFVBQU0sWUFBdUIsSUFBSTtBQUNqQyxjQUFVLFlBQVk7QUFDdEI7QUFDQSxXQUFPLElBQUksU0FBUyxRQUFRLEdBQUc7QUFBQTtBQUVuQztBQXFCQTtBQUFBLE1BQU0sZUFBb0M7QUFBQSxFQUN4QyxXQUFXLEdBQVM7QUFDbEIsWUFBUSxJQUFJLG1CQUFtQjtBQUFBO0FBRW5DOyIsCiAgImRlYnVnSWQiOiAiOUJCMEI3NzNBOEU0NzcxNTY0NzU2ZTIxNjQ3NTZlMjEiLAogICJuYW1lcyI6IFtdCn0= diff --git a/packages/bun-vscode/example/example.js b/packages/bun-vscode/example/example.js deleted file mode 100644 index 31831824b..000000000 --- a/packages/bun-vscode/example/example.js +++ /dev/null @@ -1,63 +0,0 @@ -// @bun -const express = import.meta.require("express"); -const app = express(); -import { readFile } from "node:fs/promises"; - -app - .get("/", (req, res) => { - console.log("I am logging a request!??"); - readFile(import.meta.path, "utf-8").then(data => { - console.log(data.length); - debugger; - res.send("hello world"); - }); - }) - .listen(3000); - -const va = 1; -let vb = 2; -var vc = 3; - -function fa() { - fb(); -} - -function fb() { - fc(); -} - -function fc() { - fd(); -} - -function fd() { - let map = new Map([ - [1, 2], - [2, 3], - [3, 4], - ]); - let set = new Set([1, 2, 3, 4, 5]); - let arr = [1, 2, 3, 4, 5]; - let obj = { - a: 1, - b: 2, - c: 3, - }; - function fd1() { - let date = new Date(); - console.log(new Error().stack); - debugger; - console.log(date); - } - fd1(); -} - -Bun.serve({ - port: 9229, - inspector: true, - development: true, - fetch(request, server) { - // console.log(request); - return new Response(request.url); - }, -}); diff --git a/packages/bun-vscode/example/example.test.ts b/packages/bun-vscode/example/example.test.ts new file mode 100644 index 000000000..a9da929eb --- /dev/null +++ b/packages/bun-vscode/example/example.test.ts @@ -0,0 +1,11 @@ +import { describe, test, expect } from "bun:test"; + +describe("example", () => { + test("it works", () => { + expect(1).toBe(1); + expect(1).not.toBe(2); + expect(() => { + throw new Error("error"); + }).toThrow(); + }); +}); diff --git a/packages/bun-vscode/example/example.ts b/packages/bun-vscode/example/example.ts index 386b97f7c..536852902 100644 --- a/packages/bun-vscode/example/example.ts +++ b/packages/bun-vscode/example/example.ts @@ -4,7 +4,7 @@ export default { const coolThing: CoolThing = new SuperCoolThing(); coolThing.doCoolThing(); debugger; - return new Response("HELLO WORLD"); + return new Response("BAI BAI"); }, }; diff --git a/packages/bun-vscode/example/package.json b/packages/bun-vscode/example/package.json index 0d7d79529..602fba159 100644 --- a/packages/bun-vscode/example/package.json +++ b/packages/bun-vscode/example/package.json @@ -1,4 +1,6 @@ { + "private": true, + "name": "example", "dependencies": { "elysia": "^0.6.3", "express": "^4.18.2", @@ -7,5 +9,11 @@ }, "trustedDependencies": [ "mime" - ] -} + ], + "devDependencies": { + "bun-types": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + } +}
\ No newline at end of file diff --git a/packages/bun-vscode/example/tsconfig.json b/packages/bun-vscode/example/tsconfig.json new file mode 100644 index 000000000..1449bc3d9 --- /dev/null +++ b/packages/bun-vscode/example/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "lib": ["ESNext"], + "module": "esnext", + "target": "esnext", + "moduleResolution": "bundler", + "moduleDetection": "force", + "allowImportingTsExtensions": true, + "noEmit": true, + "composite": true, + "strict": true, + "downlevelIteration": true, + "skipLibCheck": true, + "jsx": "preserve", + "allowSyntheticDefaultImports": true, + "forceConsistentCasingInFileNames": true, + "allowJs": true, + "types": [ + "bun-types" // add Bun global + ] + } +} diff --git a/packages/bun-vscode/package.json b/packages/bun-vscode/package.json index c959cd8ab..985730196 100644 --- a/packages/bun-vscode/package.json +++ b/packages/bun-vscode/package.json @@ -7,18 +7,14 @@ "url": "https://github.com/oven-sh/bun" }, "main": "dist/extension.js", - "dependencies": { - "semver": "^7.5.4", - "source-map-js": "^1.0.2", - "ws": "^8.13.0" - }, "devDependencies": { "@types/vscode": "^1.81.0", "@vscode/debugadapter": "^1.56.0", "@vscode/debugadapter-testsupport": "^1.56.0", + "@vscode/vsce": "^2.20.1", "bun-types": "^0.7.3", - "typescript": "^5.0.0", - "esbuild": "^0.19.2" + "esbuild": "^0.19.2", + "typescript": "^5.0.0" }, "activationEvents": [ "onLanguage:javascript", @@ -59,14 +55,16 @@ "commands": [ { "command": "extension.bun.runFile", - "title": "Run File", + "title": "Run Bun", + "shortTitle": "Run", "category": "Bun", "enablement": "!inDebugMode", "icon": "$(play)" }, { "command": "extension.bun.debugFile", - "title": "Debug File", + "title": "Debug Bun", + "shortTitle": "Debug", "category": "Bun", "enablement": "!inDebugMode", "icon": "$(debug-alt)" @@ -169,6 +167,11 @@ false, "hot" ], + "default": false + }, + "debug": { + "type": "boolean", + "description": "If the process should be started in debug mode.", "default": true } } @@ -177,48 +180,11 @@ "properties": { "url": { "type": "string", - "description": "The URL of the Bun process to attach to.", - "default": "ws://localhost:6499/" + "description": "The URL of the Bun process to attach to." } } } - }, - "initialConfigurations": [ - { - "type": "bun", - "request": "launch", - "name": "Bun: Debug", - "program": "${file}" - }, - { - "type": "bun", - "request": "attach", - "name": "Bun: Attach", - "url": "ws://localhost:6499/" - } - ], - "configurationSnippets": [ - { - "label": "Bun: Debug", - "description": "A new configuration for 'debugging' a Bun process.", - "body": { - "type": "bun", - "request": "launch", - "name": "Ask for file name", - "program": "^\"\\${file}\"" - } - }, - { - "label": "Bun: Attach", - "description": "A new configuration for 'attaching' to a running Bun process.", - "body": { - "type": "bun", - "request": "attach", - "name": "Attach to Bun", - "url": "ws://localhost:6499/" - } - } - ] + } } ], "languages": [ @@ -231,15 +197,15 @@ ".lockb" ], "icon": { - "dark": "src/assets/icon-small.png", - "light": "src/assets/icon-small.png" + "dark": "assets/icon-small.png", + "light": "assets/icon-small.png" } } ], "jsonValidation": [ { "fileMatch": "package.json", - "url": "src/resources/package.json" + "url": "assets/package.json" } ], "customEditors": [ @@ -268,7 +234,7 @@ "theme": "dark" }, "homepage": "https://bun.sh/", - "icon": "src/assets/icon.png", + "icon": "assets/icon.png", "keywords": [ "bun", "node.js", @@ -279,10 +245,8 @@ "license": "MIT", "publisher": "oven", "scripts": { - "bundle": "./node_modules/.bin/esbuild src/extension.ts src/web-extension.ts --bundle --external:vscode --outdir=dist --platform=node --format=cjs", - "prebuild": "bun run bundle && rm -rf extension && mkdir -p extension/src && cp -r dist extension/dist && cp -r src/assets extension/src/assets && cp package.json extension && cp README.md extension", - "build": "cd extension && vsce package", - "build:watch": "./node_modules/.bin/esbuild --watch src/extension.ts src/web-extension.ts --bundle --external:vscode --outdir=dist --platform=node --format=cjs" + "build": "node scripts/build.mjs", + "test": "node scripts/test.mjs" }, "workspaceTrust": { "request": "never" diff --git a/packages/bun-vscode/scripts/build.mjs b/packages/bun-vscode/scripts/build.mjs new file mode 100644 index 000000000..261965840 --- /dev/null +++ b/packages/bun-vscode/scripts/build.mjs @@ -0,0 +1,29 @@ +import { buildSync } from "esbuild"; +import { rmSync, mkdirSync, cpSync } from "node:fs"; +import { spawnSync } from "node:child_process"; + +const { pathname } = new URL("..", import.meta.url); +process.chdir(pathname); + +buildSync({ + entryPoints: ["src/extension.ts", "src/web-extension.ts"], + outdir: "dist", + bundle: true, + external: ["vscode"], + platform: "node", + format: "cjs", +}); + +rmSync("extension", { recursive: true, force: true }); +mkdirSync("extension", { recursive: true }); +cpSync("dist", "extension/dist", { recursive: true }); +cpSync("assets", "extension/assets", { recursive: true }); +cpSync("README.md", "extension/README.md"); +cpSync("LICENSE", "extension/LICENSE"); +cpSync("package.json", "extension/package.json"); + +const cmd = process.isBun ? "bunx" : "npx"; +spawnSync(cmd, ["vsce", "package"], { + cwd: "extension", + stdio: "inherit", +}); diff --git a/packages/bun-vscode/scripts/test.mjs b/packages/bun-vscode/scripts/test.mjs new file mode 100644 index 000000000..6e890c420 --- /dev/null +++ b/packages/bun-vscode/scripts/test.mjs @@ -0,0 +1,21 @@ +import { readdirSync } from "node:fs"; +import { spawn } from "node:child_process"; + +const { pathname } = new URL("..", import.meta.url); +process.chdir(pathname); + +let path; +for (const filename of readdirSync("extension")) { + if (filename.endsWith(".vsix")) { + path = `extension/${filename}`; + break; + } +} + +if (!path) { + throw new Error("No .vsix file found"); +} + +spawn("code", ["--new-window", `--install-extension=${path}`, `--extensionDevelopmentPath=${pathname}`, "example"], { + stdio: "inherit", +}); diff --git a/packages/bun-vscode/src/features/debug.ts b/packages/bun-vscode/src/features/debug.ts index 3b841ea66..eae2b1c33 100644 --- a/packages/bun-vscode/src/features/debug.ts +++ b/packages/bun-vscode/src/features/debug.ts @@ -3,13 +3,15 @@ import type { CancellationToken, DebugConfiguration, ProviderResult, WorkspaceFo import type { DAP } from "../../../bun-debug-adapter-protocol"; import { DebugAdapter } from "../../../bun-debug-adapter-protocol"; import { DebugSession } from "@vscode/debugadapter"; +import { inspect } from "node:util"; +import { tmpdir } from "node:os"; const debugConfiguration: vscode.DebugConfiguration = { type: "bun", request: "launch", name: "Debug Bun", program: "${file}", - watch: true, + watch: false, }; const runConfiguration: vscode.DebugConfiguration = { @@ -17,117 +19,131 @@ const runConfiguration: vscode.DebugConfiguration = { request: "launch", name: "Run Bun", program: "${file}", - watch: true, + debug: false, + watch: false, }; const attachConfiguration: vscode.DebugConfiguration = { type: "bun", request: "attach", - name: "Attach to Bun", + name: "Attach Bun", url: "ws://localhost:6499/", }; -const debugConfigurations: vscode.DebugConfiguration[] = [debugConfiguration, attachConfiguration]; +let channels: Record<string, vscode.OutputChannel> = {}; +let terminal: TerminalDebugSession | undefined; 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.commands.registerCommand("extension.bun.runFile", RunFileCommand), + vscode.commands.registerCommand("extension.bun.debugFile", DebugFileCommand), vscode.debug.registerDebugConfigurationProvider( "bun", - { - provideDebugConfigurations(folder: WorkspaceFolder | undefined): ProviderResult<DebugConfiguration[]> { - return debugConfigurations; - }, - }, + new DebugConfigurationProvider(), + vscode.DebugConfigurationProviderTriggerKind.Initial, + ), + vscode.debug.registerDebugConfigurationProvider( + "bun", + new DebugConfigurationProvider(), vscode.DebugConfigurationProviderTriggerKind.Dynamic, ), + vscode.debug.registerDebugAdapterDescriptorFactory("bun", factory ?? new InlineDebugAdapterFactory()), + (channels["dap"] = vscode.window.createOutputChannel("Debug Adapter Protocol (Bun)")), + (channels["jsc"] = vscode.window.createOutputChannel("JavaScript Inspector (Bun)")), + (channels["console"] = vscode.window.createOutputChannel("Console (Bun)")), + (terminal = new TerminalDebugSession()), ); +} - if (!factory) { - factory = new InlineDebugAdapterFactory(); +function RunFileCommand(resource?: vscode.Uri): void { + const path = getCurrentPath(resource); + if (path) { + vscode.debug.startDebugging(undefined, { + ...runConfiguration, + noDebug: true, + program: path, + }); } - context.subscriptions.push(vscode.debug.registerDebugAdapterDescriptorFactory("bun", factory)); - if ("dispose" in factory && typeof factory.dispose === "function") { - // @ts-ignore - context.subscriptions.push(factory); +} + +function DebugFileCommand(resource?: vscode.Uri): void { + const path = getCurrentPath(resource); + if (path) { + vscode.debug.startDebugging(undefined, { + ...debugConfiguration, + program: path, + }); } } -class BunConfigurationProvider implements vscode.DebugConfigurationProvider { +class DebugConfigurationProvider implements vscode.DebugConfigurationProvider { + provideDebugConfigurations(folder: WorkspaceFolder | undefined): ProviderResult<DebugConfiguration[]> { + return [debugConfiguration, runConfiguration, attachConfiguration]; + } + 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); + let target: DebugConfiguration; + + const { request } = config; + if (request === "attach") { + target = attachConfiguration; + } else { + target = debugConfiguration; + } + + for (const [key, value] of Object.entries(target)) { + if (config[key] === undefined) { + config[key] = value; } } + return config; } } class InlineDebugAdapterFactory implements vscode.DebugAdapterDescriptorFactory { - createDebugAdapterDescriptor(_session: vscode.DebugSession): ProviderResult<vscode.DebugAdapterDescriptor> { - const adapter = new VSCodeAdapter(_session); + createDebugAdapterDescriptor(session: vscode.DebugSession): ProviderResult<vscode.DebugAdapterDescriptor> { + const { configuration } = session; + const { request, url } = configuration; + + if (request === "attach" && url === terminal?.url) { + return new vscode.DebugAdapterInlineImplementation(terminal); + } + + const adapter = new FileDebugSession(session.id); return new vscode.DebugAdapterInlineImplementation(adapter); } } -function isJavaScript(languageId: string): boolean { - return ( - languageId === "javascript" || - languageId === "javascriptreact" || - languageId === "typescript" || - languageId === "typescriptreact" - ); -} +class FileDebugSession extends DebugSession { + readonly url: string; + readonly adapter: DebugAdapter; -export class VSCodeAdapter extends DebugSession { - #adapter: DebugAdapter; - #dap: vscode.OutputChannel; - - constructor(session: vscode.DebugSession) { + constructor(sessionId?: string) { super(); - this.#dap = vscode.window.createOutputChannel("Debug Adapter Protocol"); - this.#adapter = new DebugAdapter({ - sendToAdapter: this.sendMessage.bind(this), + const uniqueId = sessionId ?? Math.random().toString(36).slice(2); + this.url = `ws+unix://${tmpdir()}/bun-vscode-${uniqueId}.sock`; + this.adapter = new DebugAdapter({ + url: this.url, + send: this.sendMessage.bind(this), + logger(...messages) { + log("jsc", ...messages); + }, + stdout(message) { + log("console", message); + }, + stderr(message) { + log("console", message); + }, }); } sendMessage(message: DAP.Request | DAP.Response | DAP.Event): void { - console.log("[dap] -->", message); - this.#dap.appendLine("--> " + JSON.stringify(message)); + log("dap", "-->", message); const { type } = message; if (type === "response") { @@ -140,14 +156,59 @@ export class VSCodeAdapter extends DebugSession { } handleMessage(message: DAP.Event | DAP.Request | DAP.Response): void { - console.log("[dap] <--", message); - this.#dap.appendLine("<-- " + JSON.stringify(message)); + log("dap", "<--", message); - this.#adapter.accept(message); + this.adapter.accept(message); } dispose() { - this.#adapter.close(); - this.#dap.dispose(); + this.adapter.close(); + } +} + +class TerminalDebugSession extends FileDebugSession { + readonly terminal: vscode.Terminal; + + constructor() { + super(); + this.terminal = vscode.window.createTerminal({ + name: "Bun Terminal", + env: { + "BUN_INSPECT": `1${this.url}`, + "BUN_INSPECT_NOTIFY": `unix://${this.adapter.inspector.unix}`, + }, + isTransient: true, + iconPath: new vscode.ThemeIcon("debug-console"), + }); + this.terminal.show(); + this.adapter.inspector.startDebugging = () => { + vscode.debug.startDebugging(undefined, { + ...attachConfiguration, + url: this.url, + }); + }; + } +} + +function log(channel: string, ...message: unknown[]): void { + if (process.env.NODE_ENV === "development") { + console.log(`[${channel}]`, ...message); + channels[channel]?.appendLine(message.map(v => inspect(v)).join(" ")); + } +} + +function isJavaScript(languageId: string): boolean { + return ( + languageId === "javascript" || + languageId === "javascriptreact" || + languageId === "typescript" || + languageId === "typescriptreact" + ); +} + +function getCurrentPath(target?: vscode.Uri): string | undefined { + if (!target && vscode.window.activeTextEditor) { + target = vscode.window.activeTextEditor.document.uri; } + return target?.fsPath; } |