Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)

This commit is contained in:
Anthony Dresser
2019-03-26 11:43:38 -07:00
committed by GitHub
parent b1393ae615
commit 0d8ef9583b
268 changed files with 5947 additions and 3422 deletions

View File

@@ -29,6 +29,8 @@ export interface IConfigurationOverrides {
export const enum ConfigurationTarget {
USER = 1,
USER_LOCAL,
USER_REMOTE,
WORKSPACE,
WORKSPACE_FOLDER,
DEFAULT,
@@ -37,6 +39,8 @@ export const enum ConfigurationTarget {
export function ConfigurationTargetToString(configurationTarget: ConfigurationTarget) {
switch (configurationTarget) {
case ConfigurationTarget.USER: return 'USER';
case ConfigurationTarget.USER_LOCAL: return 'USER_LOCAL';
case ConfigurationTarget.USER_REMOTE: return 'USER_REMOTE';
case ConfigurationTarget.WORKSPACE: return 'WORKSPACE';
case ConfigurationTarget.WORKSPACE_FOLDER: return 'WORKSPACE_FOLDER';
case ConfigurationTarget.DEFAULT: return 'DEFAULT';
@@ -88,6 +92,8 @@ export interface IConfigurationService {
inspect<T>(key: string, overrides?: IConfigurationOverrides): {
default: T,
user: T,
userLocal?: T,
userRemote?: T,
workspace?: T,
workspaceFolder?: T,
memory?: T,

View File

@@ -36,6 +36,10 @@ export class ConfigurationModel implements IConfigurationModel {
return this.checkAndFreeze(this._keys);
}
isEmpty(): boolean {
return this._keys.length === 0 && Object.keys(this._contents).length === 0 && this._overrides.length === 0;
}
getValue<V>(section: string | undefined): V {
return section ? getConfigurationValue<any>(this.contents, section) : this.contents;
}
@@ -284,7 +288,8 @@ export class Configuration {
constructor(
private _defaultConfiguration: ConfigurationModel,
private _userConfiguration: ConfigurationModel,
private _localUserConfiguration: ConfigurationModel,
private _remoteUserConfiguration: ConfigurationModel = new ConfigurationModel(),
private _workspaceConfiguration: ConfigurationModel = new ConfigurationModel(),
private _folderConfigurations: ResourceMap<ConfigurationModel> = new ResourceMap<ConfigurationModel>(),
private _memoryConfiguration: ConfigurationModel = new ConfigurationModel(),
@@ -323,6 +328,8 @@ export class Configuration {
inspect<C>(key: string, overrides: IConfigurationOverrides, workspace: Workspace | undefined): {
default: C,
user: C,
userLocal?: C,
userRemote?: C,
workspace?: C,
workspaceFolder?: C
memory?: C
@@ -333,7 +340,9 @@ export class Configuration {
const memoryConfigurationModel = overrides.resource ? this._memoryConfigurationByResource.get(overrides.resource) || this._memoryConfiguration : this._memoryConfiguration;
return {
default: overrides.overrideIdentifier ? this._defaultConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._defaultConfiguration.freeze().getValue(key),
user: overrides.overrideIdentifier ? this._userConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._userConfiguration.freeze().getValue(key),
user: overrides.overrideIdentifier ? this.userConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.userConfiguration.freeze().getValue(key),
userLocal: overrides.overrideIdentifier ? this.localUserConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.localUserConfiguration.freeze().getValue(key),
userRemote: overrides.overrideIdentifier ? this.remoteUserConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this.remoteUserConfiguration.freeze().getValue(key),
workspace: workspace ? overrides.overrideIdentifier ? this._workspaceConfiguration.freeze().override(overrides.overrideIdentifier).getValue(key) : this._workspaceConfiguration.freeze().getValue(key) : undefined, //Check on workspace exists or not because _workspaceConfiguration is never null
workspaceFolder: folderConfigurationModel ? overrides.overrideIdentifier ? folderConfigurationModel.freeze().override(overrides.overrideIdentifier).getValue(key) : folderConfigurationModel.freeze().getValue(key) : undefined,
memory: overrides.overrideIdentifier ? memoryConfigurationModel.override(overrides.overrideIdentifier).getValue(key) : memoryConfigurationModel.getValue(key),
@@ -350,7 +359,7 @@ export class Configuration {
const folderConfigurationModel = this.getFolderConfigurationModelForResource(undefined, workspace);
return {
default: this._defaultConfiguration.freeze().keys,
user: this._userConfiguration.freeze().keys,
user: this.userConfiguration.freeze().keys,
workspace: this._workspaceConfiguration.freeze().keys,
workspaceFolder: folderConfigurationModel ? folderConfigurationModel.freeze().keys : []
};
@@ -362,8 +371,16 @@ export class Configuration {
this._foldersConsolidatedConfigurations.clear();
}
updateUserConfiguration(userConfiguration: ConfigurationModel): void {
this._userConfiguration = userConfiguration;
updateLocalUserConfiguration(localUserConfiguration: ConfigurationModel): void {
this._localUserConfiguration = localUserConfiguration;
this._userConfiguration = null;
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
updateRemoteUserConfiguration(remoteUserConfiguration: ConfigurationModel): void {
this._remoteUserConfiguration = remoteUserConfiguration;
this._userConfiguration = null;
this._workspaceConsolidatedConfiguration = null;
this._foldersConsolidatedConfigurations.clear();
}
@@ -380,7 +397,7 @@ export class Configuration {
}
deleteFolderConfiguration(resource: URI): void {
this.folders.delete(resource);
this.folderConfigurations.delete(resource);
this._foldersConsolidatedConfigurations.delete(resource);
}
@@ -388,15 +405,30 @@ export class Configuration {
return this._defaultConfiguration;
}
get user(): ConfigurationModel {
private _userConfiguration: ConfigurationModel | null;
get userConfiguration(): ConfigurationModel {
if (!this._userConfiguration) {
this._userConfiguration = this._remoteUserConfiguration.isEmpty() ? this._localUserConfiguration : this._localUserConfiguration.merge(this._remoteUserConfiguration);
if (this._freeze) {
this._userConfiguration.freeze();
}
}
return this._userConfiguration;
}
get workspace(): ConfigurationModel {
get localUserConfiguration(): ConfigurationModel {
return this._localUserConfiguration;
}
get remoteUserConfiguration(): ConfigurationModel {
return this._remoteUserConfiguration;
}
get workspaceConfiguration(): ConfigurationModel {
return this._workspaceConfiguration;
}
protected get folders(): ResourceMap<ConfigurationModel> {
protected get folderConfigurations(): ResourceMap<ConfigurationModel> {
return this._folderConfigurations;
}
@@ -424,7 +456,7 @@ export class Configuration {
private getWorkspaceConsolidatedConfiguration(): ConfigurationModel {
if (!this._workspaceConsolidatedConfiguration) {
this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this._userConfiguration, this._workspaceConfiguration, this._memoryConfiguration);
this._workspaceConsolidatedConfiguration = this._defaultConfiguration.merge(this.userConfiguration, this._workspaceConfiguration, this._memoryConfiguration);
if (this._freeze) {
this._workspaceConfiguration = this._workspaceConfiguration.freeze();
}
@@ -468,9 +500,9 @@ export class Configuration {
keys: this._defaultConfiguration.keys
},
user: {
contents: this._userConfiguration.contents,
overrides: this._userConfiguration.overrides,
keys: this._userConfiguration.keys
contents: this.userConfiguration.contents,
overrides: this.userConfiguration.overrides,
keys: this.userConfiguration.keys
},
workspace: {
contents: this._workspaceConfiguration.contents,
@@ -489,7 +521,7 @@ export class Configuration {
allKeys(workspace: Workspace | undefined): string[] {
let keys = this.keys(workspace);
let all = [...keys.default];
const addKeys = (keys) => {
const addKeys = (keys: string[]) => {
for (const key of keys) {
if (all.indexOf(key) === -1) {
all.push(key);
@@ -498,8 +530,8 @@ export class Configuration {
};
addKeys(keys.user);
addKeys(keys.workspace);
for (const resource of this.folders.keys()) {
addKeys(this.folders.get(resource)!.keys);
for (const resource of this.folderConfigurations.keys()) {
addKeys(this.folderConfigurations.get(resource)!.keys);
}
return all;
}

View File

@@ -3,13 +3,17 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable, toDisposable } 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';
import { RunOnceScheduler } from 'vs/base/common/async';
import { URI } from 'vs/base/common/uri';
import { IFileService, FileChangesEvent } from 'vs/platform/files/common/files';
import * as resources from 'vs/base/common/resources';
export class UserConfiguration extends Disposable {
export class NodeBasedUserConfiguration extends Disposable {
private userConfigModelWatcher: ConfigWatcher<ConfigurationModelParser>;
private initializePromise: Promise<void>;
@@ -50,4 +54,53 @@ export class UserConfiguration extends Disposable {
return this.initialize().then(() => new Promise<ConfigurationModel>(c => this.userConfigModelWatcher.reload(userConfigModelParser => c(userConfigModelParser.configurationModel))));
}
}
export class FileServiceBasedUserConfiguration extends Disposable {
private readonly reloadConfigurationScheduler: RunOnceScheduler;
protected readonly _onDidChangeConfiguration: Emitter<ConfigurationModel> = this._register(new Emitter<ConfigurationModel>());
readonly onDidChangeConfiguration: Event<ConfigurationModel> = this._onDidChangeConfiguration.event;
constructor(
private readonly configurationResource: URI,
private readonly fileService: IFileService
) {
super();
this._register(fileService.onFileChanges(e => this.handleFileEvents(e)));
this.reloadConfigurationScheduler = this._register(new RunOnceScheduler(() => this.reload().then(configurationModel => this._onDidChangeConfiguration.fire(configurationModel)), 50));
this.fileService.watchFileChanges(this.configurationResource);
this._register(toDisposable(() => this.fileService.unwatchFileChanges(this.configurationResource)));
}
initialize(): Promise<ConfigurationModel> {
return this.reload();
}
reload(): Promise<ConfigurationModel> {
return this.fileService.resolveContent(this.configurationResource)
.then(content => content.value, () => {
// File not found
return '';
}).then(content => {
const parser = new ConfigurationModelParser(this.configurationResource.toString());
parser.parse(content);
return parser.configurationModel;
});
}
private handleFileEvents(event: FileChangesEvent): void {
const events = event.changes;
let affectedByChanges = false;
// Find changes that affect workspace file
for (let i = 0, len = events.length; i < len && !affectedByChanges; i++) {
affectedByChanges = resources.isEqual(this.configurationResource, events[i].resource);
}
if (affectedByChanges) {
this.reloadConfigurationScheduler.schedule();
}
}
}

View File

@@ -11,14 +11,14 @@ import { DefaultConfigurationModel, Configuration, ConfigurationChangeEvent, Con
import { Event, Emitter } from 'vs/base/common/event';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IWorkspaceFolder } from 'vs/platform/workspace/common/workspace';
import { UserConfiguration } from 'vs/platform/configuration/node/configuration';
import { NodeBasedUserConfiguration } from 'vs/platform/configuration/node/configuration';
export class ConfigurationService extends Disposable implements IConfigurationService, IDisposable {
_serviceBrand: any;
private _configuration: Configuration;
private userConfiguration: UserConfiguration;
private userConfiguration: NodeBasedUserConfiguration;
private readonly _onDidChangeConfiguration: Emitter<IConfigurationChangeEvent> = this._register(new Emitter<IConfigurationChangeEvent>());
readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
@@ -28,7 +28,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
) {
super();
this.userConfiguration = this._register(new UserConfiguration(environmentService.appSettingsPath));
this.userConfiguration = this._register(new NodeBasedUserConfiguration(environmentService.appSettingsPath));
// Initialize
const defaults = new DefaultConfigurationModel();
@@ -91,10 +91,10 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
}
private onDidChangeUserConfiguration(userConfigurationModel: ConfigurationModel): void {
const { added, updated, removed } = compare(this._configuration.user, userConfigurationModel);
const { added, updated, removed } = compare(this._configuration.localUserConfiguration, userConfigurationModel);
const changedKeys = [...added, ...updated, ...removed];
if (changedKeys.length) {
this._configuration.updateUserConfiguration(userConfigurationModel);
this._configuration.updateLocalUserConfiguration(userConfigurationModel);
this.trigger(changedKeys, ConfigurationTarget.USER);
}
}
@@ -113,7 +113,7 @@ export class ConfigurationService extends Disposable implements IConfigurationSe
case ConfigurationTarget.DEFAULT:
return this._configuration.defaults.contents;
case ConfigurationTarget.USER:
return this._configuration.user.contents;
return this._configuration.localUserConfiguration.contents;
}
return {};
}

View File

@@ -56,6 +56,8 @@ export class TestConfigurationService implements IConfigurationService {
public inspect<T>(key: string, overrides?: IConfigurationOverrides): {
default: T,
user: T,
userLocal?: T,
userRemote?: T,
workspace?: T,
workspaceFolder?: T
value: T,