/* tslint:disable */ import * as objects from '@vscode-alt/monaco-editor/esm/vs/base/common/objects'; import * as types from '@vscode-alt/monaco-editor/esm/vs/base/common/types'; import { IConfigurationModel, ConfigurationTarget, IConfigurationService, IConfigurationOverrides, IOverrides, ISettingsSubject } from '../../../interfaces' import { OVERRIDE_PROPERTY_PATTERN } from '../../../constants'; import { URI } from '@vscode-alt/monaco-editor/esm/vs/base/common/uri'; // src/vs/platform/configuration/common/configuration.ts export function isConfigurationOverrides(thing: any): thing is IConfigurationOverrides { return thing && typeof thing === 'object' && (!thing.overrideIdentifier || typeof thing.overrideIdentifier === 'string') && (!thing.resource || (thing.resource instanceof URI || URI.isUri(thing.resource))); //@sri added isURI } /** * @SRI modified to match to the union type of graphql type Settings */ export function ConfigurationTargetToString(configurationTarget: ConfigurationTarget): ISettingsSubject['__typename'] { switch (configurationTarget) { case ConfigurationTarget.USER: return 'UserSettings'; case ConfigurationTarget.USER_LOCAL: return 'LocalUserSettings'; case ConfigurationTarget.USER_REMOTE: return 'RemoteUserSettings'; case ConfigurationTarget.WORKSPACE: return 'WorkspaceSettings'; case ConfigurationTarget.WORKSPACE_FOLDER: return 'FolderSettings'; case ConfigurationTarget.DEFAULT: return 'GlobalSettings'; case ConfigurationTarget.MEMORY: return 'MemorySettings'; } } export function SettingsTypeToConfiguraitonTarget(settings: ISettingsSubject['__typename']) { switch (settings) { case 'UserSettings': return ConfigurationTarget.USER; case 'LocalUserSettings': return ConfigurationTarget.USER_LOCAL; case 'RemoteUserSettings': return ConfigurationTarget.USER_REMOTE; case 'WorkspaceSettings': return ConfigurationTarget.WORKSPACE; case 'FolderSettings': return ConfigurationTarget.WORKSPACE_FOLDER; case 'DefaultSettings': return ConfigurationTarget.DEFAULT; case 'MemorySettings': return ConfigurationTarget.MEMORY; } } export function compare(from: IConfigurationModel, to: IConfigurationModel): { added: string[], removed: string[], updated: string[] } { const added = to.keys.filter(key => from.keys.indexOf(key) === -1); const removed = from.keys.filter(key => to.keys.indexOf(key) === -1); const updated: string[] = []; for (const key of from.keys) { const value1 = getConfigurationValue(from.contents, key); const value2 = getConfigurationValue(to.contents, key); if (!objects.equals(value1, value2)) { updated.push(key); } } return { added, removed, updated }; } // not using currently but stays here for future reference //@sri modified function to take ConfigurationRegistry as second argument input export function toOverrides(raw: any, configurationProperties, conflictReporter: (message: string) => void): IOverrides[] { const overrides: IOverrides[] = []; // const configurationProperties = Registry.Instance.as(Extensions.Configuration).getConfigurationProperties(); for (const key of Object.keys(raw)) { if (OVERRIDE_PROPERTY_PATTERN.test(key)) { const overrideRaw = {}; for (const keyInOverrideRaw in raw[key]) { if (configurationProperties[keyInOverrideRaw] && configurationProperties[keyInOverrideRaw].overridable) { overrideRaw[keyInOverrideRaw] = raw[key][keyInOverrideRaw]; } } overrides.push({ identifiers: [overrideIdentifierFromKey(key).trim()], contents: toValuesTree(overrideRaw, conflictReporter) }); } } return overrides; } export function toValuesTree(properties: { [qualifiedKey: string]: any }, conflictReporter: (message: string) => void): any { const root = Object.create(null); for (let key in properties) { addToValueTree(root, key, properties[key], conflictReporter); } return root; } export function addToValueTree(settingsTreeRoot: any, key: string, value: any, conflictReporter: (message: string) => void): void { const segments = key.split('.'); const last = segments.pop()!; let curr = settingsTreeRoot; for (let i = 0; i < segments.length; i++) { let s = segments[i]; let obj = curr[s]; switch (typeof obj) { case 'undefined': obj = curr[s] = Object.create(null); break; case 'object': break; default: conflictReporter(`Ignoring ${key} as ${segments.slice(0, i + 1).join('.')} is ${JSON.stringify(obj)}`); return; } curr = obj; } if (typeof curr === 'object') { curr[last] = value; // workaround https://github.com/Microsoft/vscode/issues/13606 } else { conflictReporter(`Ignoring ${key} as ${segments.join('.')} is ${JSON.stringify(curr)}`); } } export function removeFromValueTree(valueTree: any, key: string): void { const segments = key.split('.'); doRemoveFromValueTree(valueTree, segments); } function doRemoveFromValueTree(valueTree: any, segments: string[]): void { const first = segments.shift()!; if (segments.length === 0) { // Reached last segment delete valueTree[first]; return; } if (Object.keys(valueTree).indexOf(first) !== -1) { const value = valueTree[first]; if (typeof value === 'object' && !Array.isArray(value)) { doRemoveFromValueTree(value, segments); if (Object.keys(value).length === 0) { delete valueTree[first]; } } } } /** * A helper function to get the configuration value with a specific settings path (e.g. config.some.setting) */ export function getConfigurationValue(config: any, settingPath: string, defaultValue?: T): T { function accessSetting(config: any, path: string[]): any { let current = config; for (const component of path) { if (typeof current !== 'object' || current === null) { return undefined; } current = current[component]; } return current; } //@ sri: customized to prevent from failing due to numberic value from settingPath let result; try{ const path = settingPath.split('.'); result = accessSetting(config, path); } catch(err){ console.warn('received path as number', settingPath); } return typeof result === 'undefined' ? defaultValue : result; } export function merge(base: any, add: any, overwrite: boolean): void { Object.keys(add).forEach(key => { if (key in base) { if (types.isObject(base[key]) && types.isObject(add[key])) { merge(base[key], add[key], overwrite); } else if (overwrite) { base[key] = add[key]; } } else { base[key] = add[key]; } }); } // getConfigurationKeys() exist in the server-core // getDefaultValues() exist in the server core export function overrideIdentifierFromKey(key: string): string { return key.substring(1, key.length - 1); } export function keyFromOverrideIdentifier(overrideIdentifier: string): string { return `[${overrideIdentifier}]`; } export function getMigratedSettingValue(configurationService: IConfigurationService, currentSettingName: string, legacySettingName: string): T { const setting = configurationService.inspect(currentSettingName); const legacySetting = configurationService.inspect(legacySettingName); if (typeof setting.user !== 'undefined' || typeof setting.workspace !== 'undefined' || typeof setting.workspaceFolder !== 'undefined') { return setting.value; } else if (typeof legacySetting.user !== 'undefined' || typeof legacySetting.workspace !== 'undefined' || typeof legacySetting.workspaceFolder !== 'undefined') { return legacySetting.value; } else { return setting.default; } }