Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973 (#6381)

* Merge from vscode 8e0f348413f4f616c23a88ae30030efa85811973

* disable strict null check
This commit is contained in:
Anthony Dresser
2019-07-15 22:35:46 -07:00
committed by GitHub
parent f720ec642f
commit 0b7e7ddbf9
2406 changed files with 59140 additions and 35464 deletions

View File

@@ -148,7 +148,7 @@ export function toOverrides(raw: any, conflictReporter: (message: string) => voi
const configurationProperties = Registry.as<IConfigurationRegistry>(Extensions.Configuration).getConfigurationProperties();
for (const key of Object.keys(raw)) {
if (OVERRIDE_PROPERTY_PATTERN.test(key)) {
const overrideRaw = {};
const overrideRaw: any = {};
for (const keyInOverrideRaw in raw[key]) {
if (configurationProperties[keyInOverrideRaw] && configurationProperties[keyInOverrideRaw].overridable) {
overrideRaw[keyInOverrideRaw] = raw[key][keyInOverrideRaw];

View File

@@ -53,7 +53,7 @@ export class ConfigurationModel implements IConfigurationModel {
return this;
}
let contents = {};
let contents: any = {};
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
let contentsForKey = this.contents[key];
@@ -297,8 +297,8 @@ export class ConfigurationModelParser {
return { contents, keys, overrides };
}
private filterByScope(properties: {}, configurationProperties: { [qualifiedKey: string]: IConfigurationPropertySchema }, filterOverriddenProperties: boolean, scopes: ConfigurationScope[]): {} {
const result = {};
private filterByScope(properties: any, configurationProperties: { [qualifiedKey: string]: IConfigurationPropertySchema }, filterOverriddenProperties: boolean, scopes: ConfigurationScope[]): {} {
const result: any = {};
for (let key in properties) {
if (OVERRIDE_PROPERTY_PATTERN.test(key) && filterOverriddenProperties) {
result[key] = this.filterByScope(properties[key], configurationProperties, false, scopes);

View File

@@ -131,11 +131,13 @@ export interface IDefaultConfigurationExtension {
defaults: { [key: string]: {} };
}
export const allSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
export const applicationSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
export const machineSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
export const windowSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
export const resourceSettings: { properties: {}, patternProperties: {} } = { properties: {}, patternProperties: {} };
type SettingProperties = { [key: string]: any };
export const allSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
export const applicationSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
export const machineSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
export const windowSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
export const resourceSettings: { properties: SettingProperties, patternProperties: SettingProperties } = { properties: {}, patternProperties: {} };
export const editorConfigurationSchemaId = 'vscode://schemas/settings/editor';
const contributionRegistry = Registry.as<IJSONContributionRegistry>(JSONExtensions.JSONContribution);
@@ -468,13 +470,13 @@ export function validateProperty(property: string): string | null {
return null;
}
export function getScopes(): { [key: string]: ConfigurationScope } {
const scopes = {};
export function getScopes(): [string, ConfigurationScope | undefined][] {
const scopes: [string, ConfigurationScope | undefined][] = [];
const configurationProperties = configurationRegistry.getConfigurationProperties();
for (const key of Object.keys(configurationProperties)) {
scopes[key] = configurationProperties[key].scope;
scopes.push([key, configurationProperties[key].scope]);
}
scopes['launch'] = ConfigurationScope.RESOURCE;
scopes['task'] = ConfigurationScope.RESOURCE;
scopes.push(['launch', ConfigurationScope.RESOURCE]);
scopes.push(['task', ConfigurationScope.RESOURCE]);
return scopes;
}

View File

@@ -1,56 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { onUnexpectedError } from 'vs/base/common/errors';
import { ConfigurationModelParser, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
import { ConfigWatcher } from 'vs/base/node/config';
import { Event, Emitter } from 'vs/base/common/event';
export class NodeBasedUserConfiguration extends Disposable {
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser>;
private initializePromise: Promise<void>;
private readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
constructor(private settingsPath: string) {
super();
}
initialize(): Promise<ConfigurationModel> {
if (!this.initializePromise) {
this.initializePromise = new Promise<void>((c, e) => {
this.userConfigModelWatcher = new ConfigWatcher(this.settingsPath, {
changeBufferDelay: 300, onError: error => onUnexpectedError(error), defaultConfig: new ConfigurationModelParser(this.settingsPath), parse: (content: string, parseErrors: any[]) => {
const userConfigModelParser = new ConfigurationModelParser(this.settingsPath);
userConfigModelParser.parseContent(content);
parseErrors = [...userConfigModelParser.errors];
return userConfigModelParser;
}, initCallback: () => c(undefined)
});
this._register(this.userConfigModelWatcher);
// Listeners
this._register(this.userConfigModelWatcher.onDidUpdateConfiguration(() => this._onDidChangeConfiguration.fire(this.userConfigModelWatcher.getConfig().configurationModel)));
});
}
return this.initializePromise.then(() => this.userConfigModelWatcher.getConfig().configurationModel);
}
initializeSync(): ConfigurationModel {
this.initialize();
return this.userConfigModelWatcher.getConfig().configurationModel;
}
reload(): Promise<ConfigurationModel> {
return this.initialize().then(() => new Promise<ConfigurationModel>(c => this.userConfigModelWatcher.reload(userConfigModelParser => c(userConfigModelParser.configurationModel))));
}
getConfigurationModel(): ConfigurationModel {
return this.userConfigModelWatcher.getConfig().configurationModel;
}
}

View File

@@ -7,40 +7,54 @@ import { Registry } from 'vs/platform/registry/common/platform';
import { IConfigurationRegistry, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
import { IDisposable, Disposable } from 'vs/base/common/lifecycle';
import { IConfigurationService, IConfigurationChangeEvent, IConfigurationOverrides, ConfigurationTarget, compare, isConfigurationOverrides, IConfigurationData } from 'vs/platform/configuration/common/configuration';
import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, ConfigurationModel } from 'vs/platform/configuration/common/configurationModels';
import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, ConfigurationModel, ConfigurationModelParser } from 'vs/platform/configuration/common/configurationModels';
import { Event, Emitter } from 'vs/base/common/event';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
import { ConfigWatcher } from 'vs/base/node/config';
import { onUnexpectedError } from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
import { Schemas } from 'vs/base/common/network';
export class ConfigurationService extends Disposable implements IConfigurationService, IDisposable {
_serviceBrand: any;
private _configuration: Configuration;
private userConfiguration: NodeBasedUserConfiguration;
private configuration: Configuration;
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser> | undefined;
private readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
constructor(
configurationPath: string
private readonly settingsResource: URI
) {
super();
this.userConfiguration = this._register(new NodeBasedUserConfiguration(configurationPath));
// Initialize
const defaults = new DefaultConfigurationModel();
const user = this.userConfiguration.initializeSync();
this._configuration = new Configuration(defaults, user);
// Listeners
this._register(this.userConfiguration.onDidChangeConfiguration(userConfigurationModel => this.onDidChangeUserConfiguration(userConfigurationModel)));
this.configuration = new Configuration(new DefaultConfigurationModel(), new ConfigurationModel());
this._register(Registry.as<IConfigurationRegistry>(Extensions.Configuration).onDidUpdateConfiguration(configurationProperties => this.onDidDefaultConfigurationChange(configurationProperties)));
}
get configuration(): Configuration {
return this._configuration;
initialize(): Promise<void> {
if (this.userConfigModelWatcher) {
this.userConfigModelWatcher.dispose();
}
if (this.settingsResource.scheme !== Schemas.file) {
return Promise.resolve();
}
return new Promise<void>((c, e) => {
this.userConfigModelWatcher = this._register(new ConfigWatcher(this.settingsResource.fsPath, {
changeBufferDelay: 300, onError: error => onUnexpectedError(error), defaultConfig: new ConfigurationModelParser(this.settingsResource.fsPath), parse: (content: string, parseErrors: any[]) => {
const userConfigModelParser = new ConfigurationModelParser(this.settingsResource.fsPath);
userConfigModelParser.parseContent(content);
parseErrors = [...userConfigModelParser.errors];
return userConfigModelParser;
}, initCallback: () => {
this.configuration = new Configuration(new DefaultConfigurationModel(), this.userConfigModelWatcher!.getConfig().configurationModel);
this._register(this.userConfigModelWatcher!.onDidUpdateConfiguration(() => this.onDidChangeUserConfiguration(this.userConfigModelWatcher!.getConfig().configurationModel)));
c();
}
}));
});
}
getConfigurationData(): IConfigurationData {
@@ -85,21 +99,26 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
}
reloadConfiguration(folder?: IWorkspaceFolder): Promise<void> {
return folder ? Promise.resolve(undefined) :
this.userConfiguration.reload().then(userConfigurationModel => this.onDidChangeUserConfiguration(userConfigurationModel));
if (this.userConfigModelWatcher) {
return new Promise<void>(c => this.userConfigModelWatcher!.reload(userConfigModelParser => {
this.onDidChangeUserConfiguration(userConfigModelParser.configurationModel);
c();
}));
}
return this.initialize();
}
private onDidChangeUserConfiguration(userConfigurationModel: ConfigurationModel): void {
const { added, updated, removed } = compare(this._configuration.localUserConfiguration, userConfigurationModel);
const { added, updated, removed } = compare(this.configuration.localUserConfiguration, userConfigurationModel);
const changedKeys = [...added, ...updated, ...removed];
if (changedKeys.length) {
this._configuration.updateLocalUserConfiguration(userConfigurationModel);
this.configuration.updateLocalUserConfiguration(userConfigurationModel);
this.trigger(changedKeys, ConfigurationTarget.USER);
}
}
private onDidDefaultConfigurationChange(keys: string[]): void {
this._configuration.updateDefaultConfiguration(new DefaultConfigurationModel());
this.configuration.updateDefaultConfiguration(new DefaultConfigurationModel());
this.trigger(keys, ConfigurationTarget.DEFAULT);
}
@@ -110,9 +129,9 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
private getTargetConfiguration(target: ConfigurationTarget): any {
switch (target) {
case ConfigurationTarget.DEFAULT:
return this._configuration.defaults.contents;
return this.configuration.defaults.contents;
case ConfigurationTarget.USER:
return this._configuration.localUserConfiguration.contents;
return this.configuration.localUserConfiguration.contents;
}
return {};
}

View File

@@ -32,7 +32,7 @@ suite('Configuration', () => {
assert.deepEqual(target, { 'a': { 'b': 2 } });
});
test('removeFromValueTree: remove a single segemented key', () => {
test('removeFromValueTree: remove a single segmented key', () => {
let target = { 'a': 1 };
removeFromValueTree(target, 'a');
@@ -40,7 +40,7 @@ suite('Configuration', () => {
assert.deepEqual(target, {});
});
test('removeFromValueTree: remove a single segemented key when its value is undefined', () => {
test('removeFromValueTree: remove a single segmented key when its value is undefined', () => {
let target = { 'a': undefined };
removeFromValueTree(target, 'a');
@@ -48,7 +48,7 @@ suite('Configuration', () => {
assert.deepEqual(target, {});
});
test('removeFromValueTree: remove a multi segemented key when its value is undefined', () => {
test('removeFromValueTree: remove a multi segmented key when its value is undefined', () => {
let target = { 'a': { 'b': 1 } };
removeFromValueTree(target, 'a.b');
@@ -56,7 +56,7 @@ suite('Configuration', () => {
assert.deepEqual(target, {});
});
test('removeFromValueTree: remove a multi segemented key when its value is array', () => {
test('removeFromValueTree: remove a multi segmented key when its value is array', () => {
let target = { 'a': { 'b': [1] } };
removeFromValueTree(target, 'a.b');
@@ -64,7 +64,7 @@ suite('Configuration', () => {
assert.deepEqual(target, {});
});
test('removeFromValueTree: remove a multi segemented key first segment value is array', () => {
test('removeFromValueTree: remove a multi segmented key first segment value is array', () => {
let target = { 'a': [1] };
removeFromValueTree(target, 'a.0');
@@ -80,7 +80,7 @@ suite('Configuration', () => {
assert.deepEqual(target, {});
});
test('removeFromValueTree: remove a multi segemented key when the first node has more values', () => {
test('removeFromValueTree: remove a multi segmented key when the first node has more values', () => {
let target = { 'a': { 'b': { 'c': 1 }, 'd': 1 } };
removeFromValueTree(target, 'a.b.c');
@@ -88,7 +88,7 @@ suite('Configuration', () => {
assert.deepEqual(target, { 'a': { 'd': 1 } });
});
test('removeFromValueTree: remove a multi segemented key when in between node has more values', () => {
test('removeFromValueTree: remove a multi segmented key when in between node has more values', () => {
let target = { 'a': { 'b': { 'c': { 'd': 1 }, 'd': 1 } } };
removeFromValueTree(target, 'a.b.c.d');
@@ -96,7 +96,7 @@ suite('Configuration', () => {
assert.deepEqual(target, { 'a': { 'b': { 'd': 1 } } });
});
test('removeFromValueTree: remove a multi segemented key when the last but one node has more values', () => {
test('removeFromValueTree: remove a multi segmented key when the last but one node has more values', () => {
let target = { 'a': { 'b': { 'c': 1, 'd': 1 } } };
removeFromValueTree(target, 'a.b.c');

View File

@@ -82,7 +82,7 @@ suite('ConfigurationModel', () => {
assert.deepEqual(testObject.keys, ['a.b']);
});
test('removeValue: remove a single segemented key', () => {
test('removeValue: remove a single segmented key', () => {
let testObject = new ConfigurationModel({ 'a': 1 }, ['a']);
testObject.removeValue('a');
@@ -91,7 +91,7 @@ suite('ConfigurationModel', () => {
assert.deepEqual(testObject.keys, []);
});
test('removeValue: remove a multi segemented key', () => {
test('removeValue: remove a multi segmented key', () => {
let testObject = new ConfigurationModel({ 'a': { 'b': 1 } }, ['a.b']);
testObject.removeValue('a.b');

View File

@@ -13,6 +13,7 @@ import { ConfigurationService } from 'vs/platform/configuration/node/configurati
import * as uuid from 'vs/base/common/uuid';
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
import { testFile } from 'vs/base/test/node/utils';
import { URI } from 'vs/base/common/uri';
suite('ConfigurationService - Node', () => {
@@ -20,7 +21,8 @@ suite('ConfigurationService - Node', () => {
const res = await testFile('config', 'config.json');
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
await service.initialize();
const config = service.getValue<{
foo: string;
}>();
@@ -37,7 +39,8 @@ suite('ConfigurationService - Node', () => {
fs.writeFileSync(res.testFile, '{ "testworkbench.editor.tabs": true }');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
await service.initialize();
const config = service.getValue<{
testworkbench: {
editor: {
@@ -59,7 +62,8 @@ suite('ConfigurationService - Node', () => {
fs.writeFileSync(res.testFile, ',,,,');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
await service.initialize();
const config = service.getValue<{
foo: string;
}>();
@@ -69,13 +73,14 @@ suite('ConfigurationService - Node', () => {
return res.cleanUp();
});
test('missing file does not explode', () => {
test('missing file does not explode', async () => {
const id = uuid.generateUuid();
const parentDir = path.join(os.tmpdir(), 'vsctests', id);
const newDir = path.join(parentDir, 'config', id);
const testFile = path.join(newDir, 'config.json');
const service = new ConfigurationService(testFile);
const service = new ConfigurationService(URI.file(testFile));
await service.initialize();
const config = service.getValue<{ foo: string }>();
assert.ok(config);
@@ -86,7 +91,8 @@ suite('ConfigurationService - Node', () => {
test('trigger configuration change event', async () => {
const res = await testFile('config', 'config.json');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
await service.initialize();
return new Promise((c, e) => {
service.onDidChangeConfiguration(() => {
assert.equal(service.getValue('foo'), 'bar');
@@ -103,7 +109,8 @@ suite('ConfigurationService - Node', () => {
fs.writeFileSync(res.testFile, '{ "foo": "bar" }');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
await service.initialize();
let config = service.getValue<{
foo: string;
}>();
@@ -130,7 +137,7 @@ suite('ConfigurationService - Node', () => {
return res.cleanUp();
});
test('model defaults', () => {
test('model defaults', async () => {
interface ITestSetting {
configuration: {
service: {
@@ -151,7 +158,8 @@ suite('ConfigurationService - Node', () => {
}
});
let serviceWithoutFile = new ConfigurationService('__testFile');
let serviceWithoutFile = new ConfigurationService(URI.file('__testFile'));
await serviceWithoutFile.initialize();
let setting = serviceWithoutFile.getValue<ITestSetting>();
assert.ok(setting);
@@ -160,7 +168,7 @@ suite('ConfigurationService - Node', () => {
return testFile('config', 'config.json').then(async res => {
fs.writeFileSync(res.testFile, '{ "testworkbench.editor.tabs": true }');
const service = new ConfigurationService(res.testFile);
const service = new ConfigurationService(URI.file(res.testFile));
let setting = service.getValue<ITestSetting>();
@@ -193,7 +201,9 @@ suite('ConfigurationService - Node', () => {
});
const r = await testFile('config', 'config.json');
const service = new ConfigurationService(r.testFile);
const service = new ConfigurationService(URI.file(r.testFile));
service.initialize();
let res = service.inspect('something.missing');
assert.strictEqual(res.value, undefined);
assert.strictEqual(res.default, undefined);
@@ -229,7 +239,9 @@ suite('ConfigurationService - Node', () => {
});
const r = await testFile('config', 'config.json');
const service = new ConfigurationService(r.testFile);
const service = new ConfigurationService(URI.file(r.testFile));
service.initialize();
let res = service.inspect('lookup.service.testNullSetting');
assert.strictEqual(res.default, null);
assert.strictEqual(res.value, null);