configurationModels.ts 22.0 KB
Newer Older
1 2 3 4 5 6 7 8 9
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/
'use strict';

import * as json from 'vs/base/common/json';
import { StrictResourceMap } from 'vs/base/common/map';
import * as arrays from 'vs/base/common/arrays';
S
Sandeep Somavarapu 已提交
10
import * as types from 'vs/base/common/types';
11 12
import * as objects from 'vs/base/common/objects';
import URI from 'vs/base/common/uri';
S
Sandeep Somavarapu 已提交
13 14
import { OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
import { IOverrides, overrideIdentifierFromKey, addToValueTree, toValuesTree, IConfigurationModel, getConfigurationValue, IConfigurationOverrides, IConfigurationData, getDefaultValues, getConfigurationKeys, IConfigurationChangeEvent, ConfigurationTarget, removeFromValueTree, toOverrides } from 'vs/platform/configuration/common/configuration';
15 16
import { Workspace } from 'vs/platform/workspace/common/workspace';

S
Sandeep Somavarapu 已提交
17
export class ConfigurationModel implements IConfigurationModel {
18

S
Sandeep Somavarapu 已提交
19
	private isFrozen: boolean = false;
20

S
Sandeep Somavarapu 已提交
21 22 23 24 25
	constructor(
		private _contents: any = {},
		private _keys: string[] = [],
		private _overrides: IOverrides[] = []
	) {
26 27
	}

S
Sandeep Somavarapu 已提交
28 29
	get contents(): any {
		return this.checkAndFreeze(this._contents);
30 31
	}

S
Sandeep Somavarapu 已提交
32 33
	get overrides(): IOverrides[] {
		return this.checkAndFreeze(this._overrides);
34 35
	}

S
Sandeep Somavarapu 已提交
36 37
	get keys(): string[] {
		return this.checkAndFreeze(this._keys);
38 39
	}

40 41
	getValue<V>(section: string): V {
		return section ? getConfigurationValue<any>(this.contents, section) : this.contents;
42 43
	}

S
Sandeep Somavarapu 已提交
44
	override(identifier: string): ConfigurationModel {
45 46
		const overrideContents = this.getContentsForOverrideIdentifer(identifier);

47
		if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
S
Sandeep Somavarapu 已提交
48 49
			// If there are no valid overrides, return self
			return this;
50 51 52
		}

		let contents = {};
S
Sandeep Somavarapu 已提交
53
		for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
54

S
Sandeep Somavarapu 已提交
55
			let contentsForKey = this.contents[key];
56 57
			let overrideContentsForKey = overrideContents[key];

58
			// If there are override contents for the key, clone and merge otherwise use base contents
59
			if (overrideContentsForKey) {
60 61
				// Clone and merge only if base contents and override contents are of type object otherwise just override
				if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
J
Johannes Rieken 已提交
62
					contentsForKey = objects.deepClone(contentsForKey);
S
Sandeep Somavarapu 已提交
63
					this.mergeContents(contentsForKey, overrideContentsForKey);
64 65
				} else {
					contentsForKey = overrideContentsForKey;
66 67
				}
			}
68 69

			contents[key] = contentsForKey;
70
		}
S
Sandeep Somavarapu 已提交
71

72
		return new ConfigurationModel(contents);
73 74
	}

S
Sandeep Somavarapu 已提交
75
	merge(...others: ConfigurationModel[]): ConfigurationModel {
J
Johannes Rieken 已提交
76 77
		const contents = objects.deepClone(this.contents);
		const overrides = objects.deepClone(this.overrides);
S
Sandeep Somavarapu 已提交
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
		const keys = [...this.keys];

		for (const other of others) {
			this.mergeContents(contents, other.contents);

			for (const otherOverride of other.overrides) {
				const [override] = overrides.filter(o => arrays.equals(o.identifiers, otherOverride.identifiers));
				if (override) {
					this.mergeContents(override.contents, otherOverride.contents);
				} else {
					overrides.push(otherOverride);
				}
			}
			for (const key of other.keys) {
				if (keys.indexOf(key) === -1) {
					keys.push(key);
				}
			}
		}
		return new ConfigurationModel(contents, keys, overrides);
98 99
	}

S
Sandeep Somavarapu 已提交
100 101 102 103 104 105 106 107 108 109 110 111
	freeze(): ConfigurationModel {
		this.isFrozen = true;
		return this;
	}

	private mergeContents(source: any, target: any): void {
		for (const key of Object.keys(target)) {
			if (key in source) {
				if (types.isObject(source[key]) && types.isObject(target[key])) {
					this.mergeContents(source[key], target[key]);
					continue;
				}
112
			}
J
Johannes Rieken 已提交
113
			source[key] = objects.deepClone(target[key]);
114
		}
S
Sandeep Somavarapu 已提交
115 116 117 118 119 120 121
	}

	private checkAndFreeze<T>(data: T): T {
		if (this.isFrozen && !Object.isFrozen(data)) {
			return objects.deepFreeze(data);
		}
		return data;
122
	}
123 124

	private getContentsForOverrideIdentifer(identifier: string): any {
S
Sandeep Somavarapu 已提交
125
		for (const override of this.overrides) {
126 127 128 129 130 131
			if (override.identifiers.indexOf(identifier) !== -1) {
				return override.contents;
			}
		}
		return null;
	}
132

S
Sandeep Somavarapu 已提交
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
	toJSON(): IConfigurationModel {
		return {
			contents: this.contents,
			overrides: this.overrides,
			keys: this.keys
		};
	}

	// Update methods

	public setValue(key: string, value: any) {
		this.addKey(key);
		addToValueTree(this.contents, key, value, e => { throw new Error(e); });
	}

	public removeValue(key: string): void {
		if (this.removeKey(key)) {
			removeFromValueTree(this.contents, key);
		}
	}

	public setValueInOverrides(overrideIdentifier: string, key: string, value: any): void {
		let override = this.overrides.filter(override => override.identifiers.indexOf(overrideIdentifier) !== -1)[0];
		if (!override) {
			override = { identifiers: [overrideIdentifier], contents: {} };
			this.overrides.push(override);
		}
		addToValueTree(override.contents, key, value, e => { throw new Error(e); });
	}

163
	private addKey(key: string): void {
S
Sandeep Somavarapu 已提交
164
		let index = this.keys.length;
165
		for (let i = 0; i < index; i++) {
S
Sandeep Somavarapu 已提交
166
			if (key.indexOf(this.keys[i]) === 0) {
167 168 169
				index = i;
			}
		}
S
Sandeep Somavarapu 已提交
170
		this.keys.splice(index, 1, key);
171 172 173
	}

	private removeKey(key: string): boolean {
S
Sandeep Somavarapu 已提交
174
		let index = this.keys.indexOf(key);
175
		if (index !== -1) {
S
Sandeep Somavarapu 已提交
176
			this.keys.splice(index, 1);
177 178 179 180
			return true;
		}
		return false;
	}
181 182
}

183
export class DefaultConfigurationModel extends ConfigurationModel {
184 185

	constructor() {
S
Sandeep Somavarapu 已提交
186 187 188 189 190 191
		const contents = getDefaultValues();
		const keys = getConfigurationKeys();
		const overrides: IOverrides[] = [];
		for (const key of Object.keys(contents)) {
			if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
				overrides.push({
192
					identifiers: [overrideIdentifierFromKey(key).trim()],
S
Sandeep Somavarapu 已提交
193 194 195 196 197
					contents: toValuesTree(contents[key], message => console.error(`Conflict in default settings file: ${message}`))
				});
			}
		}
		super(contents, keys, overrides);
198 199 200
	}
}

S
Sandeep Somavarapu 已提交
201
export class ConfigurationModelParser {
202

S
Sandeep Somavarapu 已提交
203 204
	private _configurationModel: ConfigurationModel = null;
	private _parseErrors: any[] = [];
205

S
Sandeep Somavarapu 已提交
206
	constructor(protected readonly _name: string) { }
207

S
Sandeep Somavarapu 已提交
208 209
	get configurationModel(): ConfigurationModel {
		return this._configurationModel || new ConfigurationModel();
210 211
	}

S
Sandeep Somavarapu 已提交
212
	get errors(): any[] {
213 214 215
		return this._parseErrors;
	}

S
Sandeep Somavarapu 已提交
216 217 218 219 220 221 222 223
	public parse(content: string): void {
		const raw = this.parseContent(content);
		const configurationModel = this.parseRaw(raw);
		this._configurationModel = new ConfigurationModel(configurationModel.contents, configurationModel.keys, configurationModel.overrides);
	}

	protected parseContent(content: string): any {
		let raw: any = {};
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
		let currentProperty: string = null;
		let currentParent: any = [];
		let previousParents: any[] = [];
		let parseErrors: json.ParseError[] = [];

		function onValue(value: any) {
			if (Array.isArray(currentParent)) {
				(<any[]>currentParent).push(value);
			} else if (currentProperty) {
				currentParent[currentProperty] = value;
			}
		}

		let visitor: json.JSONVisitor = {
			onObjectBegin: () => {
				let object = {};
				onValue(object);
				previousParents.push(currentParent);
				currentParent = object;
				currentProperty = null;
			},
			onObjectProperty: (name: string) => {
				currentProperty = name;
			},
			onObjectEnd: () => {
				currentParent = previousParents.pop();
			},
			onArrayBegin: () => {
				let array: any[] = [];
				onValue(array);
				previousParents.push(currentParent);
				currentParent = array;
				currentProperty = null;
			},
			onArrayEnd: () => {
				currentParent = previousParents.pop();
			},
			onLiteralValue: onValue,
			onError: (error: json.ParseErrorCode) => {
				parseErrors.push({ error: error });
			}
		};
		if (content) {
			try {
				json.visit(content, visitor);
S
Sandeep Somavarapu 已提交
269
				raw = currentParent[0] || {};
270
			} catch (e) {
S
Sandeep Somavarapu 已提交
271
				console.error(`Error while parsing settings file ${this._name}: ${e}`);
272 273 274
				this._parseErrors = [e];
			}
		}
S
Sandeep Somavarapu 已提交
275 276

		return raw;
277 278
	}

S
Sandeep Somavarapu 已提交
279 280 281 282 283
	protected parseRaw(raw: any): IConfigurationModel {
		const contents = toValuesTree(raw, message => console.error(`Conflict in settings file ${this._name}: ${message}`));
		const keys = Object.keys(raw);
		const overrides: IOverrides[] = toOverrides(raw, message => console.error(`Conflict in settings file ${this._name}: ${message}`));
		return { contents, keys, overrides };
284 285 286
	}
}

287
export class Configuration {
288

S
Sandeep Somavarapu 已提交
289 290
	private _workspaceConsolidatedConfiguration: ConfigurationModel = null;
	private _foldersConsolidatedConfigurations: StrictResourceMap<ConfigurationModel> = new StrictResourceMap<ConfigurationModel>();
291

S
Sandeep Somavarapu 已提交
292 293 294 295 296 297 298
	constructor(
		private _defaultConfiguration: ConfigurationModel,
		private _userConfiguration: ConfigurationModel,
		private _workspaceConfiguration: ConfigurationModel = new ConfigurationModel(),
		private _folderConfigurations: StrictResourceMap<ConfigurationModel> = new StrictResourceMap<ConfigurationModel>(),
		private _memoryConfiguration: ConfigurationModel = new ConfigurationModel(),
		private _memoryConfigurationByResource: StrictResourceMap<ConfigurationModel> = new StrictResourceMap<ConfigurationModel>()) {
299 300
	}

301
	getValue(section: string, overrides: IConfigurationOverrides, workspace: Workspace): any {
S
Sandeep Somavarapu 已提交
302
		const consolidateConfigurationModel = this.getConsolidateConfigurationModel(overrides, workspace);
303
		return consolidateConfigurationModel.getValue(section);
304 305 306
	}

	updateValue(key: string, value: any, overrides: IConfigurationOverrides = {}): void {
307
		let memoryConfiguration: ConfigurationModel;
308
		if (overrides.resource) {
309
			memoryConfiguration = this._memoryConfigurationByResource.get(overrides.resource);
310 311 312 313 314 315 316
			if (!memoryConfiguration) {
				memoryConfiguration = new ConfigurationModel();
				this._memoryConfigurationByResource.set(overrides.resource, memoryConfiguration);
			}
		} else {
			memoryConfiguration = this._memoryConfiguration;
		}
317

318 319 320 321 322
		if (value === void 0) {
			memoryConfiguration.removeValue(key);
		} else {
			memoryConfiguration.setValue(key, value);
		}
323 324

		if (!overrides.resource) {
S
Sandeep Somavarapu 已提交
325
			this._workspaceConsolidatedConfiguration = null;
326
		}
327 328
	}

329
	inspect<C>(key: string, overrides: IConfigurationOverrides, workspace: Workspace): {
330 331 332 333 334 335 336
		default: C,
		user: C,
		workspace: C,
		workspaceFolder: C
		memory?: C
		value: C,
	} {
S
Sandeep Somavarapu 已提交
337 338
		const consolidateConfigurationModel = this.getConsolidateConfigurationModel(overrides, workspace);
		const folderConfigurationModel = this.getFolderConfigurationModelForResource(overrides.resource, workspace);
339
		const memoryConfigurationModel = overrides.resource ? this._memoryConfigurationByResource.get(overrides.resource) || this._memoryConfiguration : this._memoryConfiguration;
S
Sandeep Somavarapu 已提交
340
		return {
341 342 343 344 345
			default: getConfigurationValue<C>(overrides.overrideIdentifier ? this._defaultConfiguration.freeze().override(overrides.overrideIdentifier).contents : this._defaultConfiguration.freeze().contents, key),
			user: getConfigurationValue<C>(overrides.overrideIdentifier ? this._userConfiguration.freeze().override(overrides.overrideIdentifier).contents : this._userConfiguration.freeze().contents, key),
			workspace: workspace ? getConfigurationValue<C>(overrides.overrideIdentifier ? this._workspaceConfiguration.freeze().override(overrides.overrideIdentifier).contents : this._workspaceConfiguration.freeze().contents, key) : void 0, //Check on workspace exists or not because _workspaceConfiguration is never null
			workspaceFolder: folderConfigurationModel ? getConfigurationValue<C>(overrides.overrideIdentifier ? folderConfigurationModel.freeze().override(overrides.overrideIdentifier).contents : folderConfigurationModel.freeze().contents, key) : void 0,
			memory: getConfigurationValue<C>(overrides.overrideIdentifier ? memoryConfigurationModel.freeze().override(overrides.overrideIdentifier).contents : memoryConfigurationModel.freeze().contents, key),
346
			value: getConfigurationValue<C>(consolidateConfigurationModel.contents, key)
S
Sandeep Somavarapu 已提交
347
		};
348 349
	}

S
Sandeep Somavarapu 已提交
350
	keys(workspace: Workspace): {
351 352 353 354 355
		default: string[];
		user: string[];
		workspace: string[];
		workspaceFolder: string[];
	} {
S
Sandeep Somavarapu 已提交
356
		const folderConfigurationModel = this.getFolderConfigurationModelForResource(null, workspace);
J
Johannes Rieken 已提交
357
		return objects.deepClone({
358 359 360 361 362
			default: this._defaultConfiguration.freeze().keys,
			user: this._userConfiguration.freeze().keys,
			workspace: this._workspaceConfiguration.freeze().keys,
			workspaceFolder: folderConfigurationModel ? folderConfigurationModel.freeze().keys : []
		});
S
Sandeep Somavarapu 已提交
363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414
	}

	updateDefaultConfiguration(defaultConfiguration: ConfigurationModel): void {
		this._defaultConfiguration = defaultConfiguration;
		this._workspaceConsolidatedConfiguration = null;
		this._foldersConsolidatedConfigurations.clear();
	}

	updateUserConfiguration(userConfiguration: ConfigurationModel): void {
		this._userConfiguration = userConfiguration;
		this._workspaceConsolidatedConfiguration = null;
		this._foldersConsolidatedConfigurations.clear();
	}

	updateWorkspaceConfiguration(workspaceConfiguration: ConfigurationModel): void {
		this._workspaceConfiguration = workspaceConfiguration;
		this._workspaceConsolidatedConfiguration = null;
		this._foldersConsolidatedConfigurations.clear();
	}

	updateFolderConfiguration(resource: URI, configuration: ConfigurationModel): void {
		this._folderConfigurations.set(resource, configuration);
		this._foldersConsolidatedConfigurations.delete(resource);
	}

	deleteFolderConfiguration(resource: URI): void {
		this.folders.delete(resource);
		this._foldersConsolidatedConfigurations.delete(resource);
	}

	get defaults(): ConfigurationModel {
		return this._defaultConfiguration;
	}

	get user(): ConfigurationModel {
		return this._userConfiguration;
	}

	get workspace(): ConfigurationModel {
		return this._workspaceConfiguration;
	}

	protected get folders(): StrictResourceMap<ConfigurationModel> {
		return this._folderConfigurations;
	}

	private get memory(): ConfigurationModel {
		return this._memoryConfiguration;
	}

	private get memoryByResource(): StrictResourceMap<ConfigurationModel> {
		return this._memoryConfigurationByResource;
415 416
	}

M
Matt Bierner 已提交
417
	private getConsolidateConfigurationModel(overrides: IConfigurationOverrides, workspace: Workspace): ConfigurationModel {
S
Sandeep Somavarapu 已提交
418
		let configurationModel = this.getConsolidatedConfigurationModelForResource(overrides, workspace);
419
		return overrides.overrideIdentifier ? configurationModel.override(overrides.overrideIdentifier) : configurationModel;
420 421
	}

S
Sandeep Somavarapu 已提交
422
	private getConsolidatedConfigurationModelForResource({ resource }: IConfigurationOverrides, workspace: Workspace): ConfigurationModel {
S
Sandeep Somavarapu 已提交
423
		let consolidateConfiguration = this.getWorkspaceConsolidatedConfiguration();
424

S
Sandeep Somavarapu 已提交
425 426 427 428 429 430 431 432 433
		if (workspace && resource) {
			const root = workspace.getFolder(resource);
			if (root) {
				consolidateConfiguration = this.getFolderConsolidatedConfiguration(root.uri) || consolidateConfiguration;
			}
			const memoryConfigurationForResource = this._memoryConfigurationByResource.get(resource);
			if (memoryConfigurationForResource) {
				consolidateConfiguration = consolidateConfiguration.merge(memoryConfigurationForResource);
			}
434 435
		}

S
Sandeep Somavarapu 已提交
436 437
		return consolidateConfiguration;
	}
438

S
Sandeep Somavarapu 已提交
439 440 441
	private getWorkspaceConsolidatedConfiguration(): ConfigurationModel {
		if (!this._workspaceConsolidatedConfiguration) {
			this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this._userConfiguration).merge(this._workspaceConfiguration).merge(this._memoryConfiguration).freeze();
442
		}
S
Sandeep Somavarapu 已提交
443 444
		return this._workspaceConsolidatedConfiguration;
	}
445

S
Sandeep Somavarapu 已提交
446 447 448 449 450 451 452
	private getFolderConsolidatedConfiguration(folder: URI): ConfigurationModel {
		let folderConsolidatedConfiguration = this._foldersConsolidatedConfigurations.get(folder);
		if (!folderConsolidatedConfiguration) {
			folderConsolidatedConfiguration = this.getWorkspaceConsolidatedConfiguration().merge(this._folderConfigurations.get(folder)).freeze();
			this._foldersConsolidatedConfigurations.set(folder, folderConsolidatedConfiguration);
		}
		return folderConsolidatedConfiguration;
453 454
	}

S
Sandeep Somavarapu 已提交
455
	private getFolderConfigurationModelForResource(resource: URI, workspace: Workspace): ConfigurationModel {
S
Sandeep Somavarapu 已提交
456 457 458 459 460
		if (workspace && resource) {
			const root = workspace.getFolder(resource);
			if (root) {
				return this._folderConfigurations.get(root.uri);
			}
461
		}
S
Sandeep Somavarapu 已提交
462
		return null;
463 464
	}

S
Sandeep Somavarapu 已提交
465
	toData(): IConfigurationData {
466 467
		return {
			defaults: {
S
Sandeep Somavarapu 已提交
468 469 470
				contents: this._defaultConfiguration.contents,
				overrides: this._defaultConfiguration.overrides,
				keys: this._defaultConfiguration.keys
471 472
			},
			user: {
S
Sandeep Somavarapu 已提交
473 474 475
				contents: this._userConfiguration.contents,
				overrides: this._userConfiguration.overrides,
				keys: this._userConfiguration.keys
476 477 478 479 480 481
			},
			workspace: {
				contents: this._workspaceConfiguration.contents,
				overrides: this._workspaceConfiguration.overrides,
				keys: this._workspaceConfiguration.keys
			},
S
Sandeep Somavarapu 已提交
482 483
			folders: this._folderConfigurations.keys().reduce((result, folder) => {
				const { contents, overrides, keys } = this._folderConfigurations.get(folder);
484 485 486 487 488 489
				result[folder.toString()] = { contents, overrides, keys };
				return result;
			}, Object.create({}))
		};
	}

S
Sandeep Somavarapu 已提交
490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
	allKeys(workspace: Workspace): string[] {
		let keys = this.keys(workspace);
		let all = [...keys.default];
		const addKeys = (keys) => {
			for (const key of keys) {
				if (all.indexOf(key) === -1) {
					all.push(key);
				}
			}
		};
		addKeys(keys.user);
		addKeys(keys.workspace);
		for (const resource of this.folders.keys()) {
			addKeys(this.folders.get(resource).keys);
		}
		return all;
	}

S
Sandeep Somavarapu 已提交
508
	public static parse(data: IConfigurationData): Configuration {
509 510 511
		const defaultConfiguration = Configuration.parseConfigurationModel(data.defaults);
		const userConfiguration = Configuration.parseConfigurationModel(data.user);
		const workspaceConfiguration = Configuration.parseConfigurationModel(data.workspace);
512
		const folders: StrictResourceMap<ConfigurationModel> = Object.keys(data.folders).reduce((result, key) => {
513 514
			result.set(URI.parse(key), Configuration.parseConfigurationModel(data.folders[key]));
			return result;
515
		}, new StrictResourceMap<ConfigurationModel>());
S
Sandeep Somavarapu 已提交
516
		return new Configuration(defaultConfiguration, userConfiguration, workspaceConfiguration, folders);
517 518
	}

S
Sandeep Somavarapu 已提交
519
	private static parseConfigurationModel(model: IConfigurationModel): ConfigurationModel {
S
Sandeep Somavarapu 已提交
520
		return new ConfigurationModel(model.contents, model.keys, model.overrides).freeze();
521
	}
522 523
}

524
export class AbstractConfigurationChangeEvent {
525

526 527 528
	protected doesConfigurationContains(configuration: ConfigurationModel, config: string): boolean {
		let changedKeysTree = configuration.contents;
		let requestedTree = toValuesTree({ [config]: true }, () => { });
529

530 531 532 533 534 535 536 537 538 539 540 541 542
		let key;
		while (typeof requestedTree === 'object' && (key = Object.keys(requestedTree)[0])) { // Only one key should present, since we added only one property
			changedKeysTree = changedKeysTree[key];
			if (!changedKeysTree) {
				return false; // Requested tree is not found
			}
			requestedTree = requestedTree[key];
		}
		return true;
	}

	protected updateKeys(configuration: ConfigurationModel, keys: string[], resource?: URI): void {
		for (const key of keys) {
S
Sandeep Somavarapu 已提交
543
			configuration.setValue(key, {});
544 545 546 547 548
		}
	}
}

export class ConfigurationChangeEvent extends AbstractConfigurationChangeEvent implements IConfigurationChangeEvent {
549 550 551 552

	private _source: ConfigurationTarget;
	private _sourceConfig: any;

553
	constructor(
554 555
		private _changedConfiguration: ConfigurationModel = new ConfigurationModel(),
		private _changedConfigurationByResource: StrictResourceMap<ConfigurationModel> = new StrictResourceMap<ConfigurationModel>()) {
556 557 558
		super();
	}

S
Sandeep Somavarapu 已提交
559
	get changedConfiguration(): IConfigurationModel {
560 561 562
		return this._changedConfiguration;
	}

S
Sandeep Somavarapu 已提交
563
	get changedConfigurationByResource(): StrictResourceMap<IConfigurationModel> {
564 565 566
		return this._changedConfigurationByResource;
	}

567 568
	change(event: ConfigurationChangeEvent): ConfigurationChangeEvent;
	change(keys: string[], resource?: URI): ConfigurationChangeEvent;
569 570
	change(arg1: any, arg2?: any): ConfigurationChangeEvent {
		if (arg1 instanceof ConfigurationChangeEvent) {
571
			this._changedConfiguration = this._changedConfiguration.merge(arg1._changedConfiguration);
S
Sandeep Somavarapu 已提交
572
			for (const resource of arg1._changedConfigurationByResource.keys()) {
573
				let changedConfigurationByResource = this.getOrSetChangedConfigurationForResource(resource);
574 575
				changedConfigurationByResource = changedConfigurationByResource.merge(arg1._changedConfigurationByResource.get(resource));
				this._changedConfigurationByResource.set(resource, changedConfigurationByResource);
576
			}
577 578
		} else {
			this.changeWithKeys(arg1, arg2);
579
		}
580
		return this;
581 582 583 584 585 586 587 588 589
	}

	telemetryData(source: ConfigurationTarget, sourceConfig: any): ConfigurationChangeEvent {
		this._source = source;
		this._sourceConfig = sourceConfig;
		return this;
	}

	get affectedKeys(): string[] {
590 591
		const keys = [...this._changedConfiguration.keys];
		this._changedConfigurationByResource.forEach(model => keys.push(...model.keys));
S
Sandeep Somavarapu 已提交
592
		return arrays.distinct(keys);
593 594 595 596 597 598 599 600 601 602
	}

	get source(): ConfigurationTarget {
		return this._source;
	}

	get sourceConfig(): any {
		return this._sourceConfig;
	}

S
Sandeep Somavarapu 已提交
603
	affectsConfiguration(config: string, resource?: URI): boolean {
604
		let configurationModelsToSearch: ConfigurationModel[] = [this._changedConfiguration];
605

606
		if (resource) {
607
			let model = this._changedConfigurationByResource.get(resource);
608 609
			if (model) {
				configurationModelsToSearch.push(model);
610
			}
611
		} else {
612
			configurationModelsToSearch.push(...this._changedConfigurationByResource.values());
613
		}
614

615 616 617
		for (const configuration of configurationModelsToSearch) {
			if (this.doesConfigurationContains(configuration, config)) {
				return true;
618 619
			}
		}
620

621 622 623
		return false;
	}

624
	private changeWithKeys(keys: string[], resource?: URI): void {
625
		let changedConfiguration = resource ? this.getOrSetChangedConfigurationForResource(resource) : this._changedConfiguration;
626
		this.updateKeys(changedConfiguration, keys);
627 628 629
	}

	private getOrSetChangedConfigurationForResource(resource: URI): ConfigurationModel {
630
		let changedConfigurationByResource = this._changedConfigurationByResource.get(resource);
631 632
		if (!changedConfigurationByResource) {
			changedConfigurationByResource = new ConfigurationModel();
633
			this._changedConfigurationByResource.set(resource, changedConfigurationByResource);
634 635 636
		}
		return changedConfigurationByResource;
	}
J
Johannes Rieken 已提交
637
}