configuration.js 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. /*---------------------------------------------------------------------------------------------
  2. * Copyright (c) Microsoft Corporation. All rights reserved.
  3. * Licensed under the MIT License. See License.txt in the project root for license information.
  4. *--------------------------------------------------------------------------------------------*/
  5. import { createDecorator } from '../../instantiation/common/instantiation.js';
  6. export const IConfigurationService = createDecorator('configurationService');
  7. export function toValuesTree(properties, conflictReporter) {
  8. const root = Object.create(null);
  9. for (let key in properties) {
  10. addToValueTree(root, key, properties[key], conflictReporter);
  11. }
  12. return root;
  13. }
  14. export function addToValueTree(settingsTreeRoot, key, value, conflictReporter) {
  15. const segments = key.split('.');
  16. const last = segments.pop();
  17. let curr = settingsTreeRoot;
  18. for (let i = 0; i < segments.length; i++) {
  19. let s = segments[i];
  20. let obj = curr[s];
  21. switch (typeof obj) {
  22. case 'undefined':
  23. obj = curr[s] = Object.create(null);
  24. break;
  25. case 'object':
  26. break;
  27. default:
  28. conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is ${JSON.stringify(obj)}`);
  29. return;
  30. }
  31. curr = obj;
  32. }
  33. if (typeof curr === 'object' && curr !== null) {
  34. try {
  35. curr[last] = value; // workaround https://github.com/microsoft/vscode/issues/13606
  36. }
  37. catch (e) {
  38. conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
  39. }
  40. }
  41. else {
  42. conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`);
  43. }
  44. }
  45. export function removeFromValueTree(valueTree, key) {
  46. const segments = key.split('.');
  47. doRemoveFromValueTree(valueTree, segments);
  48. }
  49. function doRemoveFromValueTree(valueTree, segments) {
  50. const first = segments.shift();
  51. if (segments.length === 0) {
  52. // Reached last segment
  53. delete valueTree[first];
  54. return;
  55. }
  56. if (Object.keys(valueTree).indexOf(first) !== -1) {
  57. const value = valueTree[first];
  58. if (typeof value === 'object' && !Array.isArray(value)) {
  59. doRemoveFromValueTree(value, segments);
  60. if (Object.keys(value).length === 0) {
  61. delete valueTree[first];
  62. }
  63. }
  64. }
  65. }
  66. /**
  67. * A helper function to get the configuration value with a specific settings path (e.g. config.some.setting)
  68. */
  69. export function getConfigurationValue(config, settingPath, defaultValue) {
  70. function accessSetting(config, path) {
  71. let current = config;
  72. for (const component of path) {
  73. if (typeof current !== 'object' || current === null) {
  74. return undefined;
  75. }
  76. current = current[component];
  77. }
  78. return current;
  79. }
  80. const path = settingPath.split('.');
  81. const result = accessSetting(config, path);
  82. return typeof result === 'undefined' ? defaultValue : result;
  83. }