提交 79282cda 编写于 作者: S Sandeep Somavarapu

#28538 Create a configuration model that can retrieve and merge contents

上级 850c8391
......@@ -4,6 +4,9 @@
*--------------------------------------------------------------------------------------------*/
import { TPromise } from 'vs/base/common/winjs.base';
import * as arrays from 'vs/base/common/arrays';
import * as types from 'vs/base/common/types';
import * as objects from 'vs/base/common/objects';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import Event from 'vs/base/common/event';
......@@ -101,18 +104,76 @@ export function getConfigurationValue<T>(config: any, settingPath: string, defau
return typeof result === 'undefined' ? defaultValue : result;
}
export interface IConfigModel<T> {
contents: T;
overrides: IOverrides<T>[];
keys: string[];
errors: any[];
merge(other: IConfigModel<T>, overwrite?: boolean): IConfigModel<T>;
getContentsFor<V>(section: string): V;
configWithOverrides<V>(identifier: string, section?: string): IConfigModel<V>;
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];
}
});
}
export interface IOverrides<T> {
contents: T;
identifiers: string[];
}
export class Configuration<T> {
protected _keys: string[] = [];
constructor(protected _contents: T = <T>{}, protected _overrides: IOverrides<T>[] = []) {
}
public get contents(): T {
return this._contents;
}
public get keys(): string[] {
return this._keys;
}
public getContentsFor<V>(section: string): V {
return objects.clone(this.contents[section]);
}
public override<V>(identifier: string): Configuration<V> {
const result = new Configuration<V>();
const contents = objects.clone<any>(this.contents);
if (this._overrides) {
for (const override of this._overrides) {
if (override.identifiers.indexOf(identifier) !== -1) {
merge(contents, override.contents, true);
}
}
}
result._contents = contents;
return result;
}
public merge(other: Configuration<T>, overwrite: boolean = true): Configuration<T> {
const mergedModel = new Configuration<T>();
this.doMerge(mergedModel, this, overwrite);
this.doMerge(mergedModel, other, overwrite);
return mergedModel;
}
protected doMerge(source: Configuration<T>, target: Configuration<T>, overwrite: boolean = true) {
merge(source.contents, objects.clone(target.contents), overwrite);
const overrides = objects.clone(source._overrides);
for (const override of target._overrides) {
const [sourceOverride] = overrides.filter(o => arrays.equals(o.identifiers, override.identifiers));
if (sourceOverride) {
merge(sourceOverride.contents, override.contents, overwrite);
} else {
overrides.push(override);
}
}
source._overrides = overrides;
}
}
\ No newline at end of file
......@@ -5,12 +5,9 @@
'use strict';
import { Registry } from 'vs/platform/platform';
import * as types from 'vs/base/common/types';
import * as json from 'vs/base/common/json';
import * as objects from 'vs/base/common/objects';
import * as arrays from 'vs/base/common/arrays';
import { IConfigurationRegistry, Extensions, OVERRIDE_PROPERTY_PATTERN } from 'vs/platform/configuration/common/configurationRegistry';
import { IConfigModel, IOverrides } from 'vs/platform/configuration/common/configuration';
import { Configuration, IOverrides } from 'vs/platform/configuration/common/configuration';
export function getDefaultValues(): any {
const valueTreeRoot: any = Object.create(null);
......@@ -68,92 +65,45 @@ export function getConfigurationKeys(): string[] {
return Object.keys(properties);
}
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];
}
});
export class DefaultConfiguration<T> extends Configuration<T> {
constructor() {
super(getDefaultValues());
this._keys = getConfigurationKeys();
this._overrides = Object.keys(this._contents)
.filter(key => OVERRIDE_PROPERTY_PATTERN.test(key))
.map(key => {
return <IOverrides<any>>{
identifiers: [overrideIdentifierFromKey(key).trim()],
contents: toValuesTree(this._contents[key], message => console.error(`Conflict in default settings file: ${message}`))
};
});
}
public get keys(): string[] {
return this._keys;
}
}
interface Overrides<T> extends IOverrides<T> {
raw: any;
}
export class ConfigModel<T> implements IConfigModel<T> {
export class CustomConfiguration<T> extends Configuration<T> {
protected _contents: T = <T>{};
protected _overrides: IOverrides<T>[] = [];
protected _keys: string[] = [];
protected _parseErrors: any[] = [];
constructor(content: string = '', private name: string = '') {
super();
if (content) {
this.update(content);
}
}
public get contents(): T {
return this._contents;
}
public get overrides(): IOverrides<T>[] {
return this._overrides;
}
public get keys(): string[] {
return this._keys;
}
public get errors(): any[] {
return this._parseErrors;
}
public merge(other: IConfigModel<T>, overwrite: boolean = true): ConfigModel<T> {
const mergedModel = new ConfigModel<T>(null);
this.doMerge(mergedModel, this, overwrite);
this.doMerge(mergedModel, other, overwrite);
return mergedModel;
}
protected doMerge(source: ConfigModel<T>, target: IConfigModel<T>, overwrite: boolean = true) {
merge(source.contents, objects.clone(target.contents), overwrite);
const overrides = objects.clone(source.overrides);
for (const override of target.overrides) {
const [sourceOverride] = overrides.filter(o => arrays.equals(o.identifiers, override.identifiers));
if (sourceOverride) {
merge(sourceOverride.contents, override.contents, overwrite);
} else {
overrides.push(override);
}
}
source._overrides = overrides;
}
public getContentsFor<V>(section: string): V {
return objects.clone(this.contents[section]);
}
public configWithOverrides<V>(identifier: string): ConfigModel<V> {
const result = new ConfigModel<V>(null);
const contents = objects.clone<any>(this.contents);
if (this.overrides) {
for (const override of this.overrides) {
if (override.identifiers.indexOf(identifier) !== -1) {
merge(contents, override.contents, true);
}
}
}
result._contents = contents;
return result;
}
public update(content: string): void {
let parsed: T = <T>{};
let overrides: Overrides<T>[] = [];
......@@ -243,31 +193,6 @@ export class ConfigModel<T> implements IConfigModel<T> {
}
}
export class DefaultConfigModel<T> extends ConfigModel<T> {
constructor() {
super(null);
this.update();
}
public get keys(): string[] {
return this._keys;
}
public update(): void {
this._contents = getDefaultValues(); // defaults coming from contributions to registries
this._keys = getConfigurationKeys();
this._overrides = Object.keys(this._contents)
.filter(key => OVERRIDE_PROPERTY_PATTERN.test(key))
.map(key => {
return <IOverrides<any>>{
identifiers: [overrideIdentifierFromKey(key).trim()],
contents: toValuesTree(this._contents[key], message => console.error(`Conflict in default settings file: ${message}`))
};
});
}
}
export function overrideIdentifierFromKey(key: string): string {
return key.substring(1, key.length - 1);
}
......
......@@ -10,15 +10,15 @@ import { ConfigWatcher } from 'vs/base/node/config';
import { Registry } from 'vs/platform/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { IDisposable, toDisposable, Disposable } from 'vs/base/common/lifecycle';
import { ConfigurationSource, IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, getConfigurationValue, IConfigurationKeys, IConfigModel, IConfigurationOptions } from 'vs/platform/configuration/common/configuration';
import { ConfigModel, DefaultConfigModel } from 'vs/platform/configuration/common/model';
import { ConfigurationSource, IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, getConfigurationValue, IConfigurationKeys, Configuration, IConfigurationOptions } from 'vs/platform/configuration/common/configuration';
import { CustomConfiguration, DefaultConfiguration } from 'vs/platform/configuration/common/model';
import Event, { Emitter } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
export interface ICache<T> {
defaults: IConfigModel<T>;
user: IConfigModel<T>;
consolidated: IConfigModel<any>;
defaults: Configuration<T>;
user: Configuration<T>;
consolidated: Configuration<any>;
}
export class ConfigurationService<T> extends Disposable implements IConfigurationService, IDisposable {
......@@ -26,7 +26,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
_serviceBrand: any;
private cache: ICache<T>;
private userConfigModelWatcher: ConfigWatcher<IConfigModel<T>>;
private userConfigModelWatcher: ConfigWatcher<Configuration<T>>;
private _onDidUpdateConfiguration: Emitter<IConfigurationServiceEvent> = this._register(new Emitter<IConfigurationServiceEvent>());
public readonly onDidUpdateConfiguration: Event<IConfigurationServiceEvent> = this._onDidUpdateConfiguration.event;
......@@ -37,8 +37,8 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
super();
this.userConfigModelWatcher = new ConfigWatcher(environmentService.appSettingsPath, {
changeBufferDelay: 300, defaultConfig: new ConfigModel<T>(null, environmentService.appSettingsPath), parse: (content: string, parseErrors: any[]) => {
const userConfigModel = new ConfigModel<T>(content, environmentService.appSettingsPath);
changeBufferDelay: 300, defaultConfig: new CustomConfiguration<T>(null, environmentService.appSettingsPath), parse: (content: string, parseErrors: any[]) => {
const userConfigModel = new CustomConfiguration<T>(content, environmentService.appSettingsPath);
parseErrors = [...userConfigModel.errors];
return userConfigModel;
}
......@@ -77,7 +77,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
public getConfiguration<C>(arg?: any): C {
const options = this.toOptions(arg);
const cache = this.getCache();
const configModel = options.overrideIdentifier ? cache.consolidated.configWithOverrides<C>(options.overrideIdentifier) : cache.consolidated;
const configModel = options.overrideIdentifier ? cache.consolidated.override<C>(options.overrideIdentifier) : cache.consolidated;
return options.section ? configModel.getContentsFor<C>(options.section) : configModel.contents;
}
......@@ -86,9 +86,9 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
// make sure to clone the configuration so that the receiver does not tamper with the values
return {
default: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.defaults.configWithOverrides(overrideIdentifier).contents : cache.defaults.contents, key)),
user: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.user.configWithOverrides(overrideIdentifier).contents : cache.user.contents, key)),
value: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.consolidated.configWithOverrides(overrideIdentifier).contents : cache.consolidated.contents, key))
default: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.defaults.override(overrideIdentifier).contents : cache.defaults.contents, key)),
user: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.user.override(overrideIdentifier).contents : cache.user.contents, key)),
value: objects.clone(getConfigurationValue<C>(overrideIdentifier ? cache.consolidated.override(overrideIdentifier).contents : cache.consolidated.contents, key))
};
}
......@@ -116,7 +116,7 @@ export class ConfigurationService<T> extends Disposable implements IConfiguratio
}
private consolidateConfigurations(): ICache<T> {
const defaults = new DefaultConfigModel<T>();
const defaults = new DefaultConfiguration<T>();
const user = this.userConfigModelWatcher.getConfig();
const consolidated = defaults.merge(user);
return { defaults, user, consolidated };
......
/*---------------------------------------------------------------------------------------------
* 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 assert from 'assert';
import { Configuration, merge } from 'vs/platform/configuration/common/configuration';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/platform';
suite('Configuration', () => {
suiteSetup(() => {
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
'id': 'a',
'order': 1,
'title': 'a',
'type': 'object',
'properties': {
'a': {
'description': 'a',
'type': 'boolean',
'default': true,
'overridable': true
}
}
});
});
test('simple merge', () => {
let base = { 'a': 1, 'b': 2 };
merge(base, { 'a': 3, 'c': 4 }, true);
assert.deepEqual(base, { 'a': 3, 'b': 2, 'c': 4 });
base = { 'a': 1, 'b': 2 };
merge(base, { 'a': 3, 'c': 4 }, false);
assert.deepEqual(base, { 'a': 1, 'b': 2, 'c': 4 });
});
test('Recursive merge', () => {
const base = { 'a': { 'b': 1 } };
merge(base, { 'a': { 'b': 2 } }, true);
assert.deepEqual(base, { 'a': { 'b': 2 } });
});
test('simple merge using configuration', () => {
let base = new Configuration<any>({ 'a': 1, 'b': 2 });
let add = new Configuration<any>({ 'a': 3, 'c': 4 });
let result = base.merge(add);
assert.deepEqual(result.contents, { 'a': 3, 'b': 2, 'c': 4 });
});
test('Recursive merge using config models', () => {
let base = new Configuration({ 'a': { 'b': 1 } });
let add = new Configuration({ 'a': { 'b': 2 } });
let result = base.merge(add);
assert.deepEqual(result.contents, { 'a': { 'b': 2 } });
});
test('Test contents while getting an existing property', () => {
let testObject = new Configuration({ 'a': 1 });
assert.deepEqual(testObject.getContentsFor('a'), 1);
testObject = new Configuration<any>({ 'a': { 'b': 1 } });
assert.deepEqual(testObject.getContentsFor('a'), { 'b': 1 });
});
test('Test contents are undefined for non existing properties', () => {
const testObject = new Configuration({ awesome: true });
assert.deepEqual(testObject.getContentsFor('unknownproperty'), undefined);
});
test('Test override gives all content merged with overrides', () => {
const testObject = new Configuration<any>({ 'a': 1, 'c': 1 }, [{ identifiers: ['b'], contents: { 'a': 2 } }]);
assert.deepEqual(testObject.override('b').contents, { 'a': 2, 'c': 1 });
});
});
\ No newline at end of file
......@@ -5,11 +5,11 @@
'use strict';
import * as assert from 'assert';
import * as model from 'vs/platform/configuration/common/model';
import { CustomConfiguration, DefaultConfiguration } from 'vs/platform/configuration/common/model';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/platform';
suite('ConfigurationService - Model', () => {
suite('Configuration', () => {
suiteSetup(() => {
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
......@@ -28,62 +28,47 @@ suite('ConfigurationService - Model', () => {
});
});
test('simple merge', () => {
let base = { 'a': 1, 'b': 2 };
model.merge(base, { 'a': 3, 'c': 4 }, true);
assert.deepEqual(base, { 'a': 3, 'b': 2, 'c': 4 });
base = { 'a': 1, 'b': 2 };
model.merge(base, { 'a': 3, 'c': 4 }, false);
assert.deepEqual(base, { 'a': 1, 'b': 2, 'c': 4 });
});
test('Recursive merge', () => {
const base = { 'a': { 'b': 1 } };
model.merge(base, { 'a': { 'b': 2 } }, true);
assert.deepEqual(base, { 'a': { 'b': 2 } });
});
test('simple merge using models', () => {
let base = new model.ConfigModel(JSON.stringify({ 'a': 1, 'b': 2 }));
let add = new model.ConfigModel(JSON.stringify({ 'a': 3, 'c': 4 }));
let base = new CustomConfiguration(JSON.stringify({ 'a': 1, 'b': 2 }));
let add = new CustomConfiguration(JSON.stringify({ 'a': 3, 'c': 4 }));
let result = base.merge(add);
assert.deepEqual(result.contents, { 'a': 3, 'b': 2, 'c': 4 });
});
test('simple merge with an undefined contents', () => {
let base = new model.ConfigModel(JSON.stringify({ 'a': 1, 'b': 2 }));
let add = new model.ConfigModel(null);
let base = new CustomConfiguration(JSON.stringify({ 'a': 1, 'b': 2 }));
let add = new CustomConfiguration(null);
let result = base.merge(add);
assert.deepEqual(result.contents, { 'a': 1, 'b': 2 });
base = new model.ConfigModel(null);
add = new model.ConfigModel(JSON.stringify({ 'a': 1, 'b': 2 }));
base = new CustomConfiguration(null);
add = new CustomConfiguration(JSON.stringify({ 'a': 1, 'b': 2 }));
result = base.merge(add);
assert.deepEqual(result.contents, { 'a': 1, 'b': 2 });
base = new model.ConfigModel(null);
add = new model.ConfigModel(null);
base = new CustomConfiguration(null);
add = new CustomConfiguration(null);
result = base.merge(add);
assert.deepEqual(result.contents, {});
});
test('Recursive merge using config models', () => {
let base = new model.ConfigModel(JSON.stringify({ 'a': { 'b': 1 } }));
let add = new model.ConfigModel(JSON.stringify({ 'a': { 'b': 2 } }));
let base = new CustomConfiguration(JSON.stringify({ 'a': { 'b': 1 } }));
let add = new CustomConfiguration(JSON.stringify({ 'a': { 'b': 2 } }));
let result = base.merge(add);
assert.deepEqual(result.contents, { 'a': { 'b': 2 } });
});
test('Test contents while getting an existing property', () => {
let testObject = new model.ConfigModel(JSON.stringify({ 'a': 1 }));
let testObject = new CustomConfiguration(JSON.stringify({ 'a': 1 }));
assert.deepEqual(testObject.getContentsFor('a'), 1);
testObject = new model.ConfigModel(JSON.stringify({ 'a': { 'b': 1 } }));
testObject = new CustomConfiguration(JSON.stringify({ 'a': { 'b': 1 } }));
assert.deepEqual(testObject.getContentsFor('a'), { 'b': 1 });
});
test('Test contents are undefined for non existing properties', () => {
const testObject = new model.ConfigModel(JSON.stringify({
const testObject = new CustomConfiguration(JSON.stringify({
awesome: true
}));
......@@ -91,25 +76,25 @@ suite('ConfigurationService - Model', () => {
});
test('Test contents are undefined for undefined config', () => {
const testObject = new model.ConfigModel(null);
const testObject = new CustomConfiguration(null);
assert.deepEqual(testObject.getContentsFor('unknownproperty'), undefined);
});
test('Test configWithOverrides gives all content merged with overrides', () => {
const testObject = new model.ConfigModel(JSON.stringify({ 'a': 1, 'c': 1, '[b]': { 'a': 2 } }));
const testObject = new CustomConfiguration(JSON.stringify({ 'a': 1, 'c': 1, '[b]': { 'a': 2 } }));
assert.deepEqual(testObject.configWithOverrides('b').contents, { 'a': 2, 'c': 1, '[b]': { 'a': 2 } });
assert.deepEqual(testObject.override('b').contents, { 'a': 2, 'c': 1, '[b]': { 'a': 2 } });
});
test('Test configWithOverrides gives empty contents', () => {
const testObject = new model.ConfigModel(null);
const testObject = new CustomConfiguration(null);
assert.deepEqual(testObject.configWithOverrides('b').contents, {});
assert.deepEqual(testObject.override('b').contents, {});
});
test('Test update with empty data', () => {
const testObject = new model.ConfigModel();
const testObject = new CustomConfiguration();
testObject.update('');
assert.deepEqual(testObject.contents, {});
......@@ -140,7 +125,7 @@ suite('ConfigurationService - Model', () => {
}
}
});
assert.equal(true, new model.DefaultConfigModel().getContentsFor('a'));
assert.equal(true, new DefaultConfiguration().getContentsFor('a'));
});
test('Test registering the language property', () => {
......@@ -157,7 +142,7 @@ suite('ConfigurationService - Model', () => {
}
}
});
assert.equal(undefined, new model.DefaultConfigModel().getContentsFor('[a]'));
assert.equal(undefined, new DefaultConfiguration().getContentsFor('[a]'));
});
});
\ No newline at end of file
......@@ -4,12 +4,12 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import { ConfigModel } from 'vs/platform/configuration/common/model';
import { CustomConfiguration } from 'vs/platform/configuration/common/model';
import { WORKSPACE_STANDALONE_CONFIGURATIONS } from 'vs/workbench/services/configuration/common/configuration';
import { Registry } from 'vs/platform/platform';
import { IConfigurationRegistry, IConfigurationPropertySchema, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
export class ScopedConfigModel<T> extends ConfigModel<T> {
export class ScopedConfigModel<T> extends CustomConfiguration<T> {
constructor(content: string, name: string, public readonly scope: string) {
super(null, name);
......@@ -25,7 +25,7 @@ export class ScopedConfigModel<T> extends ConfigModel<T> {
}
export class WorkspaceSettingsConfigModel<T> extends ConfigModel<T> {
export class WorkspaceSettingsConfigModel<T> extends CustomConfiguration<T> {
private _raw: T;
private _unsupportedKeys: string[];
......@@ -62,7 +62,7 @@ export class WorkspaceSettingsConfigModel<T> extends ConfigModel<T> {
}
}
export class WorkspaceConfigModel<T> extends ConfigModel<T> {
export class WorkspaceConfigModel<T> extends CustomConfiguration<T> {
constructor(public readonly workspaceSettingsConfig: WorkspaceSettingsConfigModel<T>, private scopedConfigs: ScopedConfigModel<T>[]) {
super();
......
......@@ -20,9 +20,8 @@ import * as extfs from 'vs/base/node/extfs';
import { IWorkspaceContextService, IWorkspace2, Workspace as SingleRootWorkspace, IWorkspace } from "vs/platform/workspace/common/workspace";
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { FileChangeType, FileChangesEvent, isEqual } from 'vs/platform/files/common/files';
import { ConfigModel } from 'vs/platform/configuration/common/model';
import { ScopedConfigModel, WorkspaceConfigModel, WorkspaceSettingsConfigModel } from 'vs/workbench/services/configuration/common/configurationModels';
import { IConfigurationServiceEvent, ConfigurationSource, getConfigurationValue, IConfigModel, IConfigurationOptions } from 'vs/platform/configuration/common/configuration';
import { IConfigurationServiceEvent, ConfigurationSource, getConfigurationValue, IConfigurationOptions, Configuration } from 'vs/platform/configuration/common/configuration';
import { IWorkspaceConfigurationValues, IWorkspaceConfigurationService, IWorkspaceConfigurationValue, WORKSPACE_CONFIG_FOLDER_DEFAULT_NAME, WORKSPACE_STANDALONE_CONFIGURATIONS, WORKSPACE_CONFIG_DEFAULT_PATH } from 'vs/workbench/services/configuration/common/configuration';
import { ConfigurationService as GlobalConfigurationService } from 'vs/platform/configuration/node/configurationService';
......@@ -68,11 +67,11 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
private baseConfigurationService: GlobalConfigurationService<any>;
private cachedConfig: ConfigModel<any>;
private cachedConfig: Configuration<any>;
private cachedWorkspaceConfig: WorkspaceConfigModel<any>;
private bulkFetchFromWorkspacePromise: TPromise<any>;
private workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: TPromise<IConfigModel<any>> };
private workspaceFilePathToConfiguration: { [relativeWorkspacePath: string]: TPromise<Configuration<any>> };
private reloadConfigurationScheduler: RunOnceScheduler;
private readonly workspace: Workspace;
......@@ -83,7 +82,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
this.workspace = singleRootWorkspace ? new Workspace(singleRootWorkspace.resource.toString(), [singleRootWorkspace.resource]) : null;
this.workspaceFilePathToConfiguration = Object.create(null);
this.cachedConfig = new ConfigModel<any>(null);
this.cachedConfig = new Configuration<any>();
this.cachedWorkspaceConfig = new WorkspaceConfigModel(new WorkspaceSettingsConfigModel(null), []);
this.baseConfigurationService = this._register(new GlobalConfigurationService(environmentService));
......@@ -162,7 +161,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
// update cached config when base config changes
const configModel = <ConfigModel<any>>this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify)
const configModel = <Configuration<any>>this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify)
.merge(this.cachedWorkspaceConfig); // workspace configured values
// emit this as update to listeners if changed
......@@ -184,7 +183,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
public getConfiguration<C>(options?: IConfigurationOptions): C
public getConfiguration<C>(arg?: any): C {
const options = this.toOptions(arg);
const configModel = options.overrideIdentifier ? this.cachedConfig.configWithOverrides<C>(options.overrideIdentifier) : this.cachedConfig;
const configModel = options.overrideIdentifier ? this.cachedConfig.override<C>(options.overrideIdentifier) : this.cachedConfig;
return options.section ? configModel.getContentsFor<C>(options.section) : configModel.contents;
}
......@@ -193,8 +192,8 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
return {
default: configurationValue.default,
user: configurationValue.user,
workspace: objects.clone(getConfigurationValue<C>(overrideIdentifier ? this.cachedWorkspaceConfig.configWithOverrides(overrideIdentifier).contents : this.cachedWorkspaceConfig.contents, key)),
value: objects.clone(getConfigurationValue<C>(overrideIdentifier ? this.cachedConfig.configWithOverrides(overrideIdentifier).contents : this.cachedConfig.contents, key))
workspace: objects.clone(getConfigurationValue<C>(overrideIdentifier ? this.cachedWorkspaceConfig.override(overrideIdentifier).contents : this.cachedWorkspaceConfig.contents, key)),
value: objects.clone(getConfigurationValue<C>(overrideIdentifier ? this.cachedConfig.override(overrideIdentifier).contents : this.cachedConfig.contents, key))
};
}
......@@ -268,7 +267,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
this.cachedWorkspaceConfig = new WorkspaceConfigModel<T>(workspaceSettingsConfig, otherConfigModels);
// Override base (global < user) with workspace locals (global < user < workspace)
this.cachedConfig = <ConfigModel<any>>this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify)
this.cachedConfig = <Configuration<any>>this.baseConfigurationService.getCache().consolidated // global/default values (do NOT modify)
.merge(this.cachedWorkspaceConfig); // workspace configured values
return {
......@@ -278,7 +277,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
});
}
private loadWorkspaceConfigFiles<T>(): TPromise<{ [relativeWorkspacePath: string]: IConfigModel<T> }> {
private loadWorkspaceConfigFiles<T>(): TPromise<{ [relativeWorkspacePath: string]: Configuration<T> }> {
// Return early if we don't have a workspace
if (!this.workspace) {
......@@ -363,7 +362,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
}
private createConfigModel<T>(content: IContent): IConfigModel<T> {
private createConfigModel<T>(content: IContent): Configuration<T> {
const path = this.toWorkspaceRelativePath(content.resource);
if (path === WORKSPACE_CONFIG_DEFAULT_PATH) {
return new WorkspaceSettingsConfigModel<T>(content.value, content.resource.toString());
......@@ -374,7 +373,7 @@ export class WorkspaceConfigurationService extends Disposable implements IWorksp
}
}
return new ConfigModel<T>(null);
return new Configuration<T>();
}
private isWorkspaceConfigurationFile(workspaceRelativePath: string): boolean {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册