src/vs/platform/configuration/common/configurationModels.ts
1298 LOC · 1198 covered · 100 uncovered · 398 ranges · 2492 concepts · 147 introducers · 1276 tests
File neighbourhood
The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.
Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file
In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.
Graph controls are ready.
Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.
/*---------------------------------------------------------------------------------------------
configurationModels.ts ×92
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as arrays from '../../../base/common/arrays.js';
import { IStringDictionary } from '../../../base/common/collections.js';
import { Emitter, Event } from '../../../base/common/event.js';
import * as json from '../../../base/common/json.js';
import { Disposable } from '../../../base/common/lifecycle.js';
import { getOrSet, ResourceMap } from '../../../base/common/map.js';
import * as objects from '../../../base/common/objects.js';
import { IExtUri } from '../../../base/common/resources.js';
import * as types from '../../../base/common/types.js';
import { URI, UriComponents } from '../../../base/common/uri.js';
import { addToValueTree, ConfigurationTarget, getConfigurationValue, IConfigurationChange, IConfigurationChangeEvent, IConfigurationCompareResult, IConfigurationData, IConfigurationModel, IConfigurationOverrides, IConfigurationUpdateOverrides, IConfigurationValue, IInspectValue, IOverrides, removeFromValueTree, toValuesTree } from './configuration.js';
import { ConfigurationScope, Extensions, IConfigurationPropertySchema, IConfigurationRegistry, overrideIdentifiersFromKey, OVERRIDE_PROPERTY_REGEX, IRegisteredConfigurationPropertySchema } from './configurationRegistry.js';
import { FileOperation, IFileService } from '../../files/common/files.js';
import { ILogService } from '../../log/common/log.js';
import { Registry } from '../../registry/common/platform.js';
import { Workspace } from '../../workspace/common/workspace.js';
return Object.isFrozen(data) ? data : objects.deepFreeze(data);
}
type InspectValue<V> = IInspectValue<V> & { merged?: V };
export class ConfigurationModel implements IConfigurationModel {
static createEmptyModel(logService: ILogService): ConfigurationModel {
return new ConfigurationModel({}, [], [], undefined, logService);
}
private readonly overrideConfigurations = new Map<string, ConfigurationModel>();
constructor(
private readonly _keys: string[],
private readonly _overrides: IOverrides[],
private readonly _raw: IStringDictionary<unknown> | ReadonlyArray<IStringDictionary<unknown> | ConfigurationModel> | undefined,
private readonly logService: ILogService
) {
}
private _rawConfiguration: ConfigurationModel | undefined;
get rawConfiguration(): ConfigurationModel {
if (this._raw) {
const rawConfigurationModels = (Array.isArray(this._raw) ? this._raw : [this._raw]).map(raw => {
configurationModels.ts ×2
if (raw instanceof ConfigurationModel) {
}
parser.parseRaw(raw);
return parser.configurationModel;
});
this._rawConfiguration = rawConfigurationModels.reduce((previous, current) => current === previous ? current : previous.merge(current), rawConfigurationModels[0]);
this._rawConfiguration = this;
}
return this._rawConfiguration;
}
get contents(): IStringDictionary<unknown> {
}
get overrides(): IOverrides[] {
}
get keys(): string[] {
}
get raw(): IStringDictionary<unknown> | IStringDictionary<unknown>[] | undefined {
}
if (Array.isArray(this._raw) && this._raw.every(raw => raw instanceof ConfigurationModel)) {
configurationModels.ts ×3
return undefined;
}
return this._raw as IStringDictionary<unknown> | IStringDictionary<unknown>[];
configurationModels.ts ×1
isEmpty(): boolean {
return this._keys.length === 0 && Object.keys(this._contents).length === 0 && this._overrides.length === 0;
configurationModels.ts ×1
}
getValue<V>(section: string | undefined): V | undefined {
return section ? getConfigurationValue<V>(this.contents, section) : this.contents as V;
configurationModels.ts ×1
}
inspect<V>(section: string | undefined, overrideIdentifier?: string | null): InspectValue<V> {
return {
get value() {
},
return overrideIdentifier ? freeze(that.rawConfiguration.getOverrideValue<V>(section, overrideIdentifier)) : undefined;
configurationModels.ts ×2
},
return freeze(overrideIdentifier ? that.rawConfiguration.override(overrideIdentifier).getValue<V>(section) : that.rawConfiguration.getValue<V>(section));
configurationModels.ts ×1
},
const overrides: { readonly identifiers: string[]; readonly value: V }[] = [];
configurationModels.ts ×2
for (const { contents, identifiers, keys } of that.rawConfiguration.overrides) {
const value = new ConfigurationModel(contents, keys, [], undefined, that.logService).getValue<V>(section);
objects.ts ×1
if (value !== undefined) {
overrides.push({ identifiers, value });
}
}
}
}
getOverrideValue<V>(section: string | undefined, overrideIdentifier: string): V | undefined {
const overrideContents = this.getContentsForOverrideIdentifer(overrideIdentifier);
configurationModels.ts ×2
return overrideContents
? section ? getConfigurationValue<V>(overrideContents, section) : overrideContents as V
configurationModels.ts ×1
getKeysForOverrideIdentifier(identifier: string): string[] {
for (const override of this.overrides) {
if (override.identifiers.includes(identifier)) {
keys.push(...override.keys);
}
}
return arrays.distinct(keys);
}
getAllOverrideIdentifiers(): string[] {
for (const override of this.overrides) {
}
}
override(identifier: string): ConfigurationModel {
let overrideConfigurationModel = this.overrideConfigurations.get(identifier);
configurationModels.ts ×3
if (!overrideConfigurationModel) {
overrideConfigurationModel = this.createOverrideConfigurationModel(identifier);
this.overrideConfigurations.set(identifier, overrideConfigurationModel);
}
return overrideConfigurationModel;
}
merge(...others: ConfigurationModel[]): ConfigurationModel {
const overrides = objects.deepClone(this.overrides);
const keys = [...this.keys];
const raws = this._raw ? Array.isArray(this._raw) ? [...this._raw] : [this._raw] : [this];
for (const other of others) {
raws.push(...(other._raw ? Array.isArray(other._raw) ? other._raw : [other._raw] : [other]));
if (other.isEmpty()) {
}
for (const otherOverride of other.overrides) {
const [override] = overrides.filter(o => arrays.equals(o.identifiers, otherOverride.identifiers));
configurationModels.ts ×3
if (override) {
override.keys.push(...otherOverride.keys);
override.keys = arrays.distinct(override.keys);
}
if (keys.indexOf(key) === -1) {
}
}
return new ConfigurationModel(contents, keys, overrides, !raws.length || raws.every(raw => raw instanceof ConfigurationModel) ? undefined : raws, this.logService);
configurationModels.ts ×2
}
private createOverrideConfigurationModel(identifier: string): ConfigurationModel {
const overrideContents = this.getContentsForOverrideIdentifer(identifier);
configurationModels.ts ×3
if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
return this;
}
const contents: IStringDictionary<unknown> = {};
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
let contentsForKey = this.contents[key];
const overrideContentsForKey = overrideContents[key];
// If there are override contents for the key, clone and merge otherwise use base contents
if (overrideContentsForKey) {
// Clone and merge only if base contents and override contents are of type object otherwise just override
if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
this.mergeContents(contentsForKey as IStringDictionary<unknown>, overrideContentsForKey as IStringDictionary<unknown>);
}
contents[key] = contentsForKey;
}
return new ConfigurationModel(contents, this.keys, this.overrides, undefined, this.logService);
private mergeContents(source: IStringDictionary<unknown>, target: IStringDictionary<unknown>): void {
if (key in source) {
this.mergeContents(source[key] as IStringDictionary<unknown>, target[key] as IStringDictionary<unknown>);
configurationModels.ts ×1
continue;
}
}
}
private getContentsForOverrideIdentifer(identifier: string): IStringDictionary<unknown> | null {
let contentsForIdentifierOnly: IStringDictionary<unknown> | null = null;
configurationModels.ts ×3
let contents: IStringDictionary<unknown> | null = null;
const mergeContents = (contentsToMerge: IStringDictionary<unknown> | null) => {
if (contentsToMerge) {
contents = objects.deepClone(contentsToMerge);
}
}
for (const override of this.overrides) {
if (override.identifiers.length === 1 && override.identifiers[0] === identifier) {
configurationModels.ts ×3
}
// Merge contents of the identifier only at the end to take precedence.
configurationModels.ts ×3
mergeContents(contentsForIdentifierOnly);
return contents;
}
toJSON(): IConfigurationModel {
return {
contents: this.contents,
overrides: this.overrides,
keys: this.keys
};
}
// Update methods
public addValue(key: string, value: unknown): void {
this.updateValue(key, value, true);
}
public setValue(key: string, value: unknown): void {
}
public removeValue(key: string): void {
if (index === -1) {
}
removeFromValueTree(this.contents, key);
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
this.overrides.splice(this.overrides.findIndex(o => arrays.equals(o.identifiers, overrideIdentifiersFromKey(key))), 1);
configurationModels.ts ×1
}
private updateValue(key: string, value: unknown, add: boolean): void {
addToValueTree(this.contents, key, value, e => this.logService.error(e));
configurationModels.ts ×4
add = add || this.keys.indexOf(key) === -1;
if (add) {
}
const overrideContents = this.contents[key] as IStringDictionary<unknown>;
configurationModels.ts ×2
const identifiers = overrideIdentifiersFromKey(key);
const override = {
identifiers,
keys: Object.keys(overrideContents),
contents: toValuesTree(overrideContents, message => this.logService.error(message)),
};
const index = this.overrides.findIndex(o => arrays.equals(o.identifiers, identifiers));
if (index !== -1) {
this.overrides.push(override);
}
}
export interface ConfigurationParseOptions {
skipUnregistered?: boolean;
scopes?: ConfigurationScope[];
skipRestricted?: boolean;
include?: string[];
exclude?: string[];
}
export class ConfigurationModelParser {
private _raw: IStringDictionary<unknown> | null = null;
private _configurationModel: ConfigurationModel | null = null;
private _restrictedConfigurations: string[] = [];
private _parseErrors: json.ParseError[] = [];
constructor(
protected readonly logService: ILogService
) { }
get configurationModel(): ConfigurationModel {
return this._configurationModel || ConfigurationModel.createEmptyModel(this.logService);
configurationModels.ts ×1
}
get restrictedConfigurations(): string[] {
}
get errors(): json.ParseError[] {
return this._parseErrors;
}
public parse(content: string | null | undefined, options?: ConfigurationParseOptions): void {
const raw = this.doParseContent(content);
this.parseRaw(raw, options);
}
}
public reparse(options: ConfigurationParseOptions): void {
this.parseRaw(this._raw, options);
}
}
public parseRaw(raw: IStringDictionary<unknown>, options?: ConfigurationParseOptions): void {
const { contents, keys, overrides, restricted, hasExcludedProperties } = this.doParseRaw(raw, options);
this._configurationModel = new ConfigurationModel(contents, keys, overrides, hasExcludedProperties ? [raw] : undefined /* raw has not changed */, this.logService);
this._restrictedConfigurations = restricted || [];
}
private doParseContent(content: string): IStringDictionary<unknown> {
let currentProperty: string | null = null;
let currentParent: unknown[] | IStringDictionary<unknown> = [];
const previousParents: (unknown[] | IStringDictionary<unknown>)[] = [];
const parseErrors: json.ParseError[] = [];
function onValue(value: unknown) {
currentParent.push(value);
} else if (currentProperty !== null) {
}
const visitor: json.JSONVisitor = {
onObjectBegin: () => {
onValue(object);
previousParents.push(currentParent);
currentParent = object;
currentProperty = null;
},
},
},
onValue(array);
previousParents.push(currentParent);
currentParent = array;
currentProperty = null;
},
},
onError: (error: json.ParseErrorCode, offset: number, length: number) => {
}
if (content) {
json.visit(content, visitor);
raw = (currentParent[0] as IStringDictionary<unknown>) || {};
} catch (e) {
this.logService.error(`Error while parsing settings file ${this._name}: ${e}`);
this._parseErrors = [e as json.ParseError];
}
return raw;
}
protected doParseRaw(raw: IStringDictionary<unknown>, options?: ConfigurationParseOptions): IConfigurationModel & { restricted?: string[]; hasExcludedProperties?: boolean } {
const registry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
configurationModels.ts ×6
const configurationProperties = registry.getConfigurationProperties();
const excludedConfigurationProperties = registry.getExcludedConfigurationProperties();
const filtered = this.filter(raw, configurationProperties, excludedConfigurationProperties, true, options);
raw = filtered.raw;
const contents = toValuesTree(raw, message => this.logService.error(`Conflict in settings file ${this._name}: ${message}`));
const keys = Object.keys(raw);
const overrides = this.toOverrides(raw, message => this.logService.error(`Conflict in settings file ${this._name}: ${message}`));
return { contents, keys, overrides, restricted: filtered.restricted, hasExcludedProperties: filtered.hasExcludedProperties };
}
private filter(properties: IStringDictionary<unknown>, configurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, excludedConfigurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, filterOverriddenProperties: boolean, options?: ConfigurationParseOptions): { raw: IStringDictionary<unknown>; restricted: string[]; hasExcludedProperties: boolean } {
if (!options?.scopes && !options?.skipRestricted && !options?.skipUnregistered && !options?.exclude?.length) {
}
const restricted: string[] = [];
for (const key in properties) {
if (OVERRIDE_PROPERTY_REGEX.test(key) && filterOverriddenProperties) {
const result = this.filter(properties[key] as IStringDictionary<unknown>, configurationProperties, excludedConfigurationProperties, false, options);
configurationModels.ts ×1
raw[key] = result.raw;
hasExcludedProperties = hasExcludedProperties || result.hasExcludedProperties;
restricted.push(...result.restricted);
const propertySchema = configurationProperties[key];
if (propertySchema?.restricted) {
}
if (this.shouldInclude(key, propertySchema, excludedConfigurationProperties, options)) {
configurationModels.ts ×11
}
}
return { raw, restricted, hasExcludedProperties };
private shouldInclude(key: string, propertySchema: IConfigurationPropertySchema | undefined, excludedConfigurationProperties: IStringDictionary<IRegisteredConfigurationPropertySchema>, options: ConfigurationParseOptions): boolean {
}
if (options.include?.includes(key)) {
}
}
}
const schema = propertySchema ?? excludedConfigurationProperties[key];
const scope = schema ? typeof schema.scope !== 'undefined' ? schema.scope : ConfigurationScope.WINDOW : undefined;
configurationModels.ts ×11
if (scope === undefined || options.scopes === undefined) {
}
return options.scopes.includes(scope);
private toOverrides(raw: IStringDictionary<unknown>, conflictReporter: (message: string) => void): IOverrides[] {
for (const key of Object.keys(raw)) {
const rawKey = raw[key] as IStringDictionary<unknown>;
for (const keyInOverrideRaw in rawKey) {
overrideRaw[keyInOverrideRaw] = rawKey[keyInOverrideRaw];
}
overrides.push({
identifiers: overrideIdentifiersFromKey(key),
keys: Object.keys(overrideRaw),
contents: toValuesTree(overrideRaw, conflictReporter)
});
}
}
}
export class UserSettings extends Disposable {
private readonly parser: ConfigurationModelParser;
protected readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChange: Event<void> = this._onDidChange.event;
constructor(
protected parseOptions: ConfigurationParseOptions,
extUri: IExtUri,
private readonly fileService: IFileService,
private readonly logService: ILogService,
) {
super();
this.parser = new ConfigurationModelParser(this.userSettingsResource.toString(), logService);
this._register(this.fileService.watch(extUri.dirname(this.userSettingsResource)));
// Also listen to the resource incase the resource is a symlink - https://github.com/microsoft/vscode/issues/118134
this._register(this.fileService.watch(this.userSettingsResource));
this._register(Event.any(
Event.filter(this.fileService.onDidFilesChange, e => e.contains(this.userSettingsResource)),
Event.filter(this.fileService.onDidRunOperation, e => (e.isOperation(FileOperation.CREATE) || e.isOperation(FileOperation.COPY) || e.isOperation(FileOperation.DELETE) || e.isOperation(FileOperation.WRITE)) && extUri.isEqual(e.resource, userSettingsResource))
)(() => this._onDidChange.fire()));
}
async loadConfiguration(): Promise<ConfigurationModel> {
const content = await this.fileService.readFile(this.userSettingsResource);
this.parser.parse(content.value.toString() || '{}', this.parseOptions);
return this.parser.configurationModel;
} catch (e) {
}
reparse(parseOptions?: ConfigurationParseOptions): ConfigurationModel {
if (parseOptions) {
this.parseOptions = parseOptions;
}
this.parser.reparse(this.parseOptions);
return this.parser.configurationModel;
}
getRestrictedSettings(): string[] {
return this.parser.restrictedConfigurations;
}
class ConfigurationInspectValue<V> implements IConfigurationValue<V> {
constructor(
private readonly overrides: IConfigurationOverrides,
private readonly _value: V | undefined,
readonly overrideIdentifiers: string[] | undefined,
private readonly defaultConfiguration: ConfigurationModel,
private readonly policyConfiguration: ConfigurationModel | undefined,
private readonly applicationConfiguration: ConfigurationModel | undefined,
private readonly userConfiguration: ConfigurationModel,
private readonly localUserConfiguration: ConfigurationModel,
private readonly remoteUserConfiguration: ConfigurationModel,
private readonly workspaceConfiguration: ConfigurationModel | undefined,
private readonly folderConfigurationModel: ConfigurationModel | undefined,
private readonly memoryConfigurationModel: ConfigurationModel
) {
}
get value(): V | undefined {
}
private toInspectValue(inspectValue: IInspectValue<V> | undefined | null): IInspectValue<V> | undefined {
return inspectValue?.value !== undefined || inspectValue?.override !== undefined || inspectValue?.overrides !== undefined ? inspectValue : undefined;
configurationModels.ts ×4
}
private _defaultInspectValue: InspectValue<V> | undefined;
private get defaultInspectValue(): InspectValue<V> {
this._defaultInspectValue = this.defaultConfiguration.inspect<V>(this.key, this.overrides.overrideIdentifier);
}
return this._defaultInspectValue;
}
get defaultValue(): V | undefined {
}
get default(): IInspectValue<V> | undefined {
return this.toInspectValue(this.defaultInspectValue);
}
private _policyInspectValue: InspectValue<V> | undefined | null;
private get policyInspectValue(): InspectValue<V> | null {
this._policyInspectValue = this.policyConfiguration ? this.policyConfiguration.inspect<V>(this.key) : null;
}
return this._policyInspectValue;
}
get policyValue(): V | undefined {
}
get policy(): IInspectValue<V> | undefined {
return this.policyInspectValue?.value !== undefined ? { value: this.policyInspectValue.value } : undefined;
}
private _applicationInspectValue: InspectValue<V> | undefined | null;
private get applicationInspectValue(): InspectValue<V> | null {
this._applicationInspectValue = this.applicationConfiguration ? this.applicationConfiguration.inspect<V>(this.key) : null;
}
return this._applicationInspectValue;
}
get applicationValue(): V | undefined {
}
get application(): IInspectValue<V> | undefined {
return this.toInspectValue(this.applicationInspectValue);
}
private _userInspectValue: InspectValue<V> | undefined;
private get userInspectValue(): InspectValue<V> {
this._userInspectValue = this.userConfiguration.inspect<V>(this.key, this.overrides.overrideIdentifier);
}
return this._userInspectValue;
}
get userValue(): V | undefined {
}
get user(): IInspectValue<V> | undefined {
}
private _userLocalInspectValue: InspectValue<V> | undefined;
private get userLocalInspectValue(): InspectValue<V> {
this._userLocalInspectValue = this.localUserConfiguration.inspect<V>(this.key, this.overrides.overrideIdentifier);
}
return this._userLocalInspectValue;
}
get userLocalValue(): V | undefined {
}
get userLocal(): IInspectValue<V> | undefined {
}
private _userRemoteInspectValue: InspectValue<V> | undefined;
private get userRemoteInspectValue(): InspectValue<V> {
this._userRemoteInspectValue = this.remoteUserConfiguration.inspect<V>(this.key, this.overrides.overrideIdentifier);
}
return this._userRemoteInspectValue;
}
get userRemoteValue(): V | undefined {
}
get userRemote(): IInspectValue<V> | undefined {
}
private _workspaceInspectValue: InspectValue<V> | undefined | null;
private get workspaceInspectValue(): InspectValue<V> | null {
this._workspaceInspectValue = this.workspaceConfiguration ? this.workspaceConfiguration.inspect<V>(this.key, this.overrides.overrideIdentifier) : null;
}
return this._workspaceInspectValue;
}
get workspaceValue(): V | undefined {
}
get workspace(): IInspectValue<V> | undefined {
return this.toInspectValue(this.workspaceInspectValue);
}
private _workspaceFolderInspectValue: InspectValue<V> | undefined | null;
private get workspaceFolderInspectValue(): InspectValue<V> | null {
this._workspaceFolderInspectValue = this.folderConfigurationModel ? this.folderConfigurationModel.inspect<V>(this.key, this.overrides.overrideIdentifier) : null;
}
return this._workspaceFolderInspectValue;
}
get workspaceFolderValue(): V | undefined {
}
get workspaceFolder(): IInspectValue<V> | undefined {
return this.toInspectValue(this.workspaceFolderInspectValue);
}
private _memoryInspectValue: InspectValue<V> | undefined;
private get memoryInspectValue(): InspectValue<V> {
if (this._memoryInspectValue === undefined) {
this._memoryInspectValue = this.memoryConfigurationModel.inspect<V>(this.key, this.overrides.overrideIdentifier);
}
return this._memoryInspectValue;
}
get memoryValue(): V | undefined {
return this.memoryInspectValue.merged;
}
get memory(): IInspectValue<V> | undefined {
return this.toInspectValue(this.memoryInspectValue);
}
}
export class Configuration {
private _workspaceConsolidatedConfiguration: ConfigurationModel | null = null;
private _foldersConsolidatedConfigurations = new ResourceMap<ConfigurationModel>();
constructor(
private _policyConfiguration: ConfigurationModel,
private _applicationConfiguration: ConfigurationModel,
private _localUserConfiguration: ConfigurationModel,
private _remoteUserConfiguration: ConfigurationModel,
private _workspaceConfiguration: ConfigurationModel,
private _folderConfigurations: ResourceMap<ConfigurationModel>,
private _memoryConfiguration: ConfigurationModel,
private _memoryConfigurationByResource: ResourceMap<ConfigurationModel>,
private readonly logService: ILogService
) {
}
getValue(section: string | undefined, overrides: IConfigurationOverrides, workspace: Workspace | undefined): unknown {
const consolidateConfigurationModel = this.getConsolidatedConfigurationModel(section, overrides, workspace);
configurationModels.ts ×1
return consolidateConfigurationModel.getValue(section);
}
updateValue(key: string, value: unknown, overrides: IConfigurationUpdateOverrides = {}): void {
if (overrides.resource) {
memoryConfiguration = this._memoryConfigurationByResource.get(overrides.resource);
if (!memoryConfiguration) {
memoryConfiguration = ConfigurationModel.createEmptyModel(this.logService);
this._memoryConfigurationByResource.set(overrides.resource, memoryConfiguration);
}
memoryConfiguration = this._memoryConfiguration;
}
if (value === undefined) {
memoryConfiguration.removeValue(key);
memoryConfiguration.setValue(key, value);
}
if (!overrides.resource) {
this._workspaceConsolidatedConfiguration = null;
}
}
inspect<C>(key: string, overrides: IConfigurationOverrides, workspace: Workspace | undefined): IConfigurationValue<C> {
const consolidateConfigurationModel = this.getConsolidatedConfigurationModel(key, overrides, workspace);
configurationModels.ts ×5
const folderConfigurationModel = this.getFolderConfigurationModelForResource(overrides.resource, workspace);
const memoryConfigurationModel = overrides.resource ? this._memoryConfigurationByResource.get(overrides.resource) || this._memoryConfiguration : this._memoryConfiguration;
const overrideIdentifiers = new Set<string>();
for (const override of consolidateConfigurationModel.overrides) {
if (consolidateConfigurationModel.getOverrideValue(key, overrideIdentifier) !== undefined) {
overrideIdentifiers.add(overrideIdentifier);
}
}
}
return new ConfigurationInspectValue<C>(
key,
overrides,
consolidateConfigurationModel.getValue<C>(key),
overrideIdentifiers.size ? [...overrideIdentifiers] : undefined,
this._defaultConfiguration,
this._policyConfiguration.isEmpty() ? undefined : this._policyConfiguration,
this.applicationConfiguration.isEmpty() ? undefined : this.applicationConfiguration,
this.userConfiguration,
this.localUserConfiguration,
this.remoteUserConfiguration,
workspace ? this._workspaceConfiguration : undefined,
folderConfigurationModel ? folderConfigurationModel : undefined,
memoryConfigurationModel
);
}
keys(workspace: Workspace | undefined): {
default: string[];
policy: string[];
user: string[];
workspace: string[];
workspaceFolder: string[];
} {
const folderConfigurationModel = this.getFolderConfigurationModelForResource(undefined, workspace);
return {
default: this._defaultConfiguration.keys.slice(0),
policy: this._policyConfiguration.keys.slice(0),
user: this.userConfiguration.keys.slice(0),
workspace: this._workspaceConfiguration.keys.slice(0),
workspaceFolder: folderConfigurationModel ? folderConfigurationModel.keys.slice(0) : []
};
}
updateDefaultConfiguration(defaultConfiguration: ConfigurationModel): void {
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updatePolicyConfiguration(policyConfiguration: ConfigurationModel): void {
this._policyConfiguration = policyConfiguration;
}
updateApplicationConfiguration(applicationConfiguration: ConfigurationModel): void {
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updateLocalUserConfiguration(localUserConfiguration: ConfigurationModel): void {
this._userConfiguration = null;
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updateRemoteUserConfiguration(remoteUserConfiguration: ConfigurationModel): void {
this._remoteUserConfiguration = remoteUserConfiguration;
this._userConfiguration = null;
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updateWorkspaceConfiguration(workspaceConfiguration: ConfigurationModel): void {
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updateFolderConfiguration(resource: URI, configuration: ConfigurationModel): void {
this._foldersConsolidatedConfigurations.delete(resource);
}
deleteFolderConfiguration(resource: URI): void {
this._foldersConsolidatedConfigurations.delete(resource);
}
compareAndUpdateDefaultConfiguration(defaults: ConfigurationModel, keys?: string[]): IConfigurationChange {
if (!keys) {
const { added, updated, removed } = compare(this._defaultConfiguration, defaults);
keys = [...added, ...updated, ...removed];
}
const fromKeys = this._defaultConfiguration.getKeysForOverrideIdentifier(overrideIdentifier);
const toKeys = defaults.getKeysForOverrideIdentifier(overrideIdentifier);
const keys = [
...toKeys.filter(key => fromKeys.indexOf(key) === -1),
...fromKeys.filter(key => toKeys.indexOf(key) === -1),
...fromKeys.filter(key => !objects.equals(this._defaultConfiguration.override(overrideIdentifier).getValue(key), defaults.override(overrideIdentifier).getValue(key)))
];
overrides.push([overrideIdentifier, keys]);
}
}
return { keys, overrides };
}
compareAndUpdatePolicyConfiguration(policyConfiguration: ConfigurationModel): IConfigurationChange {
const { added, updated, removed } = compare(this._policyConfiguration, policyConfiguration);
const keys = [...added, ...updated, ...removed];
if (keys.length) {
this.updatePolicyConfiguration(policyConfiguration);
}
return { keys, overrides: [] };
}
compareAndUpdateApplicationConfiguration(application: ConfigurationModel): IConfigurationChange {
const { added, updated, removed, overrides } = compare(this.applicationConfiguration, application);
configurationModels.ts ×2
const keys = [...added, ...updated, ...removed];
if (keys.length) {
this.updateApplicationConfiguration(application);
}
return { keys, overrides };
}
compareAndUpdateLocalUserConfiguration(user: ConfigurationModel): IConfigurationChange {
const { added, updated, removed, overrides } = compare(this.localUserConfiguration, user);
configurationModels.ts ×2
const keys = [...added, ...updated, ...removed];
if (keys.length) {
}
}
compareAndUpdateRemoteUserConfiguration(user: ConfigurationModel): IConfigurationChange {
const { added, updated, removed, overrides } = compare(this.remoteUserConfiguration, user);
const keys = [...added, ...updated, ...removed];
if (keys.length) {
this.updateRemoteUserConfiguration(user);
}
return { keys, overrides };
}
compareAndUpdateWorkspaceConfiguration(workspaceConfiguration: ConfigurationModel): IConfigurationChange {
const { added, updated, removed, overrides } = compare(this.workspaceConfiguration, workspaceConfiguration);
configurationModels.ts ×2
const keys = [...added, ...updated, ...removed];
if (keys.length) {
this.updateWorkspaceConfiguration(workspaceConfiguration);
}
return { keys, overrides };
}
compareAndUpdateFolderConfiguration(resource: URI, folderConfiguration: ConfigurationModel): IConfigurationChange {
const currentFolderConfiguration = this.folderConfigurations.get(resource);
configurationModels.ts ×1
const { added, updated, removed, overrides } = compare(currentFolderConfiguration, folderConfiguration);
const keys = [...added, ...updated, ...removed];
if (keys.length || !currentFolderConfiguration) {
this.updateFolderConfiguration(resource, folderConfiguration);
}
return { keys, overrides };
}
compareAndDeleteFolderConfiguration(folder: URI): IConfigurationChange {
if (!folderConfig) {
throw new Error('Unknown folder');
}
const { added, updated, removed, overrides } = compare(folderConfig, undefined);
return { keys: [...added, ...updated, ...removed], overrides };
}
get defaults(): ConfigurationModel {
return this._defaultConfiguration;
}
get applicationConfiguration(): ConfigurationModel {
}
private _userConfiguration: ConfigurationModel | null = null;
if (this._remoteUserConfiguration.isEmpty()) {
const merged = this._localUserConfiguration.merge(this._remoteUserConfiguration);
configurationModels.ts ×1
this._userConfiguration = new ConfigurationModel(merged.contents, merged.keys, merged.overrides, undefined, this.logService);
}
return this._userConfiguration;
}
get localUserConfiguration(): ConfigurationModel {
}
get remoteUserConfiguration(): ConfigurationModel {
}
get workspaceConfiguration(): ConfigurationModel {
}
get folderConfigurations(): ResourceMap<ConfigurationModel> {
}
private getConsolidatedConfigurationModel(section: string | undefined, overrides: IConfigurationOverrides, workspace: Workspace | undefined): ConfigurationModel {
let configurationModel = this.getConsolidatedConfigurationModelForResource(overrides, workspace);
configurationModels.ts ×9
if (overrides.overrideIdentifier) {
configurationModel = configurationModel.override(overrides.overrideIdentifier);
configurationModels.ts ×1
}
if (!this._policyConfiguration.isEmpty() && this._policyConfiguration.getValue(section) !== undefined) {
configurationModels.ts ×9
configurationModel = configurationModel.merge();
for (const key of this._policyConfiguration.keys) {
configurationModel.setValue(key, this._policyConfiguration.getValue(key));
}
}
}
private getConsolidatedConfigurationModelForResource({ resource }: IConfigurationOverrides, workspace: Workspace | undefined): ConfigurationModel {
let consolidateConfiguration = this.getWorkspaceConsolidatedConfiguration();
configurationModels.ts ×9
if (workspace && resource) {
if (root) {
consolidateConfiguration = this.getFolderConsolidatedConfiguration(root.uri) || consolidateConfiguration;
}
const memoryConfigurationForResource = this._memoryConfigurationByResource.get(resource);
if (memoryConfigurationForResource) {
consolidateConfiguration = consolidateConfiguration.merge(memoryConfigurationForResource);
}
return consolidateConfiguration;
}
private getWorkspaceConsolidatedConfiguration(): ConfigurationModel {
this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this.applicationConfiguration, this.userConfiguration, this._workspaceConfiguration, this._memoryConfiguration);
}
return this._workspaceConsolidatedConfiguration;
}
private getFolderConsolidatedConfiguration(folder: URI): ConfigurationModel {
let folderConsolidatedConfiguration = this._foldersConsolidatedConfigurations.get(folder);
configurationModels.ts ×3
if (!folderConsolidatedConfiguration) {
const workspaceConsolidateConfiguration = this.getWorkspaceConsolidatedConfiguration();
const folderConfiguration = this._folderConfigurations.get(folder);
if (folderConfiguration) {
folderConsolidatedConfiguration = workspaceConsolidateConfiguration.merge(folderConfiguration);
this._foldersConsolidatedConfigurations.set(folder, folderConsolidatedConfiguration);
} else {
folderConsolidatedConfiguration = workspaceConsolidateConfiguration;
}
}
return folderConsolidatedConfiguration;
}
private getFolderConfigurationModelForResource(resource: URI | null | undefined, workspace: Workspace | undefined): ConfigurationModel | undefined {
const root = workspace.getFolder(resource);
if (root) {
return this._folderConfigurations.get(root.uri);
}
}
}
toData(): IConfigurationData {
defaults: {
contents: this._defaultConfiguration.contents,
overrides: this._defaultConfiguration.overrides,
keys: this._defaultConfiguration.keys,
},
policy: {
contents: this._policyConfiguration.contents,
overrides: this._policyConfiguration.overrides,
keys: this._policyConfiguration.keys
},
application: {
contents: this.applicationConfiguration.contents,
overrides: this.applicationConfiguration.overrides,
keys: this.applicationConfiguration.keys,
raw: Array.isArray(this.applicationConfiguration.raw) ? undefined : this.applicationConfiguration.raw
},
userLocal: {
contents: this.localUserConfiguration.contents,
overrides: this.localUserConfiguration.overrides,
keys: this.localUserConfiguration.keys,
raw: Array.isArray(this.localUserConfiguration.raw) ? undefined : this.localUserConfiguration.raw
},
userRemote: {
contents: this.remoteUserConfiguration.contents,
overrides: this.remoteUserConfiguration.overrides,
keys: this.remoteUserConfiguration.keys,
raw: Array.isArray(this.remoteUserConfiguration.raw) ? undefined : this.remoteUserConfiguration.raw
},
workspace: {
contents: this._workspaceConfiguration.contents,
overrides: this._workspaceConfiguration.overrides,
keys: this._workspaceConfiguration.keys
},
folders: [...this._folderConfigurations.keys()].reduce<[UriComponents, IConfigurationModel][]>((result, folder) => {
const { contents, overrides, keys } = this._folderConfigurations.get(folder)!;
configurationModels.ts ×2
result.push([folder, { contents, overrides, keys }]);
return result;
};
}
allKeys(): string[] {
this._defaultConfiguration.keys.forEach(key => keys.add(key));
this.userConfiguration.keys.forEach(key => keys.add(key));
this._workspaceConfiguration.keys.forEach(key => keys.add(key));
this._folderConfigurations.forEach(folderConfiguration => folderConfiguration.keys.forEach(key => keys.add(key)));
return [...keys.values()];
}
protected allOverrideIdentifiers(): string[] {
this._defaultConfiguration.getAllOverrideIdentifiers().forEach(key => keys.add(key));
this.userConfiguration.getAllOverrideIdentifiers().forEach(key => keys.add(key));
this._workspaceConfiguration.getAllOverrideIdentifiers().forEach(key => keys.add(key));
this._folderConfigurations.forEach(folderConfiguration => folderConfiguration.getAllOverrideIdentifiers().forEach(key => keys.add(key)));
return [...keys.values()];
}
protected getAllKeysForOverrideIdentifier(overrideIdentifier: string): string[] {
this._defaultConfiguration.getKeysForOverrideIdentifier(overrideIdentifier).forEach(key => keys.add(key));
this.userConfiguration.getKeysForOverrideIdentifier(overrideIdentifier).forEach(key => keys.add(key));
this._workspaceConfiguration.getKeysForOverrideIdentifier(overrideIdentifier).forEach(key => keys.add(key));
this._folderConfigurations.forEach(folderConfiguration => folderConfiguration.getKeysForOverrideIdentifier(overrideIdentifier).forEach(key => keys.add(key)));
return [...keys.values()];
}
static parse(data: IConfigurationData, logService: ILogService): Configuration {
const defaultConfiguration = this.parseConfigurationModel(data.defaults, logService);
configurationModels.ts ×3
const policyConfiguration = this.parseConfigurationModel(data.policy, logService);
const applicationConfiguration = this.parseConfigurationModel(data.application, logService);
const userLocalConfiguration = this.parseConfigurationModel(data.userLocal, logService);
const userRemoteConfiguration = this.parseConfigurationModel(data.userRemote, logService);
const workspaceConfiguration = this.parseConfigurationModel(data.workspace, logService);
const folders: ResourceMap<ConfigurationModel> = data.folders.reduce((result, value) => {
result.set(URI.revive(value[0]), this.parseConfigurationModel(value[1], logService));
configurationModels.ts ×2
return result;
return new Configuration(
defaultConfiguration,
policyConfiguration,
applicationConfiguration,
userLocalConfiguration,
userRemoteConfiguration,
workspaceConfiguration,
folders,
ConfigurationModel.createEmptyModel(logService),
new ResourceMap<ConfigurationModel>(),
logService
);
}
private static parseConfigurationModel(model: IConfigurationModel, logService: ILogService): ConfigurationModel {
return new ConfigurationModel(model.contents, model.keys, model.overrides, model.raw, logService);
configurationModels.ts ×3
}
}
export function mergeChanges(...changes: IConfigurationChange[]): IConfigurationChange {
}
}
const overridesMap = new Map<string, Set<string>>();
for (const change of changes) {
change.keys.forEach(key => keysSet.add(key));
change.overrides.forEach(([identifier, keys]) => {
keys.forEach(key => result.add(key));
}
const overrides: [string, string[]][] = [];
overridesMap.forEach((keys, identifier) => overrides.push([identifier, [...keys.values()]]));
return { keys: [...keysSet.values()], overrides };
}
export class ConfigurationChangeEvent implements IConfigurationChangeEvent {
private readonly _marker = '\n';
private readonly _markerCode1 = this._marker.charCodeAt(0);
private readonly _markerCode2 = '.'.charCodeAt(0);
private readonly _affectsConfigStr: string;
readonly affectedKeys = new Set<string>();
source!: ConfigurationTarget;
constructor(
private readonly previous: { workspace?: Workspace; data: IConfigurationData } | undefined,
private readonly currentConfiguraiton: Configuration,
private readonly currentWorkspace: Workspace | undefined,
private readonly logService: ILogService
) {
for (const key of change.keys) {
}
this.affectedKeys.add(key);
}
}
// Example: '\nfoo.bar\nabc.def\n'
this._affectsConfigStr = this._marker;
for (const key of this.affectedKeys) {
}
private _previousConfiguration: Configuration | undefined = undefined;
get previousConfiguration(): Configuration | undefined {
this._previousConfiguration = Configuration.parse(this.previous.data, this.logService);
configurationModels.ts ×1
}
}
affectsConfiguration(section: string, overrides?: IConfigurationOverrides): boolean {
// we have one large string with all keys that have changed. we pad (marker) the section
configurationModels.ts ×3
// and check that either find it padded or before a segment character
const needle = this._marker + section;
const idx = this._affectsConfigStr.indexOf(needle);
if (idx < 0) {
return false;
}
if (pos >= this._affectsConfigStr.length) {
return false;
}
return false;
}
const value1 = this.previousConfiguration ? this.previousConfiguration.getValue(section, overrides, this.previous?.workspace) : undefined;
configurationModels.ts ×3
const value2 = this.currentConfiguraiton.getValue(section, overrides, this.currentWorkspace);
return !objects.equals(value1, value2);
}
function compare(from: ConfigurationModel | undefined, to: ConfigurationModel | undefined): IConfigurationCompareResult {
configurationModels.ts ×8
const { added, removed, updated } = compareConfigurationContents(to?.rawConfiguration, from?.rawConfiguration);
const overrides: [string, string[]][] = [];
const fromOverrideIdentifiers = from?.getAllOverrideIdentifiers() || [];
const toOverrideIdentifiers = to?.getAllOverrideIdentifiers() || [];
if (to) {
const addedOverrideIdentifiers = toOverrideIdentifiers.filter(key => !fromOverrideIdentifiers.includes(key));
configurationModels.ts ×7
for (const identifier of addedOverrideIdentifiers) {
overrides.push([identifier, to.getKeysForOverrideIdentifier(identifier)]);
configurationModels.ts ×1
}
if (from) {
const removedOverrideIdentifiers = fromOverrideIdentifiers.filter(key => !toOverrideIdentifiers.includes(key));
for (const identifier of removedOverrideIdentifiers) {
overrides.push([identifier, from.getKeysForOverrideIdentifier(identifier)]);
configurationModels.ts ×1
}
if (to && from) {
const result = compareConfigurationContents({ contents: from.getOverrideValue(undefined, identifier) || {}, keys: from.getKeysForOverrideIdentifier(identifier) }, { contents: to.getOverrideValue(undefined, identifier) || {}, keys: to.getKeysForOverrideIdentifier(identifier) });
overrides.push([identifier, [...result.added, ...result.removed, ...result.updated]]);
}
}
return { added, removed, updated, overrides };
}
function compareConfigurationContents(to: { keys: string[]; contents: IStringDictionary<unknown> } | undefined, from: { keys: string[]; contents: IStringDictionary<unknown> } | undefined) {
configurationModels.ts ×8
const added = to
? from ? to.keys.filter(key => from.keys.indexOf(key) === -1) : [...to.keys]
configurationModels.ts ×7
? to ? from.keys.filter(key => to.keys.indexOf(key) === -1) : [...from.keys]
if (to && from) {
const value2 = getConfigurationValue(to.contents, key);
if (!objects.equals(value1, value2)) {
}
}