Skip to content

Commit

Permalink
Fix #46851
Browse files Browse the repository at this point in the history
  • Loading branch information
sandy081 committed Nov 24, 2021
1 parent dd7ef39 commit 4eb6b38
Show file tree
Hide file tree
Showing 20 changed files with 427 additions and 172 deletions.
19 changes: 0 additions & 19 deletions src/vs/platform/configuration/common/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
import { Event } from 'vs/base/common/event';
import * as types from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Registry } from 'vs/platform/registry/common/platform';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';

export const IConfigurationService = createDecorator<IConfigurationService>('configurationService');
Expand Down Expand Up @@ -262,23 +260,6 @@ export function merge(base: any, add: any, overwrite: boolean): void {
});
}

export function getConfigurationKeys(): string[] {
const properties = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
return Object.keys(properties);
}

export function getDefaultValues(): any {
const valueTreeRoot: any = Object.create(null);
const properties = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();

for (let key in properties) {
let value = properties[key].default;
addToValueTree(valueTreeRoot, key, value, message => console.error(`Conflict in default settings: ${message}`));
}

return valueTreeRoot;
}

export function getMigratedSettingValue<T>(configurationService: IConfigurationService, currentSettingName: string, legacySettingName: string): T {
const setting = configurationService.inspect<T>(currentSettingName);
const legacySetting = configurationService.inspect<T>(legacySettingName);
Expand Down
35 changes: 17 additions & 18 deletions src/vs/platform/configuration/common/configurationModels.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as objects from 'vs/base/common/objects';
import { IExtUri } from 'vs/base/common/resources';
import * as types from 'vs/base/common/types';
import { URI, UriComponents } from 'vs/base/common/uri';
import { addToValueTree, ConfigurationTarget, getConfigurationKeys, getConfigurationValue, getDefaultValues, IConfigurationChange, IConfigurationChangeEvent, IConfigurationCompareResult, IConfigurationData, IConfigurationModel, IConfigurationOverrides, IConfigurationUpdateOverrides, IConfigurationValue, IOverrides, removeFromValueTree, toValuesTree } from 'vs/platform/configuration/common/configuration';
import { addToValueTree, ConfigurationTarget, getConfigurationValue, IConfigurationChange, IConfigurationChangeEvent, IConfigurationCompareResult, IConfigurationData, IConfigurationModel, IConfigurationOverrides, IConfigurationUpdateOverrides, IConfigurationValue, IOverrides, removeFromValueTree, toValuesTree } from 'vs/platform/configuration/common/configuration';
import { ConfigurationScope, Extensions, IConfigurationPropertySchema, IConfigurationRegistry, overrideIdentifiersFromKey, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
import { IFileService } from 'vs/platform/files/common/files';
import { Registry } from 'vs/platform/registry/common/platform';
Expand Down Expand Up @@ -234,10 +234,17 @@ export class ConfigurationModel implements IConfigurationModel {

export class DefaultConfigurationModel extends ConfigurationModel {

constructor() {
const contents = getDefaultValues();
const keys = getConfigurationKeys();
constructor(configurationDefaultsOverrides: IStringDictionary<any> = {}) {
const properties = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
const keys = Object.keys(properties);
const contents: any = Object.create(null);
const overrides: IOverrides[] = [];

for (const key in properties) {
const defaultOverrideValue = configurationDefaultsOverrides[key];
const value = defaultOverrideValue !== undefined ? defaultOverrideValue : properties[key].default;
addToValueTree(contents, key, value, message => console.error(`Conflict in default settings: ${message}`));
}
for (const key of Object.keys(contents)) {
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
overrides.push({
Expand All @@ -247,6 +254,7 @@ export class DefaultConfigurationModel extends ConfigurationModel {
});
}
}

super(contents, keys, overrides);
}
}
Expand Down Expand Up @@ -587,21 +595,12 @@ export class Configuration {
this._foldersConsolidatedConfigurations.delete(resource);
}

compareAndUpdateDefaultConfiguration(defaults: ConfigurationModel, keys: string[]): IConfigurationChange {
const overrides: [string, string[]][] = [];
for (const key of keys) {
for (const overrideIdentifier of overrideIdentifiersFromKey(key)) {
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]);
}
compareAndUpdateDefaultConfiguration(defaults: ConfigurationModel): IConfigurationChange {
const { added, updated, removed, overrides } = compare(this._defaultConfiguration, defaults);
const keys = [...added, ...updated, ...removed];
if (keys.length) {
this.updateDefaultConfiguration(defaults);
}
this.updateDefaultConfiguration(defaults);
return { keys, overrides };
}

Expand Down
42 changes: 26 additions & 16 deletions src/vs/platform/configuration/common/configurationRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ export interface IConfigurationRegistry {
*/
deregisterDefaultConfigurations(defaultConfigurations: IStringDictionary<any>[]): void;

/**
* Return the registered configuration defaults overrides
*/
getConfigurationDefaultsOverrides(): IStringDictionary<any>;

/**
* Signal that the schema of a configuration setting has changes. It is currently only supported to change enumeration values.
* Property or default value changes are not allowed.
Expand All @@ -65,13 +70,13 @@ export interface IConfigurationRegistry {
* Event that fires whenver a configuration has been
* registered.
*/
onDidSchemaChange: Event<void>;
readonly onDidSchemaChange: Event<void>;

/**
* Event that fires whenver a configuration has been
* registered.
*/
onDidUpdateConfiguration: Event<string[]>;
readonly onDidUpdateConfiguration: Event<{ properties: string[], defaultsOverrides?: boolean }>;

/**
* Returns all configuration nodes contributed to this registry.
Expand Down Expand Up @@ -190,7 +195,7 @@ const contributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensio

class ConfigurationRegistry implements IConfigurationRegistry {

private readonly defaultValues: IStringDictionary<any>;
private readonly configurationDefaultsOverrides: IStringDictionary<any>;
private readonly defaultLanguageConfigurationOverridesNode: IConfigurationNode;
private readonly configurationContributors: IConfigurationNode[];
private readonly configurationProperties: { [qualifiedKey: string]: IJSONSchema };
Expand All @@ -201,11 +206,11 @@ class ConfigurationRegistry implements IConfigurationRegistry {
private readonly _onDidSchemaChange = new Emitter<void>();
readonly onDidSchemaChange: Event<void> = this._onDidSchemaChange.event;

private readonly _onDidUpdateConfiguration: Emitter<string[]> = new Emitter<string[]>();
readonly onDidUpdateConfiguration: Event<string[]> = this._onDidUpdateConfiguration.event;
private readonly _onDidUpdateConfiguration = new Emitter<{ properties: string[], defaultsOverrides?: boolean }>();
readonly onDidUpdateConfiguration = this._onDidUpdateConfiguration.event;

constructor() {
this.defaultValues = {};
this.configurationDefaultsOverrides = {};
this.defaultLanguageConfigurationOverridesNode = {
id: 'defaultOverrides',
title: nls.localize('defaultLanguageConfigurationOverrides.title', "Default Language Configuration Overrides"),
Expand All @@ -229,15 +234,15 @@ class ConfigurationRegistry implements IConfigurationRegistry {

contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(properties);
this._onDidUpdateConfiguration.fire({ properties });
}

public deregisterConfigurations(configurations: IConfigurationNode[]): void {
const properties = this.doDeregisterConfigurations(configurations);

contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(properties);
this._onDidUpdateConfiguration.fire({ properties });
}

public updateConfigurations({ add, remove }: { add: IConfigurationNode[], remove: IConfigurationNode[] }): void {
Expand All @@ -247,7 +252,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {

contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(distinct(properties));
this._onDidUpdateConfiguration.fire({ properties: distinct(properties) });
}

public registerDefaultConfigurations(defaultConfigurations: IStringDictionary<any>[]): void {
Expand All @@ -259,18 +264,18 @@ class ConfigurationRegistry implements IConfigurationRegistry {
properties.push(key);

if (OVERRIDE_PROPERTY_REGEX.test(key)) {
this.defaultValues[key] = { ...(this.defaultValues[key] || {}), ...defaultConfiguration[key] };
this.configurationDefaultsOverrides[key] = { ...(this.configurationDefaultsOverrides[key] || {}), ...defaultConfiguration[key] };
const property: IConfigurationPropertySchema = {
type: 'object',
default: this.defaultValues[key],
default: this.configurationDefaultsOverrides[key],
description: nls.localize('defaultLanguageConfiguration.description', "Configure settings to be overridden for {0} language.", key),
$ref: resourceLanguageSettingsSchemaId
};
overrideIdentifiers.push(...overrideIdentifiersFromKey(key));
this.configurationProperties[key] = property;
this.defaultLanguageConfigurationOverridesNode.properties![key] = property;
} else {
this.defaultValues[key] = defaultConfiguration[key];
this.configurationDefaultsOverrides[key] = defaultConfiguration[key];
const property = this.configurationProperties[key];
if (property) {
this.updatePropertyDefaultValue(key, property);
Expand All @@ -282,15 +287,15 @@ class ConfigurationRegistry implements IConfigurationRegistry {

this.registerOverrideIdentifiers(overrideIdentifiers);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(properties);
this._onDidUpdateConfiguration.fire({ properties, defaultsOverrides: true });
}

public deregisterDefaultConfigurations(defaultConfigurations: IStringDictionary<any>[]): void {
const properties: string[] = [];
for (const defaultConfiguration of defaultConfigurations) {
for (const key in defaultConfiguration) {
properties.push(key);
delete this.defaultValues[key];
delete this.configurationDefaultsOverrides[key];
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
delete this.configurationProperties[key];
delete this.defaultLanguageConfigurationOverridesNode.properties![key];
Expand All @@ -306,7 +311,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {

this.updateOverridePropertyPatternKey();
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(properties);
this._onDidUpdateConfiguration.fire({ properties, defaultsOverrides: true });
}

public notifyConfigurationSchemaUpdated(...configurations: IConfigurationNode[]) {
Expand Down Expand Up @@ -417,6 +422,10 @@ class ConfigurationRegistry implements IConfigurationRegistry {
return this.excludedConfigurationProperties;
}

getConfigurationDefaultsOverrides(): IStringDictionary<any> {
return this.configurationDefaultsOverrides;
}

private registerJSONConfiguration(configuration: IConfigurationNode) {
const register = (configuration: IConfigurationNode) => {
let properties = configuration.properties;
Expand Down Expand Up @@ -476,6 +485,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
case ConfigurationScope.RESOURCE:
case ConfigurationScope.LANGUAGE_OVERRIDABLE:
delete resourceSettings.properties[key];
delete this.resourceLanguageSettingsSchema.properties![key];
break;
}
}
Expand Down Expand Up @@ -517,7 +527,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
}

private updatePropertyDefaultValue(key: string, property: IConfigurationPropertySchema): void {
let defaultValue = this.defaultValues[key];
let defaultValue = this.configurationDefaultsOverrides[key];
if (types.isUndefined(defaultValue)) {
defaultValue = property.default;
}
Expand Down
6 changes: 3 additions & 3 deletions src/vs/platform/configuration/common/configurationService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
this.configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());

this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reloadConfiguration(), 50));
this._register(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidUpdateConfiguration(configurationProperties => this.onDidDefaultConfigurationChange(configurationProperties)));
this._register(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidUpdateConfiguration(() => this.onDidDefaultConfigurationChange()));
this._register(this.userConfiguration.onDidChange(() => this.reloadConfigurationScheduler.schedule()));
}

Expand Down Expand Up @@ -89,9 +89,9 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
this.trigger(change, previous, ConfigurationTarget.USER);
}

private onDidDefaultConfigurationChange(keys: string[]): void {
private onDidDefaultConfigurationChange(): void {
const previous = this.configuration.toData();
const change = this.configuration.compareAndUpdateDefaultConfiguration(new DefaultConfigurationModel(), keys);
const change = this.configuration.compareAndUpdateDefaultConfiguration(new DefaultConfigurationModel());
this.trigger(change, previous, ConfigurationTarget.DEFAULT);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,43 @@ suite('CustomConfigurationModel', () => {
});
});

suite('CustomConfigurationModel', () => {

test('Default configuration model uses overrides', () => {
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
'id': 'a',
'order': 1,
'title': 'a',
'type': 'object',
'properties': {
'a': {
'description': 'a',
'type': 'boolean',
'default': false,
}
}
});
assert.strictEqual(true, new DefaultConfigurationModel().getValue('a'));
});

test('Default configuration model uses overrides', () => {
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
'id': 'a',
'order': 1,
'title': 'a',
'type': 'object',
'properties': {
'a': {
'description': 'a',
'type': 'boolean',
'default': false,
}
}
});
assert.strictEqual(false, new DefaultConfigurationModel({ a: false }).getValue('a'));
});
});

suite('Configuration', () => {

test('Test inspect for overrideIdentifiers', () => {
Expand Down Expand Up @@ -488,9 +525,9 @@ suite('Configuration', () => {
'[markdown]': {
'editor.wordWrap': 'off'
}
}), ['editor.lineNumbers', '[markdown]']);
}));

assert.deepStrictEqual(actual, { keys: ['editor.lineNumbers', '[markdown]'], overrides: [['markdown', ['editor.wordWrap']]] });
assert.deepStrictEqual(actual, { keys: ['[markdown]', 'editor.lineNumbers'], overrides: [['markdown', ['editor.wordWrap']]] });

});

Expand Down Expand Up @@ -853,7 +890,7 @@ suite('ConfigurationChangeEvent', () => {
'[markdown]': {
'editor.wordWrap': 'off'
}
}), ['editor.lineNumbers', '[markdown]']),
})),
configuration.compareAndUpdateLocalUserConfiguration(toConfigurationModel({
'[json]': {
'editor.lineNumbers': 'relative'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
import { Emitter } from 'vs/base/common/event';
import { TernarySearchTree } from 'vs/base/common/map';
import { URI } from 'vs/base/common/uri';
import { getConfigurationKeys, getConfigurationValue, IConfigurationChangeEvent, IConfigurationOverrides, IConfigurationService, IConfigurationValue, isConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
import { getConfigurationValue, IConfigurationChangeEvent, IConfigurationOverrides, IConfigurationService, IConfigurationValue, isConfigurationOverrides } from 'vs/platform/configuration/common/configuration';
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
import { Registry } from 'vs/platform/registry/common/platform';

export class TestConfigurationService implements IConfigurationService {
public _serviceBrand: undefined;
Expand Down Expand Up @@ -68,7 +70,7 @@ export class TestConfigurationService implements IConfigurationService {

public keys() {
return {
default: getConfigurationKeys(),
default: Object.keys(Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties()),
user: Object.keys(this.configuration),
workspace: [],
workspaceFolder: []
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/environment/common/environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export interface IEnvironmentService {
untitledWorkspacesHome: URI;
globalStorageHome: URI;
workspaceStorageHome: URI;
cacheHome: URI;

// --- settings sync
userDataSyncHome: URI;
Expand Down
3 changes: 3 additions & 0 deletions src/vs/platform/environment/common/environmentService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ export abstract class AbstractNativeEnvironmentService implements INativeEnviron
@memoize
get tmpDir(): URI { return URI.file(this.paths.tmpDir); }

@memoize
get cacheHome(): URI { return URI.file(this.userDataPath); }

@memoize
get userRoamingDataHome(): URI { return this.appSettingsHome; }

Expand Down
Loading

0 comments on commit 4eb6b38

Please sign in to comment.