Skip to content

Commit 0b2fea0

Browse files
committed
Add expandVSCodeVariables()
1 parent e109aa9 commit 0b2fea0

5 files changed

Lines changed: 55 additions & 28 deletions

File tree

extension/cargo.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { inspect } from 'util';
1010
import { Dict } from './novsc/commonTypes';
1111
import { getExtensionConfig } from './main';
1212
import { output } from './logging';
13-
import { expandVariablesInObject } from './novsc/expand';
13+
import { expandVariables } from './novsc/expand';
1414
import { LaunchEnvironment } from 'codelldb';
1515
import { RpcServer, waitEndOfDebugSession } from './externalLaunch';
1616
import YAML from 'yaml';
@@ -310,7 +310,7 @@ export class Cargo {
310310
return cargo;
311311
}
312312

313-
getCargoCwd(cwd: string | undefined) : string {
313+
getCargoCwd(cwd: string | undefined): string {
314314
return cwd ?? (this.workspaceFolder?.uri?.fsPath!);
315315
}
316316
}
@@ -357,16 +357,15 @@ async function runTask<T, R>(
357357

358358
// Expands ${cargo: ...} placeholders.
359359
export function expandCargo(launchConfig: DebugConfiguration, cargoDict: Dict<string>): DebugConfiguration {
360-
let expander = (type: string | null, key: string) => {
360+
return expandVariables(launchConfig, (type, key) => {
361361
if (type == 'cargo') {
362362
let value = cargoDict[key];
363363
if (value == undefined)
364364
throw new Error('cargo:' + key + ' is not defined');
365365
return value.toString();
366366
}
367367
return null;
368-
};
369-
return expandVariablesInObject(launchConfig, expander);
368+
});
370369
}
371370

372371
interface CargoConfigOptions {

extension/configUtils.ts

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
import { QuickPickItem, WorkspaceConfiguration, DebugConfiguration, OutputChannel } from 'vscode';
1+
import { QuickPickItem, WorkspaceConfiguration, DebugConfiguration, OutputChannel, WorkspaceFolder, workspace } from 'vscode';
22
import * as cp from 'child_process';
33
import * as async from './novsc/async';
4+
import * as path from 'path';
5+
import * as os from 'os';
46
import { Dict } from './novsc/commonTypes';
5-
import { expandVariablesInObject } from './novsc/expand';
7+
import { expandVariables } from './novsc/expand';
68

79
// Expands variable references of the form ${dbgconfig:name} in all properties of launch configuration.
810
export function expandDbgConfig(debugConfig: DebugConfiguration, dbgconfigConfig: WorkspaceConfiguration): DebugConfiguration {
@@ -27,12 +29,12 @@ export function expandDbgConfig(debugConfig: DebugConfiguration, dbgconfigConfig
2729
converged = true;
2830
for (let prop of Object.keys(dbgconfig)) {
2931
expanding = prop;
30-
dbgconfig[prop] = expandVariablesInObject(dbgconfig[prop], expander);
32+
dbgconfig[prop] = expandVariables(dbgconfig[prop], expander);
3133
}
3234
} while (!converged);
3335

3436
// Now expand dbgconfigs in the launch configuration.
35-
debugConfig = expandVariablesInObject(debugConfig, (type, key) => {
37+
debugConfig = expandVariables(debugConfig, (type, key) => {
3638
if (type == 'dbgconfig') {
3739
let value = dbgconfig[key];
3840
if (value == undefined)
@@ -44,6 +46,30 @@ export function expandDbgConfig(debugConfig: DebugConfiguration, dbgconfigConfig
4446
return debugConfig;
4547
}
4648

49+
export function expandVSCodeVariables<T extends any>(obj: T, folder?: WorkspaceFolder): T {
50+
return expandVariables(obj, (type, key) => {
51+
if (type == null) {
52+
if (key == 'workspaceFolder') {
53+
return folder ? folder.uri.fsPath : '';
54+
} else if (key == 'workspaceFolderBasename') {
55+
return folder ? path.basename(folder.uri.fsPath) : '';
56+
} else if (key == 'userHome') {
57+
return os.homedir();
58+
} else if (key == 'pathSeparator' || key == '/') {
59+
return path.sep;
60+
} else {
61+
return null;
62+
}
63+
} else if (type == 'env') {
64+
return process.env[key] ?? '';
65+
} else if (type == 'config') {
66+
return workspace.getConfiguration(undefined, folder).get<string>(key) ?? '';
67+
} else {
68+
return null;
69+
}
70+
});
71+
}
72+
4773
export function isEmpty(obj: any): boolean {
4874
if (obj === null || obj === undefined)
4975
return true;

extension/main.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import { LaunchCompletionProvider } from './launchCompletions';
2929
import { output, showErrorWithLog } from './logging';
3030
import { LLDBCommandTool, SessionInfoTool } from './vibeDebug';
3131
import { alternateBackend, selfTest, commandPrompt } from './adapterUtils';
32+
import { expandVSCodeVariables } from './configUtils';
3233

3334
export function getExtensionConfig(scope?: ConfigurationScope, subkey?: string): WorkspaceConfiguration {
3435
let key = 'lldb';
@@ -438,10 +439,10 @@ class Extension implements DebugAdapterDescriptorFactory {
438439
let authToken = crypto.randomBytes(16).toString('base64');
439440
return {
440441
extensionPath: this.context.extensionPath,
441-
liblldb: liblldb,
442-
lldbServer: lldbServer,
443-
extraEnv: adapterEnv,
444-
workDir: workspace.rootPath,
442+
liblldb: expandVSCodeVariables(liblldb, folder),
443+
lldbServer: expandVSCodeVariables(lldbServer, folder),
444+
extraEnv: expandVSCodeVariables(adapterEnv, folder),
445+
workDir: folder?.uri.fsPath,
445446
port: port,
446447
connect: true,
447448
authToken: authToken,

extension/novsc/expand.ts

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,31 @@
1+
import { Dict } from "./commonTypes";
12

23
// Returning null means "keep the original text".
34
type Expander = (type: string | null, key: string) => string | null;
45

56
let expandVarRegex = /\$\{(?:([^:}]+):)?([^}]+)\}/g;
67

7-
export function expandVariables(str: string | String, expander: Expander): string {
8-
let result = str.replace(expandVarRegex, (all: string, type: string, key: string): string => {
9-
let replacement = expander(type, key);
10-
return replacement != null ? replacement : all;
11-
});
12-
return result;
13-
}
8+
export function expandVariables<T extends any>(obj: T, expander: Expander): T {
9+
if (obj === undefined || obj === null)
10+
return obj;
1411

15-
export function expandVariablesInObject(obj: any, expander: Expander): any {
16-
if (typeof obj == 'string' || obj instanceof String)
17-
return expandVariables(obj, expander);
12+
if (typeof obj == 'string' || obj instanceof String) {
13+
return obj.replace(expandVarRegex, (all: string, type: string, key: string): string => {
14+
let replacement = expander(type, key);
15+
return replacement != null ? replacement : all;
16+
}) as T;
17+
}
1818

1919
if (isScalarValue(obj))
2020
return obj;
2121

2222
if (obj instanceof Array)
23-
return obj.map(v => expandVariablesInObject(v, expander));
23+
return obj.map(v => expandVariables(v, expander)) as T;
2424

25-
for (let prop of Object.keys(obj))
26-
obj[prop] = expandVariablesInObject(obj[prop], expander)
27-
return obj;
25+
let result: Dict<any> = {};
26+
for (let prop of Object.getOwnPropertyNames(obj))
27+
result[prop] = expandVariables((obj as Dict<any>)[prop], expander);
28+
return result as T;
2829
}
2930

3031
function isScalarValue(value: any): boolean {

tests/util.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ suite('Versions', () => {
1515

1616
suite('Util', () => {
1717
test('expandVariables', async () => {
18-
function expander(type: string, key: string) {
18+
function expander(type: string | null, key: string) {
1919
if (type == 'echo') return key;
2020
if (type == 'reverse') return key.split('').reverse().join('');
2121
throw new Error('Unknown ' + type + ' ' + key);

0 commit comments

Comments
 (0)