Merge vscode source through 1.62 release (#19981)

* Build breaks 1

* Build breaks

* Build breaks

* Build breaks

* More build breaks

* Build breaks (#2512)

* Runtime breaks

* Build breaks

* Fix dialog location break

* Update typescript

* Fix ASAR break issue

* Unit test breaks

* Update distro

* Fix breaks in ADO builds (#2513)

* Bump to node 16

* Fix hygiene errors

* Bump distro

* Remove reference to node type

* Delete vscode specific extension

* Bump to node 16 in CI yaml

* Skip integration tests in CI builds (while fixing)

* yarn.lock update

* Bump moment dependency in remote yarn

* Fix drop-down chevron style

* Bump to node 16

* Remove playwrite from ci.yaml

* Skip building build scripts in hygine check
This commit is contained in:
Karl Burtram
2022-07-11 14:09:32 -07:00
committed by GitHub
parent fa0fcef303
commit 26455e9113
1876 changed files with 72050 additions and 37997 deletions

View File

@@ -21,11 +21,12 @@ import { Workspace } from 'vs/platform/workspace/common/workspace';
export class ConfigurationModel implements IConfigurationModel {
private isFrozen: boolean = false;
private readonly overrideConfigurations = new Map<string, ConfigurationModel>();
constructor(
private _contents: any = {},
private _keys: string[] = [],
private _overrides: IOverrides[] = []
private readonly _contents: any = {},
private readonly _keys: string[] = [],
private readonly _overrides: IOverrides[] = []
) {
}
@@ -66,34 +67,12 @@ export class ConfigurationModel implements IConfigurationModel {
}
override(identifier: string): ConfigurationModel {
const overrideContents = this.getContentsForOverrideIdentifer(identifier);
if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
// If there are no valid overrides, return self
return this;
let overrideConfigurationModel = this.overrideConfigurations.get(identifier);
if (!overrideConfigurationModel) {
overrideConfigurationModel = this.createOverrideConfigurationModel(identifier);
this.overrideConfigurations.set(identifier, overrideConfigurationModel);
}
let contents: any = {};
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
let contentsForKey = this.contents[key];
let overrideContentsForKey = overrideContents[key];
// If there are override contents for the key, clone and merge otherwise use base contents
if (overrideContentsForKey) {
// Clone and merge only if base contents and override contents are of type object otherwise just override
if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
contentsForKey = objects.deepClone(contentsForKey);
this.mergeContents(contentsForKey, overrideContentsForKey);
} else {
contentsForKey = overrideContentsForKey;
}
}
contents[key] = contentsForKey;
}
return new ConfigurationModel(contents, this.keys, this.overrides);
return overrideConfigurationModel;
}
merge(...others: ConfigurationModel[]): ConfigurationModel {
@@ -126,6 +105,37 @@ export class ConfigurationModel implements IConfigurationModel {
return this;
}
private createOverrideConfigurationModel(identifier: string): ConfigurationModel {
const overrideContents = this.getContentsForOverrideIdentifer(identifier);
if (!overrideContents || typeof overrideContents !== 'object' || !Object.keys(overrideContents).length) {
// If there are no valid overrides, return self
return this;
}
let contents: any = {};
for (const key of arrays.distinct([...Object.keys(this.contents), ...Object.keys(overrideContents)])) {
let contentsForKey = this.contents[key];
let overrideContentsForKey = overrideContents[key];
// If there are override contents for the key, clone and merge otherwise use base contents
if (overrideContentsForKey) {
// Clone and merge only if base contents and override contents are of type object otherwise just override
if (typeof contentsForKey === 'object' && typeof overrideContentsForKey === 'object') {
contentsForKey = objects.deepClone(contentsForKey);
this.mergeContents(contentsForKey, overrideContentsForKey);
} else {
contentsForKey = overrideContentsForKey;
}
}
contents[key] = contentsForKey;
}
return new ConfigurationModel(contents, this.keys, this.overrides);
}
private mergeContents(source: any, target: any): void {
for (const key of Object.keys(target)) {
if (key in source) {

View File

@@ -3,6 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { distinct } from 'vs/base/common/arrays';
import { IStringDictionary } from 'vs/base/common/collections';
import { Emitter, Event } from 'vs/base/common/event';
import { IJSONSchema } from 'vs/base/common/jsonSchema';
@@ -37,6 +38,13 @@ export interface IConfigurationRegistry {
*/
deregisterConfigurations(configurations: IConfigurationNode[]): void;
/**
* update the configuration registry by
* - registering the configurations to add
* - dereigstering the configurations to remove
*/
updateConfigurations(configurations: { add: IConfigurationNode[], remove: IConfigurationNode[] }): void;
/**
* Register multiple default configurations to the registry.
*/
@@ -210,12 +218,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
}
public registerConfigurations(configurations: IConfigurationNode[], validate: boolean = true): void {
const properties: string[] = [];
configurations.forEach(configuration => {
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo)); // fills in defaults
this.configurationContributors.push(configuration);
this.registerJSONConfiguration(configuration);
});
const properties = this.doRegisterConfigurations(configurations, validate);
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
@@ -223,32 +226,23 @@ class ConfigurationRegistry implements IConfigurationRegistry {
}
public deregisterConfigurations(configurations: IConfigurationNode[]): void {
const properties: string[] = [];
const deregisterConfiguration = (configuration: IConfigurationNode) => {
if (configuration.properties) {
for (const key in configuration.properties) {
properties.push(key);
delete this.configurationProperties[key];
this.removeFromSchema(key, configuration.properties[key]);
}
}
if (configuration.allOf) {
configuration.allOf.forEach(node => deregisterConfiguration(node));
}
};
for (const configuration of configurations) {
deregisterConfiguration(configuration);
const index = this.configurationContributors.indexOf(configuration);
if (index !== -1) {
this.configurationContributors.splice(index, 1);
}
}
const properties = this.doDeregisterConfigurations(configurations);
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(properties);
}
public updateConfigurations({ add, remove }: { add: IConfigurationNode[], remove: IConfigurationNode[] }): void {
const properties = [];
properties.push(...this.doDeregisterConfigurations(remove));
properties.push(...this.doRegisterConfigurations(add, false));
contributionRegistry.registerSchema(resourceLanguageSettingsSchemaId, this.resourceLanguageSettingsSchema);
this._onDidSchemaChange.fire();
this._onDidUpdateConfiguration.fire(distinct(properties));
}
public registerDefaultConfigurations(defaultConfigurations: IStringDictionary<any>[]): void {
const properties: string[] = [];
const overrideIdentifiers: string[] = [];
@@ -319,6 +313,40 @@ class ConfigurationRegistry implements IConfigurationRegistry {
this.updateOverridePropertyPatternKey();
}
private doRegisterConfigurations(configurations: IConfigurationNode[], validate: boolean): string[] {
const properties: string[] = [];
configurations.forEach(configuration => {
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo)); // fills in defaults
this.configurationContributors.push(configuration);
this.registerJSONConfiguration(configuration);
});
return properties;
}
private doDeregisterConfigurations(configurations: IConfigurationNode[]): string[] {
const properties: string[] = [];
const deregisterConfiguration = (configuration: IConfigurationNode) => {
if (configuration.properties) {
for (const key in configuration.properties) {
properties.push(key);
delete this.configurationProperties[key];
this.removeFromSchema(key, configuration.properties[key]);
}
}
if (configuration.allOf) {
configuration.allOf.forEach(node => deregisterConfiguration(node));
}
};
for (const configuration of configurations) {
deregisterConfiguration(configuration);
const index = this.configurationContributors.indexOf(configuration);
if (index !== -1) {
this.configurationContributors.splice(index, 1);
}
}
return properties;
}
private validateAndRegisterProperties(configuration: IConfigurationNode, validate: boolean = true, extensionInfo?: IConfigurationExtensionInfo, scope: ConfigurationScope = ConfigurationScope.WINDOW): string[] {
scope = types.isUndefinedOrNull(configuration.scope) ? scope : configuration.scope;
let propertyKeys: string[] = [];

View File

@@ -8,9 +8,8 @@ import { VSBuffer } from 'vs/base/common/buffer';
import { JSONPath, parse, ParseError } from 'vs/base/common/json';
import { setProperty } from 'vs/base/common/jsonEdit';
import { Edit, FormattingOptions } from 'vs/base/common/jsonFormatter';
import { URI } from 'vs/base/common/uri';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { FileOperationError, FileOperationResult, IFileService } from 'vs/platform/files/common/files';
import { FileOperationError, FileOperationResult, IFileService, IWriteFileOptions } from 'vs/platform/files/common/files';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { ILogService } from 'vs/platform/log/common/log';
@@ -31,6 +30,7 @@ export interface IUserConfigurationFileService {
readonly _serviceBrand: undefined;
updateSettings(value: IJSONValue, formattingOptions: FormattingOptions): Promise<void>;
write(value: VSBuffer, options?: IWriteFileOptions): Promise<void>;
}
export class UserConfigurationFileService implements IUserConfigurationFileService {
@@ -48,12 +48,12 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
}
async updateSettings(value: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
return this.queue.queue(() => this.doWrite(this.environmentService.settingsResource, value, formattingOptions)); // queue up writes to prevent race conditions
return this.queue.queue(() => this.doWrite(value, formattingOptions)); // queue up writes to prevent race conditions
}
private async doWrite(resource: URI, jsonValue: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
this.logService.trace(`${UserConfigurationFileServiceId}#write`, resource.toString(), jsonValue);
const { value, mtime, etag } = await this.fileService.readFile(resource, { atomic: true });
private async doWrite(jsonValue: IJSONValue, formattingOptions: FormattingOptions): Promise<void> {
this.logService.trace(`${UserConfigurationFileServiceId}#write`, this.environmentService.settingsResource.toString(), jsonValue);
const { value, mtime, etag } = await this.fileService.readFile(this.environmentService.settingsResource, { atomic: true });
let content = value.toString();
const parseErrors: ParseError[] = [];
@@ -66,7 +66,7 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
if (edit) {
content = content.substring(0, edit.offset) + edit.content + content.substring(edit.offset + edit.length);
try {
await this.fileService.writeFile(resource, VSBuffer.fromString(content), { etag, mtime });
await this.fileService.writeFile(this.environmentService.settingsResource, VSBuffer.fromString(content), { etag, mtime });
} catch (error) {
if ((<FileOperationError>error).fileOperationResult === FileOperationResult.FILE_MODIFIED_SINCE) {
throw new Error(UserConfigurationErrorCode.ERROR_FILE_MODIFIED_SINCE);
@@ -75,6 +75,13 @@ export class UserConfigurationFileService implements IUserConfigurationFileServi
}
}
async write(content: VSBuffer, options?: IWriteFileOptions): Promise<void> {
// queue up writes to prevent race conditions
return this.queue.queue(async () => {
await this.fileService.writeFile(this.environmentService.settingsResource, content, options);
});
}
private getEdits({ value, path }: IJSONValue, modelContent: string, formattingOptions: FormattingOptions): Edit[] {
if (path.length) {
return setProperty(modelContent, path, value, formattingOptions);

View File

@@ -89,12 +89,12 @@ suite('ConfigurationService', () => {
test('trigger configuration change event when file does not exist', async () => {
const testObject = disposables.add(new ConfigurationService(settingsResource, fileService));
await testObject.initialize();
return new Promise<void>(async (c) => {
return new Promise<void>((c, e) => {
disposables.add(Event.filter(testObject.onDidChangeConfiguration, e => e.source === ConfigurationTarget.USER)(() => {
assert.strictEqual(testObject.getValue('foo'), 'bar');
c();
}));
await fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }'));
fileService.writeFile(settingsResource, VSBuffer.fromString('{ "foo": "bar" }')).catch(e);
});
});

View File

@@ -34,7 +34,7 @@ export class TestConfigurationService implements IConfigurationService {
}
configuration = configuration ? configuration : this.configuration;
if (arg1 && typeof arg1 === 'string') {
return getConfigurationValue(configuration, arg1);
return configuration[arg1] ?? getConfigurationValue(configuration, arg1);
}
return configuration;
}