1- import * as path from "path " ;
1+ import * as Is from "vscode-languageclient/lib/common/utils/is " ;
22import * as os from "os" ;
3+ import * as path from "path" ;
34import * as vscode from "vscode" ;
45import { Env } from "./client" ;
56import { log } from "./util" ;
@@ -47,7 +48,7 @@ export class Config {
4748 }
4849
4950 private refreshLogging ( ) {
50- log . setEnabled ( this . traceExtension ) ;
51+ log . setEnabled ( this . traceExtension ?? false ) ;
5152 log . info ( "Extension version:" , this . package . version ) ;
5253
5354 const cfg = Object . entries ( this . cfg ) . filter ( ( [ _ , val ] ) => ! ( val instanceof Function ) ) ;
@@ -163,18 +164,24 @@ export class Config {
163164 * ```
164165 * So this getter handles this quirk by not requiring the caller to use postfix `!`
165166 */
166- private get < T > ( path : string ) : T {
167- return this . cfg . get < T > ( path ) ! ;
167+ private get < T > ( path : string ) : T | undefined {
168+ return substituteVSCodeVariables ( this . cfg . get < T > ( path ) ) ;
168169 }
169170
170171 get serverPath ( ) {
171172 return this . get < null | string > ( "server.path" ) ?? this . get < null | string > ( "serverPath" ) ;
172173 }
174+
173175 get serverExtraEnv ( ) : Env {
174176 const extraEnv =
175177 this . get < { [ key : string ] : string | number } | null > ( "server.extraEnv" ) ?? { } ;
176- return Object . fromEntries (
177- Object . entries ( extraEnv ) . map ( ( [ k , v ] ) => [ k , typeof v !== "string" ? v . toString ( ) : v ] )
178+ return substituteVariablesInEnv (
179+ Object . fromEntries (
180+ Object . entries ( extraEnv ) . map ( ( [ k , v ] ) => [
181+ k ,
182+ typeof v !== "string" ? v . toString ( ) : v ,
183+ ] )
184+ )
178185 ) ;
179186 }
180187 get traceExtension ( ) {
@@ -216,13 +223,13 @@ export class Config {
216223 if ( sourceFileMap !== "auto" ) {
217224 // "/rustc/<id>" used by suggestions only.
218225 const { [ "/rustc/<id>" ] : _ , ...trimmed } =
219- this . get < Record < string , string > > ( "debug.sourceFileMap" ) ;
226+ this . get < Record < string , string > > ( "debug.sourceFileMap" ) ?? { } ;
220227 sourceFileMap = trimmed ;
221228 }
222229
223230 return {
224231 engine : this . get < string > ( "debug.engine" ) ,
225- engineSettings : this . get < object > ( "debug.engineSettings" ) ,
232+ engineSettings : this . get < object > ( "debug.engineSettings" ) ?? { } ,
226233 openDebugPane : this . get < boolean > ( "debug.openDebugPane" ) ,
227234 sourceFileMap : sourceFileMap ,
228235 } ;
@@ -247,37 +254,27 @@ export class Config {
247254 }
248255}
249256
250- const VarRegex = new RegExp ( / \$ \{ ( .+ ?) \} / g) ;
251-
252- export function substituteVSCodeVariableInString ( val : string ) : string {
253- return val . replace ( VarRegex , ( substring : string , varName ) => {
254- if ( typeof varName === "string" ) {
255- return computeVscodeVar ( varName ) || substring ;
256- } else {
257- return substring ;
258- }
259- } ) ;
260- }
261-
262- export function substituteVSCodeVariables ( resp : any ) : any {
263- if ( typeof resp === "string" ) {
264- return substituteVSCodeVariableInString ( resp ) ;
265- } else if ( resp && Array . isArray ( resp ) ) {
257+ export function substituteVSCodeVariables < T > ( resp : T ) : T {
258+ if ( Is . string ( resp ) ) {
259+ return substituteVSCodeVariableInString ( resp ) as T ;
260+ } else if ( resp && Is . array < any > ( resp ) ) {
266261 return resp . map ( ( val ) => {
267262 return substituteVSCodeVariables ( val ) ;
268- } ) ;
263+ } ) as T ;
269264 } else if ( resp && typeof resp === "object" ) {
270265 const res : { [ key : string ] : any } = { } ;
271266 for ( const key in resp ) {
272267 const val = resp [ key ] ;
273268 res [ key ] = substituteVSCodeVariables ( val ) ;
274269 }
275- return res ;
276- } else if ( typeof resp === "function" ) {
277- return null ;
270+ return res as T ;
271+ } else if ( Is . func ( resp ) ) {
272+ throw new Error ( "Unexpected function type in substitution" ) ;
278273 }
279274 return resp ;
280275}
276+
277+ // FIXME: Merge this with `substituteVSCodeVariables` above
281278export function substituteVariablesInEnv ( env : Env ) : Env {
282279 const missingDeps = new Set < string > ( ) ;
283280 // vscode uses `env:ENV_NAME` for env vars resolution, and it's easier
@@ -355,6 +352,17 @@ export function substituteVariablesInEnv(env: Env): Env {
355352 return resolvedEnv ;
356353}
357354
355+ const VarRegex = new RegExp ( / \$ \{ ( .+ ?) \} / g) ;
356+ function substituteVSCodeVariableInString ( val : string ) : string {
357+ return val . replace ( VarRegex , ( substring : string , varName ) => {
358+ if ( Is . string ( varName ) ) {
359+ return computeVscodeVar ( varName ) || substring ;
360+ } else {
361+ return substring ;
362+ }
363+ } ) ;
364+ }
365+
358366function computeVscodeVar ( varName : string ) : string | null {
359367 const workspaceFolder = ( ) => {
360368 const folders = vscode . workspace . workspaceFolders ?? [ ] ;
0 commit comments