[Lldb-commits] [lldb] [lldb-dap] Allow providing debug adapter arguments in the extension (PR #129262)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Fri Mar 14 15:18:00 PDT 2025
================
@@ -0,0 +1,103 @@
+import * as vscode from "vscode";
+import * as child_process from "child_process";
+import * as util from "util";
+import { LLDBDapServer } from "./lldb-dap-server";
+import { createDebugAdapterExecutable } from "./debug-adapter-factory";
+import { ConfigureButton, showErrorMessage } from "./ui/show-error-message";
+import { ErrorWithNotification } from "./ui/error-with-notification";
+
+const exec = util.promisify(child_process.execFile);
+
+/**
+ * Determines whether or not the given lldb-dap executable supports executing
+ * in server mode.
+ *
+ * @param exe the path to the lldb-dap executable
+ * @returns a boolean indicating whether or not lldb-dap supports server mode
+ */
+async function isServerModeSupported(exe: string): Promise<boolean> {
+ const { stdout } = await exec(exe, ["--help"]);
+ return /--connection/.test(stdout);
+}
+
+export class LLDBDapConfigurationProvider
+ implements vscode.DebugConfigurationProvider
+{
+ constructor(private readonly server: LLDBDapServer) {}
+
+ async resolveDebugConfiguration(
+ folder: vscode.WorkspaceFolder | undefined,
+ debugConfiguration: vscode.DebugConfiguration,
----------------
ashgti wrote:
I wonder if we should have our own typed interface + validator to help with writing / validating the debug configurations.
For example,
```
interface LLDBDebugConfiguration extends vscode.DebugConfiguration {
program: string;
args?: string[];
env: Record<string, string>;
debugAdapterHostname?: string;
initCommands?: string[];
stopOnEntry?: boolean;
}
type TypeGuard<in out T> = {
(val: unknown): val is T;
}
function isBoolean(val: unknown): val is boolean {
return typeof val === 'boolean';
}
function isString(val: unknown): val is string {
return typeof val === 'string';
}
function isObject(val: unknown): val is object {
return typeof val === 'object';
}
function isArrayOf<T>(validator: TypeGuard<T>): TypeGuard<T[]> {
return (val: unknown): val is T[] => { return Array.isArray(val) && val.every(validator); };
}
function isRecordOf<T>(validator: TypeGuard<T>): TypeGuard<Record<string, T>> {
return (val: unknown): val is Record<string, T> => {
return isObject(val) && Object.entries(val).every(([key, value]) => isString(key) && validator(value));
};
}
function isOptional<T>(validator: TypeGuard<T>): (val: unknown) => val is undefined | T {
return (val: unknown): val is undefined | T => { return typeof val === 'undefined' ? true : validator(val) };
}
type KeyValidator<T> = { [P in keyof T]: TypeGuard<T[P]>; };
function isStruct<T>(kvValidator: KeyValidator<T>): (val: unknown) => val is T {
return (val: unknown): val is T => {
if (typeof val !== 'object' || val === null) return false;
return Object.entries(kvValidator as Record<string, (arg: unknown) => boolean>).every(([key, validator]) => validator(Reflect.get(val, key)));
};
}
const isLLDBDebugConfiguration = isStruct<LLDBDebugConfiguration>({
program: isString,
env: isRecordOf(isString),
debugAdapterHostname: isOptional(isString),
initCommands: isOptional(isArrayOf(isString)),
... other validators
});
...
async resolveDebugConfigurationWithSubstitutedVariables(folder, debugConfig) {
if (!isLLDBDebugConfiguration(debugConfig)) throw new Error("invalid debug configuration");
// After this you should be able to use `debugConfig.program` etc.
}
```
https://github.com/llvm/llvm-project/pull/129262
More information about the lldb-commits
mailing list