MCPcopy Index your code
hub / github.com/microsoft/vscode-cpptools / expandStringImpl

Function expandStringImpl

Extension/src/expand.ts:66–135  ·  view source on GitHub ↗

Returns [expandedString, didReplacement]

(input: string, options: ExpansionOptions)

Source from the content-addressed store, hash-verified

64
65/** Returns [expandedString, didReplacement] */
66async function expandStringImpl(input: string, options: ExpansionOptions): Promise<[string, boolean]> {
67 if (!input) {
68 return [input, false];
69 }
70
71 // We accumulate a list of substitutions that we need to make, preventing
72 // recursively expanding or looping forever on bad replacements
73 const subs: Map<string, string> = new Map<string, string>();
74
75 const var_re: RegExp = /\$\{(\w+)\}/g;
76 let match: RegExpMatchArray | null = null;
77 while (match = var_re.exec(input)) {
78 const full: string = match[0];
79 const key: string = match[1];
80 if (key !== 'dollar') {
81 // Replace dollar sign at the very end of the expanding process
82 const repl: string = options.vars[key];
83 if (!repl) {
84 void getOutputChannelLogger().showWarningMessage(localize('invalid.var.reference', 'Invalid variable reference {0} in string: {1}.', full, input));
85 } else {
86 subs.set(full, repl);
87 }
88 }
89 }
90
91 // Regular expression for variable value (between the variable suffix and the next ending curly bracket):
92 // .+? matches any character (except line terminators) between one and unlimited times,
93 // as few times as possible, expanding as needed (lazy)
94 const varValueRegexp: string = ".+?";
95 const env_re: RegExp = RegExp(`\\$\\{env:(${varValueRegexp})\\}`, "g");
96 while (match = env_re.exec(input)) {
97 const full: string = match[0];
98 const varname: string = match[1];
99 if (process.env[varname] === undefined) {
100 void getOutputChannelLogger().showWarningMessage(localize('env.var.not.found', 'Environment variable {0} not found', varname));
101 }
102 const repl: string = process.env[varname] || '';
103 subs.set(full, repl);
104 }
105
106 const command_re: RegExp = RegExp(`\\$\\{command:(${varValueRegexp})\\}`, "g");
107 while (match = command_re.exec(input)) {
108 if (options.doNotSupportCommands) {
109 void getOutputChannelLogger().showWarningMessage(localize('commands.not.supported', 'Commands are not supported for string: {0}.', input));
110 break;
111 }
112 const full: string = match[0];
113 const command: string = match[1];
114 if (subs.has(full)) {
115 continue; // Don't execute commands more than once per string
116 }
117 try {
118 const command_ret: unknown = await vscode.commands.executeCommand(command, options.vars.workspaceFolder);
119 subs.set(full, `${command_ret}`);
120 } catch (e: any) {
121 void getOutputChannelLogger().showWarningMessage(localize('exception.executing.command', 'Exception while executing command {0} for string: {1} {2}.', command, input, e));
122 }
123 }

Callers 1

expandStringFunction · 0.85

Calls 6

getOutputChannelLoggerFunction · 0.90
replaceAllFunction · 0.90
showWarningMessageMethod · 0.80
hasMethod · 0.80
setMethod · 0.45
forEachMethod · 0.45

Tested by

no test coverage detected