mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-23 01:58:53 +01:00
[html] multi folder settings optimizations
This commit is contained in:
@@ -10,11 +10,11 @@ import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument,
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { ConfigurationFeature } from 'vscode-languageclient/lib/proposed';
|
||||
|
||||
import { DocumentColorRequest } from 'vscode-languageserver-protocol/lib/protocol.colorProvider.proposed';
|
||||
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
import { hash } from './utils/hash';
|
||||
let localize = nls.loadMessageBundle();
|
||||
|
||||
namespace VSCodeContentRequest {
|
||||
@@ -192,8 +192,6 @@ function getSettings(): Settings {
|
||||
let httpSettings = workspace.getConfiguration('http');
|
||||
let jsonSettings = workspace.getConfiguration('json');
|
||||
|
||||
let schemas = [];
|
||||
|
||||
let settings: Settings = {
|
||||
http: {
|
||||
proxy: httpSettings.get('proxy'),
|
||||
@@ -201,41 +199,69 @@ function getSettings(): Settings {
|
||||
},
|
||||
json: {
|
||||
format: jsonSettings.get('format'),
|
||||
schemas: schemas,
|
||||
schemas: [],
|
||||
}
|
||||
};
|
||||
let schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
|
||||
let collectSchemaSettings = (schemaSettings: JSONSchemaSettings[], rootPath?: string, fileMatchPrefix?: string) => {
|
||||
for (let setting of schemaSettings) {
|
||||
let url = getSchemaId(setting, rootPath);
|
||||
if (!url) {
|
||||
continue;
|
||||
}
|
||||
let schemaSetting = schemaSettingsById[url];
|
||||
if (!schemaSetting) {
|
||||
schemaSetting = schemaSettingsById[url] = { url, fileMatch: [] };
|
||||
settings.json.schemas.push(schemaSetting);
|
||||
}
|
||||
let fileMatches = setting.fileMatch;
|
||||
if (Array.isArray(fileMatches)) {
|
||||
if (fileMatchPrefix) {
|
||||
fileMatches = fileMatches.map(m => fileMatchPrefix + m);
|
||||
}
|
||||
schemaSetting.fileMatch.push(...fileMatches);
|
||||
}
|
||||
if (setting.schema) {
|
||||
schemaSetting.schema = setting.schema;
|
||||
}
|
||||
}
|
||||
};
|
||||
let settingsSchemas = jsonSettings.get('schemas');
|
||||
if (Array.isArray(settingsSchemas)) {
|
||||
schemas.push(...settingsSchemas);
|
||||
}
|
||||
|
||||
// merge global and folder settings. Qualify all file matches with the folder path.
|
||||
let globalSettings = jsonSettings.get<JSONSchemaSettings[]>('schemas');
|
||||
if (Array.isArray(globalSettings)) {
|
||||
collectSchemaSettings(globalSettings, workspace.rootPath);
|
||||
}
|
||||
let folders = workspace.workspaceFolders;
|
||||
if (folders) {
|
||||
folders.forEach(folder => {
|
||||
let jsonConfig = workspace.getConfiguration('json', folder.uri);
|
||||
let schemaConfigInfo = jsonConfig.inspect<JSONSchemaSettings[]>('schemas');
|
||||
for (let folder of folders) {
|
||||
let folderUri = folder.uri;
|
||||
let schemaConfigInfo = workspace.getConfiguration('json', folderUri).inspect<JSONSchemaSettings[]>('schemas');
|
||||
let folderSchemas = schemaConfigInfo.workspaceFolderValue;
|
||||
if (Array.isArray(folderSchemas)) {
|
||||
folderSchemas.forEach(schema => {
|
||||
let url = schema.url;
|
||||
if (!url && schema.schema) {
|
||||
url = schema.schema.id;
|
||||
}
|
||||
if (url && url[0] === '.') {
|
||||
url = Uri.file(path.normalize(path.join(folder.uri.fsPath, url))).toString();
|
||||
}
|
||||
let fileMatch = schema.fileMatch;
|
||||
if (fileMatch) {
|
||||
fileMatch = fileMatch.map(m => folder.uri.toString() + '*' + m);
|
||||
}
|
||||
schemas.push({ url, fileMatch, schema: schema.schema });
|
||||
});
|
||||
let folderPath = folderUri.toString();
|
||||
if (folderPath[folderPath.length - 1] !== '/') {
|
||||
folderPath = folderPath + '/';
|
||||
}
|
||||
collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath + '*');
|
||||
};
|
||||
});
|
||||
};
|
||||
}
|
||||
return settings;
|
||||
}
|
||||
|
||||
function getSchemaId(schema: JSONSchemaSettings, rootPath?: string) {
|
||||
let url = schema.url;
|
||||
if (!url) {
|
||||
if (schema.schema) {
|
||||
url = schema.schema.id || `vscode://schemas/custom/${encodeURIComponent(hash(schema.schema).toString(16))}`;
|
||||
}
|
||||
} else if (rootPath && (url[0] === '.' || url[0] === '/')) {
|
||||
url = Uri.file(path.normalize(path.join(rootPath, url))).toString();
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
function getPackageInfo(context: ExtensionContext): IPackageInfo {
|
||||
let extensionPackage = require(context.asAbsolutePath('./package.json'));
|
||||
if (extensionPackage) {
|
||||
|
||||
59
extensions/json/client/src/utils/hash.ts
Normal file
59
extensions/json/client/src/utils/hash.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Return a hash value for an object.
|
||||
*/
|
||||
export function hash(obj: any, hashVal = 0): number {
|
||||
switch (typeof obj) {
|
||||
case 'object':
|
||||
if (obj === null) {
|
||||
return numberHash(349, hashVal);
|
||||
} else if (Array.isArray(obj)) {
|
||||
return arrayHash(obj, hashVal);
|
||||
}
|
||||
return objectHash(obj, hashVal);
|
||||
case 'string':
|
||||
return stringHash(obj, hashVal);
|
||||
case 'boolean':
|
||||
return booleanHash(obj, hashVal);
|
||||
case 'number':
|
||||
return numberHash(obj, hashVal);
|
||||
case 'undefined':
|
||||
return numberHash(obj, 937);
|
||||
default:
|
||||
return numberHash(obj, 617);
|
||||
}
|
||||
}
|
||||
|
||||
function numberHash(val: number, initialHashVal: number): number {
|
||||
return (((initialHashVal << 5) - initialHashVal) + val) | 0; // hashVal * 31 + ch, keep as int32
|
||||
}
|
||||
|
||||
function booleanHash(b: boolean, initialHashVal: number): number {
|
||||
return numberHash(b ? 433 : 863, initialHashVal);
|
||||
}
|
||||
|
||||
function stringHash(s: string, hashVal: number) {
|
||||
hashVal = numberHash(149417, hashVal);
|
||||
for (let i = 0, length = s.length; i < length; i++) {
|
||||
hashVal = numberHash(s.charCodeAt(i), hashVal);
|
||||
}
|
||||
return hashVal;
|
||||
}
|
||||
|
||||
function arrayHash(arr: any[], initialHashVal: number): number {
|
||||
initialHashVal = numberHash(104579, initialHashVal);
|
||||
return arr.reduce((hashVal, item) => hash(item, hashVal), initialHashVal);
|
||||
}
|
||||
|
||||
function objectHash(obj: any, initialHashVal: number): number {
|
||||
initialHashVal = numberHash(181387, initialHashVal);
|
||||
return Object.keys(obj).sort().reduce((hashVal, key) => {
|
||||
hashVal = stringHash(key, hashVal);
|
||||
return hash(obj[key], hashVal);
|
||||
}, initialHashVal);
|
||||
}
|
||||
Reference in New Issue
Block a user