Skip to content

Commit 60285cc

Browse files
committed
Add more validation for settings
1 parent 11eaafe commit 60285cc

File tree

1 file changed

+131
-63
lines changed

1 file changed

+131
-63
lines changed

src/configuration.ts

Lines changed: 131 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,12 @@ const configuration = {
185185
);
186186
},
187187
get disable(): boolean {
188-
return vscode.workspace
189-
.getConfiguration("swift.sourcekit-lsp")
190-
.get<boolean>("disable", false);
188+
return validateBooleanSetting(
189+
vscode.workspace
190+
.getConfiguration("swift.sourcekit-lsp")
191+
.get<boolean>("disable", false),
192+
"swift.sourcekit-lsp.disable"
193+
);
191194
},
192195
};
193196
},
@@ -232,49 +235,68 @@ const configuration = {
232235
return {
233236
/** Environment variables to set when running tests */
234237
get testEnvironmentVariables(): { [key: string]: string } {
235-
return vscode.workspace
236-
.getConfiguration("swift", workspaceFolder)
237-
.get<{ [key: string]: string }>("testEnvironmentVariables", {});
238+
return validateObjectSetting(
239+
vscode.workspace
240+
.getConfiguration("swift", workspaceFolder)
241+
.get<{ [key: string]: string }>("testEnvironmentVariables", {}),
242+
"swift.testEnvironmentVariables"
243+
);
238244
},
239245
/** Extra arguments to pass to swift test and swift build when running and debugging tests. */
240246
get additionalTestArguments(): string[] {
241-
return vscode.workspace
242-
.getConfiguration("swift", workspaceFolder)
243-
.get<string[]>("additionalTestArguments", [])
244-
.map(substituteVariablesInString);
247+
return validateStringArraySettings(
248+
vscode.workspace
249+
.getConfiguration("swift", workspaceFolder)
250+
.get<string[]>("additionalTestArguments", []),
251+
"swift.additionalTestArguments"
252+
).map(substituteVariablesInString);
245253
},
246254
/** auto-generate launch.json configurations */
247255
get autoGenerateLaunchConfigurations(): boolean {
248-
return vscode.workspace
249-
.getConfiguration("swift", workspaceFolder)
250-
.get<boolean>("autoGenerateLaunchConfigurations", true);
256+
return validateBooleanSetting(
257+
vscode.workspace
258+
.getConfiguration("swift", workspaceFolder)
259+
.get<boolean>("autoGenerateLaunchConfigurations", true),
260+
"swift.autoGenerateLaunchConfigurations"
261+
);
251262
},
252263
/** disable automatic running of swift package resolve */
253264
get disableAutoResolve(): boolean {
254-
return vscode.workspace
255-
.getConfiguration("swift", workspaceFolder)
256-
.get<boolean>("disableAutoResolve", false);
265+
return validateBooleanSetting(
266+
vscode.workspace
267+
.getConfiguration("swift", workspaceFolder)
268+
.get<boolean>("disableAutoResolve", false),
269+
"swift.disableAutoResolve"
270+
);
257271
},
258272
/** search sub-folder of workspace folder for Swift Packages */
259273
get searchSubfoldersForPackages(): boolean {
260-
return vscode.workspace
261-
.getConfiguration("swift", workspaceFolder)
262-
.get<boolean>("searchSubfoldersForPackages", false);
274+
return validateBooleanSetting(
275+
vscode.workspace
276+
.getConfiguration("swift", workspaceFolder)
277+
.get<boolean>("searchSubfoldersForPackages", false),
278+
"swift.searchSubfoldersForPackages"
279+
);
263280
},
264281
/** Folders to ignore when searching for Swift Packages */
265282
get ignoreSearchingForPackagesInSubfolders(): string[] {
266-
return vscode.workspace
267-
.getConfiguration("swift", workspaceFolder)
268-
.get<
269-
string[]
270-
>("ignoreSearchingForPackagesInSubfolders", [".", ".build", "Packages", "out", "bazel-out", "bazel-bin"])
271-
.map(substituteVariablesInString);
272-
},
273-
get attachmentsPath(): string {
274-
return substituteVariablesInString(
283+
return validateStringArraySettings(
275284
vscode.workspace
276285
.getConfiguration("swift", workspaceFolder)
277-
.get<string>("attachmentsPath", "./.build/attachments")
286+
.get<
287+
string[]
288+
>("ignoreSearchingForPackagesInSubfolders", [".", ".build", "Packages", "out", "bazel-out", "bazel-bin"]),
289+
"swift.ignoreSearchingForPackagesInSubfolders"
290+
).map(substituteVariablesInString);
291+
},
292+
get attachmentsPath(): string {
293+
return validateStringSetting(
294+
substituteVariablesInString(
295+
vscode.workspace
296+
.getConfiguration("swift", workspaceFolder)
297+
.get<string>("attachmentsPath", "./.build/attachments")
298+
),
299+
"swift.attachmentsPath"
278300
);
279301
},
280302
pluginPermissions(pluginId?: string): PluginPermissionConfiguration {
@@ -297,14 +319,23 @@ const configuration = {
297319
let useDebugAdapterFromToolchain =
298320
inspectUseDebugAdapterFromToolchain?.workspaceValue ??
299321
inspectUseDebugAdapterFromToolchain?.globalValue;
322+
323+
validateBooleanSetting(
324+
!!useDebugAdapterFromToolchain,
325+
"swift.debugger.useDebugAdapterFromToolchain"
326+
);
327+
300328
// On Windows arm64 we enable swift.debugger.useDebugAdapterFromToolchain by default since CodeLLDB does
301329
// not support this platform and gives an awful error message.
302330
if (process.platform === "win32" && process.arch === "arm64") {
303331
useDebugAdapterFromToolchain = useDebugAdapterFromToolchain ?? true;
304332
}
305-
const selectedAdapter = vscode.workspace
306-
.getConfiguration("swift.debugger")
307-
.get<DebugAdapters>("debugAdapter", "auto");
333+
const selectedAdapter = validateStringSetting<DebugAdapters>(
334+
vscode.workspace
335+
.getConfiguration("swift.debugger")
336+
.get<DebugAdapters>("debugAdapter", "auto"),
337+
"swift.debugger.debugAdapter"
338+
);
308339
switch (selectedAdapter) {
309340
case "auto":
310341
if (useDebugAdapterFromToolchain !== undefined) {
@@ -316,8 +347,11 @@ const configuration = {
316347
}
317348
},
318349
get customDebugAdapterPath(): string {
319-
return substituteVariablesInString(
320-
vscode.workspace.getConfiguration("swift.debugger").get<string>("path", "")
350+
return validateStringSetting(
351+
substituteVariablesInString(
352+
vscode.workspace.getConfiguration("swift.debugger").get<string>("path", "")
353+
),
354+
"swift.debugger.path"
321355
);
322356
},
323357
get disable(): boolean {
@@ -329,18 +363,21 @@ const configuration = {
329363
);
330364
},
331365
get setupCodeLLDB(): SetupCodeLLDBOptions {
332-
return vscode.workspace
333-
.getConfiguration("swift.debugger")
334-
.get<SetupCodeLLDBOptions>("setupCodeLLDB", "prompt");
366+
return validateStringSetting(
367+
vscode.workspace
368+
.getConfiguration("swift.debugger")
369+
.get<SetupCodeLLDBOptions>("setupCodeLLDB", "prompt"),
370+
"swift.debugger.setupCodeLLDB"
371+
);
335372
},
336373
};
337374
},
338375
/** Files and directories to exclude from the code coverage. */
339376
get excludeFromCodeCoverage(): string[] {
340-
return vscode.workspace
341-
.getConfiguration("swift")
342-
.get<string[]>("excludeFromCodeCoverage", [])
343-
.map(substituteVariablesInString);
377+
return validateStringArraySettings(
378+
vscode.workspace.getConfiguration("swift").get<string[]>("excludeFromCodeCoverage", []),
379+
"swift.excludeFromCodeCoverage"
380+
).map(substituteVariablesInString);
344381
},
345382
/** Whether to show inline code lenses for running and debugging tests. */
346383
get showTestCodeLenses(): boolean | ValidCodeLens[] {
@@ -350,7 +387,10 @@ const configuration = {
350387
},
351388
/** Whether to record the duration of tests in the Test Explorer. */
352389
get recordTestDuration(): boolean {
353-
return vscode.workspace.getConfiguration("swift").get<boolean>("recordTestDuration", true);
390+
return validateBooleanSetting(
391+
vscode.workspace.getConfiguration("swift").get<boolean>("recordTestDuration", true),
392+
"swift.recordTestDuration"
393+
);
354394
},
355395
/** Files and directories to exclude from the Package Dependencies view. */
356396
get excludePathsFromPackageDependencies(): string[] {
@@ -462,21 +502,30 @@ const configuration = {
462502
},
463503
/** Environment variables to set when building */
464504
get swiftEnvironmentVariables(): { [key: string]: string } {
465-
return vscode.workspace
466-
.getConfiguration("swift")
467-
.get<{ [key: string]: string }>("swiftEnvironmentVariables", {});
505+
return validateObjectSetting(
506+
vscode.workspace
507+
.getConfiguration("swift")
508+
.get<{ [key: string]: string }>("swiftEnvironmentVariables", {}),
509+
"swift.swiftEnvironmentVariables"
510+
);
468511
},
469512
/** include build errors in problems view */
470513
get diagnosticsCollection(): DiagnosticCollectionOptions {
471-
return vscode.workspace
472-
.getConfiguration("swift")
473-
.get<DiagnosticCollectionOptions>("diagnosticsCollection", "keepSourceKit");
514+
return validateStringSetting(
515+
vscode.workspace
516+
.getConfiguration("swift")
517+
.get<DiagnosticCollectionOptions>("diagnosticsCollection", "keepSourceKit"),
518+
"swift.diagnosticsCollection"
519+
);
474520
},
475521
/** set the -diagnostic-style option when running `swift` tasks */
476522
get diagnosticsStyle(): DiagnosticStyle {
477-
return vscode.workspace
478-
.getConfiguration("swift")
479-
.get<DiagnosticStyle>("diagnosticsStyle", "default");
523+
return validateStringSetting(
524+
vscode.workspace
525+
.getConfiguration("swift")
526+
.get<DiagnosticStyle>("diagnosticsStyle", "default"),
527+
"swift.diagnosticsStyle"
528+
);
480529
},
481530
/** where to show the build progress for the running task */
482531
get showBuildStatus(): ShowBuildStatusOptions {
@@ -515,9 +564,12 @@ const configuration = {
515564
},
516565
/** background indexing */
517566
get backgroundIndexing(): "on" | "off" | "auto" {
518-
const value = vscode.workspace
519-
.getConfiguration("swift.sourcekit-lsp")
520-
.get("backgroundIndexing", "auto");
567+
const value = validateStringSetting<"on" | "off" | "auto">(
568+
vscode.workspace
569+
.getConfiguration("swift.sourcekit-lsp")
570+
.get("backgroundIndexing", "auto"),
571+
"swift.sourcekit-lsp.backgroundIndexing"
572+
);
521573

522574
// Legacy versions of this setting were a boolean, convert to the new string version.
523575
if (typeof value === "boolean") {
@@ -604,9 +656,12 @@ const configuration = {
604656
},
605657
/** Whether or not the extension should warn about being unable to create symlinks on Windows */
606658
get warnAboutSymlinkCreation(): boolean {
607-
return vscode.workspace
608-
.getConfiguration("swift")
609-
.get<boolean>("warnAboutSymlinkCreation", true);
659+
return validateBooleanSetting(
660+
vscode.workspace
661+
.getConfiguration("swift")
662+
.get<boolean>("warnAboutSymlinkCreation", true),
663+
"swift.warnAboutSymlinkCreation"
664+
);
610665
},
611666
set warnAboutSymlinkCreation(value: boolean) {
612667
void vscode.workspace
@@ -667,12 +722,15 @@ const configuration = {
667722
);
668723
},
669724
parameterHintsEnabled(documentUri: vscode.Uri): boolean {
670-
const enabled = vscode.workspace
671-
.getConfiguration("editor.parameterHints", {
672-
uri: documentUri,
673-
languageId: "swift",
674-
})
675-
.get<boolean>("enabled");
725+
const enabled = validateBooleanSetting(
726+
vscode.workspace
727+
.getConfiguration("editor.parameterHints", {
728+
uri: documentUri,
729+
languageId: "swift",
730+
})
731+
.get<boolean>("enabled", false),
732+
"editor.parameterHints.enabled"
733+
);
676734

677735
return enabled === true;
678736
},
@@ -718,6 +776,16 @@ function validateStringArraySettings(arr: string[], settingName: string): string
718776
return arr;
719777
}
720778

779+
function validateObjectSetting<T extends object>(obj: T, settingName: string): T {
780+
if (typeof obj !== "object" || obj === null) {
781+
throw new ConfigurationValidationError(
782+
settingName,
783+
`The setting \`${settingName}\` must be an object`
784+
);
785+
}
786+
return obj;
787+
}
788+
721789
function computeVscodeVar(varName: string): string | null {
722790
const workspaceFolder = () => {
723791
const activeEditor = vscode.window.activeTextEditor;

0 commit comments

Comments
 (0)