blob: d45c1820eec757c9dc25a1bd88409f6197c50c0d [file] [log] [blame]
import * as vscode from "vscode";
export class LaunchUriHandler implements vscode.UriHandler {
async handleUri(uri: vscode.Uri) {
try {
const params = new URLSearchParams(uri.query);
if (uri.path == "/start") {
// Some properties have default values
let debugConfig: vscode.DebugConfiguration = {
type: "lldb-dap",
request: "launch",
name: "",
};
// The `config` parameter allows providing a complete JSON-encoded configuration
const configJson = params.get("config");
if (configJson !== null) {
Object.assign(debugConfig, JSON.parse(configJson));
}
// Furthermore, some frequently used parameters can also be provided as separate parameters
const stringKeys = [
"name",
"request",
"program",
"cwd",
"debuggerRoot",
];
const numberKeys = ["pid"];
const arrayKeys = [
"args",
"initCommands",
"preRunCommands",
"stopCommands",
"exitCommands",
"terminateCommands",
"launchCommands",
"attachCommands",
];
for (const key of stringKeys) {
const value = params.get(key);
if (value) {
debugConfig[key] = value;
}
}
for (const key of numberKeys) {
const value = params.get(key);
if (value) {
debugConfig[key] = Number(value);
}
}
for (const key of arrayKeys) {
// `getAll()` returns an array of strings.
const value = params.getAll(key);
if (value) {
debugConfig[key] = value;
}
}
// Report an error if we received any unknown parameters
const supportedKeys = new Set<string>(
["config"].concat(stringKeys).concat(numberKeys).concat(arrayKeys),
);
const presentKeys = new Set<string>(params.keys());
// FIXME: Use `Set.difference` as soon as ES2024 is widely available
const unknownKeys = new Set<string>();
for (const k of presentKeys.keys()) {
if (!supportedKeys.has(k)) {
unknownKeys.add(k);
}
}
if (unknownKeys.size > 0) {
throw new Error(
`Unsupported URL parameters: ${Array.from(unknownKeys.keys()).join(", ")}`,
);
}
// Prodide a default for the config name
const defaultName =
debugConfig.request == "launch"
? "URL-based Launch"
: "URL-based Attach";
debugConfig.name =
debugConfig.name || debugConfig.program || defaultName;
// Force the type to `lldb-dap`. We don't want to allow launching any other
// Debug Adapters using this URI scheme.
if (debugConfig.type != "lldb-dap") {
throw new Error(`Unsupported debugger type: ${debugConfig.type}`);
}
await vscode.debug.startDebugging(undefined, debugConfig);
} else {
throw new Error(`Unsupported Uri path: ${uri.path}`);
}
} catch (err) {
if (err instanceof Error) {
await vscode.window.showErrorMessage(
`Failed to handle lldb-dap URI request: ${err.message}`,
);
} else {
await vscode.window.showErrorMessage(
`Failed to handle lldb-dap URI request: ${JSON.stringify(err)}`,
);
}
}
}
}