mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-13 17:22:15 -05:00
Merge from vscode merge-base (#22769)
* Merge from vscode merge-base * Turn off basic checks * Enable compilation, unit, and integration tests
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ExtensionContext, Uri } from 'vscode';
|
||||
import { LanguageClientOptions } from 'vscode-languageclient';
|
||||
import { BaseLanguageClient, LanguageClientOptions } from 'vscode-languageclient';
|
||||
import { startClient, LanguageClientConstructor, SchemaRequestService } from '../jsonClient';
|
||||
import { LanguageClient } from 'vscode-languageclient/browser';
|
||||
|
||||
@@ -14,8 +14,10 @@ declare const Worker: {
|
||||
|
||||
declare function fetch(uri: string, options: any): any;
|
||||
|
||||
let client: BaseLanguageClient | undefined;
|
||||
|
||||
// this method is called when vs code is activated
|
||||
export function activate(context: ExtensionContext) {
|
||||
export async function activate(context: ExtensionContext) {
|
||||
const serverMain = Uri.joinPath(context.extensionUri, 'server/dist/browser/jsonServerMain.js');
|
||||
try {
|
||||
const worker = new Worker(serverMain.toString());
|
||||
@@ -32,9 +34,16 @@ export function activate(context: ExtensionContext) {
|
||||
}
|
||||
};
|
||||
|
||||
startClient(context, newLanguageClient, { schemaRequests });
|
||||
client = await startClient(context, newLanguageClient, { schemaRequests });
|
||||
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function deactivate(): Promise<void> {
|
||||
if (client) {
|
||||
await client.stop();
|
||||
client = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,18 +9,19 @@ const localize = nls.loadMessageBundle();
|
||||
export type JSONLanguageStatus = { schemas: string[] };
|
||||
|
||||
import {
|
||||
workspace, window, languages, commands, ExtensionContext, extensions, Uri,
|
||||
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken,
|
||||
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString,
|
||||
workspace, window, languages, commands, ExtensionContext, extensions, Uri, ColorInformation,
|
||||
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, FoldingRange,
|
||||
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString, FoldingContext, DocumentSymbol, SymbolInformation
|
||||
} from 'vscode';
|
||||
import {
|
||||
LanguageClientOptions, RequestType, NotificationType,
|
||||
DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams,
|
||||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, CommonLanguageClient
|
||||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, ProvideHoverSignature, BaseLanguageClient, ProvideFoldingRangeSignature, ProvideDocumentSymbolsSignature, ProvideDocumentColorsSignature
|
||||
} from 'vscode-languageclient';
|
||||
|
||||
|
||||
import { hash } from './utils/hash';
|
||||
import { createLanguageStatusItem } from './languageStatus';
|
||||
import { createDocumentColorsLimitItem, createDocumentSymbolsLimitItem, createFoldingRangeLimitItem, createLanguageStatusItem, createLimitStatusItem } from './languageStatus';
|
||||
|
||||
namespace VSCodeContentRequest {
|
||||
export const type: RequestType<string, string, any> = new RequestType('vscode/content');
|
||||
@@ -52,14 +53,11 @@ namespace SchemaAssociationNotification {
|
||||
export const type: NotificationType<ISchemaAssociations | ISchemaAssociation[]> = new NotificationType('json/schemaAssociations');
|
||||
}
|
||||
|
||||
namespace ResultLimitReachedNotification {
|
||||
export const type: NotificationType<string> = new NotificationType('json/resultLimitReached');
|
||||
}
|
||||
|
||||
interface Settings {
|
||||
type Settings = {
|
||||
json?: {
|
||||
schemas?: JSONSchemaSettings[];
|
||||
format?: { enable?: boolean };
|
||||
keepLines?: { enable?: boolean };
|
||||
validate?: { enable?: boolean };
|
||||
resultLimit?: number;
|
||||
};
|
||||
@@ -67,25 +65,22 @@ interface Settings {
|
||||
proxy?: string;
|
||||
proxyStrictSSL?: boolean;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
export interface JSONSchemaSettings {
|
||||
export type JSONSchemaSettings = {
|
||||
fileMatch?: string[];
|
||||
url?: string;
|
||||
schema?: any;
|
||||
}
|
||||
};
|
||||
|
||||
namespace SettingIds {
|
||||
export namespace SettingIds {
|
||||
export const enableFormatter = 'json.format.enable';
|
||||
export const enableKeepLines = 'json.format.keepLines';
|
||||
export const enableValidation = 'json.validate.enable';
|
||||
export const enableSchemaDownload = 'json.schemaDownload.enable';
|
||||
export const maxItemsComputed = 'json.maxItemsComputed';
|
||||
}
|
||||
|
||||
namespace StorageIds {
|
||||
export const maxItemsExceededInformation = 'json.maxItemsExceededInformation';
|
||||
}
|
||||
|
||||
export interface TelemetryReporter {
|
||||
sendTelemetryEvent(eventName: string, properties?: {
|
||||
[key: string]: string;
|
||||
@@ -94,7 +89,7 @@ export interface TelemetryReporter {
|
||||
}): void;
|
||||
}
|
||||
|
||||
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => CommonLanguageClient;
|
||||
export type LanguageClientConstructor = (name: string, description: string, clientOptions: LanguageClientOptions) => BaseLanguageClient;
|
||||
|
||||
export interface Runtime {
|
||||
schemaRequests: SchemaRequestService;
|
||||
@@ -108,7 +103,9 @@ export interface SchemaRequestService {
|
||||
|
||||
export const languageServerDescription = localize('jsonserver.name', 'JSON Language Server');
|
||||
|
||||
export function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime) {
|
||||
let resultLimit = 5000;
|
||||
|
||||
export async function startClient(context: ExtensionContext, newLanguageClient: LanguageClientConstructor, runtime: Runtime): Promise<BaseLanguageClient> {
|
||||
|
||||
const toDispose = context.subscriptions;
|
||||
|
||||
@@ -126,6 +123,11 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
|
||||
let isClientReady = false;
|
||||
|
||||
const foldingRangeLimitStatusBarItem = createLimitStatusItem((limit: number) => createFoldingRangeLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
||||
const documentSymbolsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentSymbolsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
||||
const documentColorsLimitStatusbarItem = createLimitStatusItem((limit: number) => createDocumentColorsLimitItem(documentSelector, SettingIds.maxItemsComputed, limit));
|
||||
toDispose.push(foldingRangeLimitStatusBarItem, documentSymbolsLimitStatusbarItem, documentColorsLimitStatusbarItem);
|
||||
|
||||
toDispose.push(commands.registerCommand('json.clearCache', async () => {
|
||||
if (isClientReady && runtime.schemaRequests.clearCache) {
|
||||
const cachedSchemas = await runtime.schemaRequests.clearCache();
|
||||
@@ -210,6 +212,60 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
return r.then(updateHover);
|
||||
}
|
||||
return updateHover(r);
|
||||
},
|
||||
provideFoldingRanges(document: TextDocument, context: FoldingContext, token: CancellationToken, next: ProvideFoldingRangeSignature) {
|
||||
function checkLimit(r: FoldingRange[] | null | undefined): FoldingRange[] | null | undefined {
|
||||
if (Array.isArray(r) && r.length > resultLimit) {
|
||||
r.length = resultLimit; // truncate
|
||||
foldingRangeLimitStatusBarItem.update(document, resultLimit);
|
||||
} else {
|
||||
foldingRangeLimitStatusBarItem.update(document, false);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const r = next(document, context, token);
|
||||
if (isThenable<FoldingRange[] | null | undefined>(r)) {
|
||||
return r.then(checkLimit);
|
||||
}
|
||||
return checkLimit(r);
|
||||
},
|
||||
provideDocumentColors(document: TextDocument, token: CancellationToken, next: ProvideDocumentColorsSignature) {
|
||||
function checkLimit(r: ColorInformation[] | null | undefined): ColorInformation[] | null | undefined {
|
||||
if (Array.isArray(r) && r.length > resultLimit) {
|
||||
r.length = resultLimit; // truncate
|
||||
documentColorsLimitStatusbarItem.update(document, resultLimit);
|
||||
} else {
|
||||
documentColorsLimitStatusbarItem.update(document, false);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const r = next(document, token);
|
||||
if (isThenable<ColorInformation[] | null | undefined>(r)) {
|
||||
return r.then(checkLimit);
|
||||
}
|
||||
return checkLimit(r);
|
||||
},
|
||||
provideDocumentSymbols(document: TextDocument, token: CancellationToken, next: ProvideDocumentSymbolsSignature) {
|
||||
type T = SymbolInformation[] | DocumentSymbol[];
|
||||
function countDocumentSymbols(symbols: DocumentSymbol[]): number {
|
||||
return symbols.reduce((previousValue, s) => previousValue + 1 + countDocumentSymbols(s.children), 0);
|
||||
}
|
||||
function isDocumentSymbol(r: T): r is DocumentSymbol[] {
|
||||
return r[0] instanceof DocumentSymbol;
|
||||
}
|
||||
function checkLimit(r: T | null | undefined): T | null | undefined {
|
||||
if (Array.isArray(r) && (isDocumentSymbol(r) ? countDocumentSymbols(r) : r.length) > resultLimit) {
|
||||
documentSymbolsLimitStatusbarItem.update(document, resultLimit);
|
||||
} else {
|
||||
documentSymbolsLimitStatusbarItem.update(document, false);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const r = next(document, token);
|
||||
if (isThenable<T | undefined | null>(r)) {
|
||||
return r.then(checkLimit);
|
||||
}
|
||||
return checkLimit(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -218,176 +274,162 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
||||
const client = newLanguageClient('json', languageServerDescription, clientOptions);
|
||||
client.registerProposedFeatures();
|
||||
|
||||
const disposable = client.start();
|
||||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
isClientReady = true;
|
||||
const schemaDocuments: { [uri: string]: boolean } = {};
|
||||
|
||||
const schemaDocuments: { [uri: string]: boolean } = {};
|
||||
|
||||
// handle content request
|
||||
client.onRequest(VSCodeContentRequest.type, (uriPath: string) => {
|
||||
const uri = Uri.parse(uriPath);
|
||||
if (uri.scheme === 'untitled') {
|
||||
return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString())));
|
||||
}
|
||||
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
|
||||
return workspace.openTextDocument(uri).then(doc => {
|
||||
schemaDocuments[uri.toString()] = true;
|
||||
return doc.getText();
|
||||
}, error => {
|
||||
return Promise.reject(new ResponseError(2, error.toString()));
|
||||
});
|
||||
} else if (schemaDownloadEnabled) {
|
||||
if (runtime.telemetry && uri.authority === 'schema.management.azure.com') {
|
||||
/* __GDPR__
|
||||
"json.schema" : {
|
||||
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
|
||||
}
|
||||
return runtime.schemaRequests.getContent(uriPath).catch(e => {
|
||||
return Promise.reject(new ResponseError(4, e.toString()));
|
||||
});
|
||||
} else {
|
||||
return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload)));
|
||||
}
|
||||
});
|
||||
|
||||
const handleContentChange = (uriString: string) => {
|
||||
if (schemaDocuments[uriString]) {
|
||||
client.sendNotification(SchemaContentChangeNotification.type, uriString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleActiveEditorChange = (activeEditor?: TextEditor) => {
|
||||
if (!activeEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeDocUri = activeEditor.document.uri.toString();
|
||||
|
||||
if (activeDocUri && fileSchemaErrors.has(activeDocUri)) {
|
||||
schemaResolutionErrorStatusBarItem.show();
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.hide();
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri.toString())));
|
||||
toDispose.push(workspace.onDidCloseTextDocument(d => {
|
||||
const uriString = d.uri.toString();
|
||||
if (handleContentChange(uriString)) {
|
||||
delete schemaDocuments[uriString];
|
||||
}
|
||||
fileSchemaErrors.delete(uriString);
|
||||
}));
|
||||
toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange));
|
||||
|
||||
const handleRetryResolveSchemaCommand = () => {
|
||||
if (window.activeTextEditor) {
|
||||
schemaResolutionErrorStatusBarItem.text = '$(watch)';
|
||||
const activeDocUri = window.activeTextEditor.document.uri.toString();
|
||||
client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => {
|
||||
const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError);
|
||||
if (schemaErrorIndex !== -1) {
|
||||
// Show schema resolution errors in status bar only; ref: #51032
|
||||
const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
|
||||
fileSchemaErrors.set(activeDocUri, schemaResolveDiagnostic.message);
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.hide();
|
||||
}
|
||||
schemaResolutionErrorStatusBarItem.text = '$(alert)';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand));
|
||||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context));
|
||||
|
||||
toDispose.push(extensions.onDidChange(_ => {
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context));
|
||||
}));
|
||||
|
||||
// manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652.
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
|
||||
updateSchemaDownloadSetting();
|
||||
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(SettingIds.enableFormatter)) {
|
||||
updateFormatterRegistration();
|
||||
} else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) {
|
||||
updateSchemaDownloadSetting();
|
||||
}
|
||||
}));
|
||||
|
||||
client.onNotification(ResultLimitReachedNotification.type, async message => {
|
||||
const shouldPrompt = context.globalState.get<boolean>(StorageIds.maxItemsExceededInformation) !== false;
|
||||
if (shouldPrompt) {
|
||||
const ok = localize('ok', "OK");
|
||||
const openSettings = localize('goToSetting', 'Open Settings');
|
||||
const neverAgain = localize('yes never again', "Don't Show Again");
|
||||
const pick = await window.showInformationMessage(`${message}\n${localize('configureLimit', 'Use setting \'{0}\' to configure the limit.', SettingIds.maxItemsComputed)}`, ok, openSettings, neverAgain);
|
||||
if (pick === neverAgain) {
|
||||
await context.globalState.update(StorageIds.maxItemsExceededInformation, false);
|
||||
} else if (pick === openSettings) {
|
||||
await commands.executeCommand('workbench.action.openSettings', SettingIds.maxItemsComputed);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
toDispose.push(createLanguageStatusItem(documentSelector, (uri: string) => client.sendRequest(LanguageStatusRequest.type, uri)));
|
||||
|
||||
function updateFormatterRegistration() {
|
||||
const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter);
|
||||
if (!formatEnabled && rangeFormatting) {
|
||||
rangeFormatting.dispose();
|
||||
rangeFormatting = undefined;
|
||||
} else if (formatEnabled && !rangeFormatting) {
|
||||
rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, {
|
||||
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
|
||||
const filesConfig = workspace.getConfiguration('files', document);
|
||||
const fileFormattingOptions = {
|
||||
trimTrailingWhitespace: filesConfig.get<boolean>('trimTrailingWhitespace'),
|
||||
trimFinalNewlines: filesConfig.get<boolean>('trimFinalNewlines'),
|
||||
insertFinalNewline: filesConfig.get<boolean>('insertFinalNewline'),
|
||||
};
|
||||
const params: DocumentRangeFormattingParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
range: client.code2ProtocolConverter.asRange(range),
|
||||
options: client.code2ProtocolConverter.asFormattingOptions(options, fileFormattingOptions)
|
||||
};
|
||||
|
||||
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
|
||||
client.protocol2CodeConverter.asTextEdits,
|
||||
(error) => {
|
||||
client.handleFailedRequest(DocumentRangeFormattingRequest.type, error, []);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
// handle content request
|
||||
client.onRequest(VSCodeContentRequest.type, (uriPath: string) => {
|
||||
const uri = Uri.parse(uriPath);
|
||||
if (uri.scheme === 'untitled') {
|
||||
return Promise.reject(new ResponseError(3, localize('untitled.schema', 'Unable to load {0}', uri.toString())));
|
||||
}
|
||||
|
||||
function updateSchemaDownloadSetting() {
|
||||
schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false;
|
||||
if (schemaDownloadEnabled) {
|
||||
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.');
|
||||
schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema';
|
||||
handleRetryResolveSchemaCommand();
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.');
|
||||
schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' };
|
||||
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
|
||||
return workspace.openTextDocument(uri).then(doc => {
|
||||
schemaDocuments[uri.toString()] = true;
|
||||
return doc.getText();
|
||||
}, error => {
|
||||
return Promise.reject(new ResponseError(2, error.toString()));
|
||||
});
|
||||
} else if (schemaDownloadEnabled) {
|
||||
if (runtime.telemetry && uri.authority === 'schema.management.azure.com') {
|
||||
/* __GDPR__
|
||||
"json.schema" : {
|
||||
"owner": "aeschli",
|
||||
"comment": "Measure the use of the Azure resource manager schemas",
|
||||
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "comment": "The azure schema URL that was requested." }
|
||||
}
|
||||
*/
|
||||
runtime.telemetry.sendTelemetryEvent('json.schema', { schemaURL: uriPath });
|
||||
}
|
||||
return runtime.schemaRequests.getContent(uriPath).catch(e => {
|
||||
return Promise.reject(new ResponseError(4, e.toString()));
|
||||
});
|
||||
} else {
|
||||
return Promise.reject(new ResponseError(1, localize('schemaDownloadDisabled', 'Downloading schemas is disabled through setting \'{0}\'', SettingIds.enableSchemaDownload)));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
await client.start();
|
||||
|
||||
isClientReady = true;
|
||||
|
||||
const handleContentChange = (uriString: string) => {
|
||||
if (schemaDocuments[uriString]) {
|
||||
client.sendNotification(SchemaContentChangeNotification.type, uriString);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
const handleActiveEditorChange = (activeEditor?: TextEditor) => {
|
||||
if (!activeEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
const activeDocUri = activeEditor.document.uri.toString();
|
||||
|
||||
if (activeDocUri && fileSchemaErrors.has(activeDocUri)) {
|
||||
schemaResolutionErrorStatusBarItem.show();
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.hide();
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(workspace.onDidChangeTextDocument(e => handleContentChange(e.document.uri.toString())));
|
||||
toDispose.push(workspace.onDidCloseTextDocument(d => {
|
||||
const uriString = d.uri.toString();
|
||||
if (handleContentChange(uriString)) {
|
||||
delete schemaDocuments[uriString];
|
||||
}
|
||||
fileSchemaErrors.delete(uriString);
|
||||
}));
|
||||
toDispose.push(window.onDidChangeActiveTextEditor(handleActiveEditorChange));
|
||||
|
||||
const handleRetryResolveSchemaCommand = () => {
|
||||
if (window.activeTextEditor) {
|
||||
schemaResolutionErrorStatusBarItem.text = '$(watch)';
|
||||
const activeDocUri = window.activeTextEditor.document.uri.toString();
|
||||
client.sendRequest(ForceValidateRequest.type, activeDocUri).then((diagnostics) => {
|
||||
const schemaErrorIndex = diagnostics.findIndex(isSchemaResolveError);
|
||||
if (schemaErrorIndex !== -1) {
|
||||
// Show schema resolution errors in status bar only; ref: #51032
|
||||
const schemaResolveDiagnostic = diagnostics[schemaErrorIndex];
|
||||
fileSchemaErrors.set(activeDocUri, schemaResolveDiagnostic.message);
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.hide();
|
||||
}
|
||||
schemaResolutionErrorStatusBarItem.text = '$(alert)';
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
toDispose.push(commands.registerCommand('_json.retryResolveSchema', handleRetryResolveSchemaCommand));
|
||||
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context));
|
||||
|
||||
toDispose.push(extensions.onDidChange(_ => {
|
||||
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations(context));
|
||||
}));
|
||||
|
||||
// manually register / deregister format provider based on the `json.format.enable` setting avoiding issues with late registration. See #71652.
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
|
||||
updateSchemaDownloadSetting();
|
||||
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(SettingIds.enableFormatter)) {
|
||||
updateFormatterRegistration();
|
||||
} else if (e.affectsConfiguration(SettingIds.enableSchemaDownload)) {
|
||||
updateSchemaDownloadSetting();
|
||||
}
|
||||
}));
|
||||
|
||||
toDispose.push(createLanguageStatusItem(documentSelector, (uri: string) => client.sendRequest(LanguageStatusRequest.type, uri)));
|
||||
|
||||
function updateFormatterRegistration() {
|
||||
const formatEnabled = workspace.getConfiguration().get(SettingIds.enableFormatter);
|
||||
if (!formatEnabled && rangeFormatting) {
|
||||
rangeFormatting.dispose();
|
||||
rangeFormatting = undefined;
|
||||
} else if (formatEnabled && !rangeFormatting) {
|
||||
rangeFormatting = languages.registerDocumentRangeFormattingEditProvider(documentSelector, {
|
||||
provideDocumentRangeFormattingEdits(document: TextDocument, range: Range, options: FormattingOptions, token: CancellationToken): ProviderResult<TextEdit[]> {
|
||||
const filesConfig = workspace.getConfiguration('files', document);
|
||||
const fileFormattingOptions = {
|
||||
trimTrailingWhitespace: filesConfig.get<boolean>('trimTrailingWhitespace'),
|
||||
trimFinalNewlines: filesConfig.get<boolean>('trimFinalNewlines'),
|
||||
insertFinalNewline: filesConfig.get<boolean>('insertFinalNewline'),
|
||||
};
|
||||
const params: DocumentRangeFormattingParams = {
|
||||
textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
|
||||
range: client.code2ProtocolConverter.asRange(range),
|
||||
options: client.code2ProtocolConverter.asFormattingOptions(options, fileFormattingOptions)
|
||||
};
|
||||
|
||||
return client.sendRequest(DocumentRangeFormattingRequest.type, params, token).then(
|
||||
client.protocol2CodeConverter.asTextEdits,
|
||||
(error) => {
|
||||
client.handleFailedRequest(DocumentRangeFormattingRequest.type, undefined, error, []);
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function updateSchemaDownloadSetting() {
|
||||
schemaDownloadEnabled = workspace.getConfiguration().get(SettingIds.enableSchemaDownload) !== false;
|
||||
if (schemaDownloadEnabled) {
|
||||
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionErrorMessage', 'Unable to resolve schema. Click to retry.');
|
||||
schemaResolutionErrorStatusBarItem.command = '_json.retryResolveSchema';
|
||||
handleRetryResolveSchemaCommand();
|
||||
} else {
|
||||
schemaResolutionErrorStatusBarItem.tooltip = localize('json.schemaResolutionDisabledMessage', 'Downloading schemas is disabled. Click to configure.');
|
||||
schemaResolutionErrorStatusBarItem.command = { command: 'workbench.action.openSettings', arguments: [SettingIds.enableSchemaDownload], title: '' };
|
||||
}
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] {
|
||||
@@ -430,7 +472,7 @@ function getSettings(): Settings {
|
||||
const configuration = workspace.getConfiguration();
|
||||
const httpSettings = workspace.getConfiguration('http');
|
||||
|
||||
const resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000;
|
||||
resultLimit = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get(SettingIds.maxItemsComputed)))) || 5000;
|
||||
|
||||
const settings: Settings = {
|
||||
http: {
|
||||
@@ -440,8 +482,9 @@ function getSettings(): Settings {
|
||||
json: {
|
||||
validate: { enable: configuration.get(SettingIds.enableValidation) },
|
||||
format: { enable: configuration.get(SettingIds.enableFormatter) },
|
||||
keepLines: { enable: configuration.get(SettingIds.enableKeepLines) },
|
||||
schemas: [],
|
||||
resultLimit
|
||||
resultLimit: resultLimit + 1 // ask for one more so we can detect if the limit has been exceeded
|
||||
}
|
||||
};
|
||||
const schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
|
||||
|
||||
@@ -3,7 +3,11 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { window, languages, Uri, LanguageStatusSeverity, Disposable, commands, QuickPickItem, extensions, workspace, Extension, WorkspaceFolder, QuickPickItemKind, ThemeIcon } from 'vscode';
|
||||
import {
|
||||
window, languages, Uri, Disposable, commands, QuickPickItem,
|
||||
extensions, workspace, Extension, WorkspaceFolder, QuickPickItemKind,
|
||||
ThemeIcon, TextDocument, LanguageStatusSeverity
|
||||
} from 'vscode';
|
||||
import { JSONLanguageStatus, JSONSchemaSettings } from './jsonClient';
|
||||
|
||||
import * as nls from 'vscode-nls';
|
||||
@@ -187,13 +191,13 @@ export function createLanguageStatusItem(documentSelector: string[], statusReque
|
||||
statusItem.detail = undefined;
|
||||
if (schemas.length === 0) {
|
||||
statusItem.text = localize('status.noSchema.short', "No Schema Validation");
|
||||
statusItem.detail = localize('status.noSchema', 'No JSON schema configured.');
|
||||
statusItem.detail = localize('status.noSchema', 'no JSON schema configured');
|
||||
} else if (schemas.length === 1) {
|
||||
statusItem.text = localize('status.withSchema.short', "Schema Validated");
|
||||
statusItem.detail = localize('status.singleSchema', 'JSON schema configured.');
|
||||
statusItem.detail = localize('status.singleSchema', 'JSON schema configured');
|
||||
} else {
|
||||
statusItem.text = localize('status.withSchemas.short', "Schema Validated");
|
||||
statusItem.detail = localize('status.multipleSchema', 'Multiple JSON schemas configured.');
|
||||
statusItem.detail = localize('status.multipleSchema', 'multiple JSON schemas configured');
|
||||
}
|
||||
statusItem.command = {
|
||||
command: '_json.showAssociatedSchemaList',
|
||||
@@ -217,3 +221,85 @@ export function createLanguageStatusItem(documentSelector: string[], statusReque
|
||||
return Disposable.from(statusItem, activeEditorListener, showSchemasCommand);
|
||||
}
|
||||
|
||||
export function createLimitStatusItem(newItem: (limit: number) => Disposable) {
|
||||
let statusItem: Disposable | undefined;
|
||||
const activeLimits: Map<TextDocument, number> = new Map();
|
||||
|
||||
const toDispose: Disposable[] = [];
|
||||
toDispose.push(window.onDidChangeActiveTextEditor(textEditor => {
|
||||
statusItem?.dispose();
|
||||
statusItem = undefined;
|
||||
const doc = textEditor?.document;
|
||||
if (doc) {
|
||||
const limit = activeLimits.get(doc);
|
||||
if (limit !== undefined) {
|
||||
statusItem = newItem(limit);
|
||||
}
|
||||
}
|
||||
}));
|
||||
toDispose.push(workspace.onDidCloseTextDocument(document => {
|
||||
activeLimits.delete(document);
|
||||
}));
|
||||
|
||||
function update(document: TextDocument, limitApplied: number | false) {
|
||||
if (limitApplied === false) {
|
||||
activeLimits.delete(document);
|
||||
if (statusItem && document === window.activeTextEditor?.document) {
|
||||
statusItem.dispose();
|
||||
statusItem = undefined;
|
||||
}
|
||||
} else {
|
||||
activeLimits.set(document, limitApplied);
|
||||
if (document === window.activeTextEditor?.document) {
|
||||
if (!statusItem || limitApplied !== activeLimits.get(document)) {
|
||||
statusItem?.dispose();
|
||||
statusItem = newItem(limitApplied);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {
|
||||
update,
|
||||
dispose() {
|
||||
statusItem?.dispose();
|
||||
toDispose.forEach(d => d.dispose());
|
||||
toDispose.length = 0;
|
||||
statusItem = undefined;
|
||||
activeLimits.clear();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const openSettingsCommand = 'workbench.action.openSettings';
|
||||
const configureSettingsLabel = localize('status.button.configure', "Configure");
|
||||
|
||||
export function createFoldingRangeLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable {
|
||||
const statusItem = languages.createLanguageStatusItem('json.foldingRangesStatus', documentSelector);
|
||||
statusItem.name = localize('foldingRangesStatusItem.name', "JSON Folding Status");
|
||||
statusItem.severity = LanguageStatusSeverity.Warning;
|
||||
statusItem.text = localize('status.limitedFoldingRanges.short', "Folding Ranges Limited");
|
||||
statusItem.detail = localize('status.limitedFoldingRanges.details', 'only {0} folding ranges shown', limit);
|
||||
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
||||
return Disposable.from(statusItem);
|
||||
}
|
||||
|
||||
export function createDocumentSymbolsLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable {
|
||||
const statusItem = languages.createLanguageStatusItem('json.documentSymbolsStatus', documentSelector);
|
||||
statusItem.name = localize('documentSymbolsStatusItem.name', "JSON Outline Status");
|
||||
statusItem.severity = LanguageStatusSeverity.Warning;
|
||||
statusItem.text = localize('status.limitedDocumentSymbols.short', "Outline Limited");
|
||||
statusItem.detail = localize('status.limitedDocumentSymbols.details', 'only {0} document symbols shown', limit);
|
||||
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
||||
return Disposable.from(statusItem);
|
||||
}
|
||||
|
||||
export function createDocumentColorsLimitItem(documentSelector: string[], settingId: string, limit: number): Disposable {
|
||||
const statusItem = languages.createLanguageStatusItem('json.documentColorsStatus', documentSelector);
|
||||
statusItem.name = localize('documentColorsStatusItem.name', "JSON Color Symbol Status");
|
||||
statusItem.severity = LanguageStatusSeverity.Warning;
|
||||
statusItem.text = localize('status.limitedDocumentColors.short', "Color Symbols Limited");
|
||||
statusItem.detail = localize('status.limitedDocumentColors.details', 'only {0} color decorators shown', limit);
|
||||
statusItem.command = { command: openSettingsCommand, arguments: [settingId], title: configureSettingsLabel };
|
||||
return Disposable.from(statusItem);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { ExtensionContext, OutputChannel, window, workspace } from 'vscode';
|
||||
import { startClient, LanguageClientConstructor, SchemaRequestService, languageServerDescription } from '../jsonClient';
|
||||
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient } from 'vscode-languageclient/node';
|
||||
import { ServerOptions, TransportKind, LanguageClientOptions, LanguageClient, BaseLanguageClient } from 'vscode-languageclient/node';
|
||||
|
||||
import { promises as fs } from 'fs';
|
||||
import * as path from 'path';
|
||||
@@ -15,6 +15,7 @@ import TelemetryReporter from '@vscode/extension-telemetry';
|
||||
import { JSONSchemaCache } from './schemaCache';
|
||||
|
||||
let telemetry: TelemetryReporter | undefined;
|
||||
let client: BaseLanguageClient | undefined;
|
||||
|
||||
// this method is called when vs code is activated
|
||||
export async function activate(context: ExtensionContext) {
|
||||
@@ -45,11 +46,15 @@ export async function activate(context: ExtensionContext) {
|
||||
|
||||
const schemaRequests = await getSchemaRequestService(context, log);
|
||||
|
||||
startClient(context, newLanguageClient, { schemaRequests, telemetry });
|
||||
client = await startClient(context, newLanguageClient, { schemaRequests, telemetry });
|
||||
}
|
||||
|
||||
export function deactivate(): Promise<any> {
|
||||
return telemetry ? telemetry.dispose() : Promise.resolve(null);
|
||||
export async function deactivate(): Promise<any> {
|
||||
if (client) {
|
||||
await client.stop();
|
||||
client = undefined;
|
||||
}
|
||||
telemetry?.dispose();
|
||||
}
|
||||
|
||||
interface IPackageInfo {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"license": "MIT",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"aiKey": "0c6ae279ed8443289764825290e4f9e2-1a736e7c-1324-4338-be46-fc2a58ae4d14-7255",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
@@ -85,6 +85,12 @@
|
||||
"default": true,
|
||||
"description": "%json.format.enable.desc%"
|
||||
},
|
||||
"json.format.keepLines": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": false,
|
||||
"description": "%json.format.keepLines.desc%"
|
||||
},
|
||||
"json.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
@@ -147,10 +153,10 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vscode/extension-telemetry": "0.5.0",
|
||||
"@vscode/extension-telemetry": "0.6.2",
|
||||
"request-light": "^0.5.8",
|
||||
"vscode-languageclient": "^7.0.0",
|
||||
"vscode-nls": "^5.0.0"
|
||||
"vscode-languageclient": "^8.0.2-next.5",
|
||||
"vscode-nls": "^5.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "16.x"
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
"json.schemas.fileMatch.item.desc": "A file pattern that can contain '*' to match against when resolving JSON files to schemas.",
|
||||
"json.schemas.schema.desc": "The schema definition for the given URL. The schema only needs to be provided to avoid accesses to the schema URL.",
|
||||
"json.format.enable.desc": "Enable/disable default JSON formatter",
|
||||
"json.format.keepLines.desc" : "Keep all existing new lines when formatting.",
|
||||
"json.validate.enable.desc": "Enable/disable JSON validation.",
|
||||
"json.tracing.desc": "Traces the communication between Azure Data Studio and the JSON language server.",
|
||||
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
|
||||
|
||||
@@ -188,12 +188,6 @@ Notification:
|
||||
### Item Limit
|
||||
|
||||
If the setting `resultLimit` is set, the JSON language server will limit the number of folding ranges and document symbols computed.
|
||||
When the limit is reached, a notification `json/resultLimitReached` is sent that can be shown that can be shown to the user.
|
||||
|
||||
Notification:
|
||||
- method: 'json/resultLimitReached'
|
||||
- params: a human readable string to show to the user.
|
||||
|
||||
|
||||
## Try
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
},
|
||||
"main": "./out/node/jsonServerMain",
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^3.0.0",
|
||||
"jsonc-parser": "^3.1.0",
|
||||
"request-light": "^0.5.8",
|
||||
"vscode-json-languageservice": "^4.2.1",
|
||||
"vscode-languageserver": "^7.0.0",
|
||||
"vscode-json-languageservice": "^5.1.0",
|
||||
"vscode-languageserver": "^8.0.2-next.5",
|
||||
"vscode-uri": "^3.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
import {
|
||||
Connection,
|
||||
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions, Diagnostic
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { formatError, runSafe, runSafeAsync } from './utils/runner';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Diagnostic, Range, Position } from 'vscode-json-languageservice';
|
||||
import { runSafe, runSafeAsync } from './utils/runner';
|
||||
import { DiagnosticsSupport, registerDiagnosticsPullSupport, registerDiagnosticsPushSupport } from './utils/validation';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, Range, Position } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
import { Utils, URI } from 'vscode-uri';
|
||||
|
||||
@@ -30,10 +31,6 @@ namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string | string[]> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ResultLimitReachedNotification {
|
||||
export const type: NotificationType<string> = new NotificationType('json/resultLimitReached');
|
||||
}
|
||||
|
||||
namespace ForceValidateRequest {
|
||||
export const type: RequestType<string, Diagnostic[], any> = new RequestType('json/validate');
|
||||
}
|
||||
@@ -68,7 +65,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
|
||||
function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) {
|
||||
const builtInHandlers: { [protocol: string]: RequestService | undefined } = {};
|
||||
for (let protocol of handledSchemas) {
|
||||
for (const protocol of handledSchemas) {
|
||||
if (protocol === 'file') {
|
||||
builtInHandlers[protocol] = runtime.file;
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
@@ -113,11 +110,16 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
let resultLimit = Number.MAX_VALUE;
|
||||
let formatterMaxNumberOfEdits = Number.MAX_VALUE;
|
||||
|
||||
let diagnosticsSupport: DiagnosticsSupport | undefined;
|
||||
|
||||
|
||||
// After the server has started the client sends an initialize request. The server receives
|
||||
// in the passed params the rootPath of the workspace plus the client capabilities.
|
||||
connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
|
||||
const handledProtocols = params.initializationOptions?.handledSchemaProtocols;
|
||||
const initializationOptions = params.initializationOptions as any || {};
|
||||
|
||||
const handledProtocols = initializationOptions?.handledSchemaProtocols;
|
||||
|
||||
languageService = getLanguageService({
|
||||
schemaRequestService: getSchemaRequestService(handledProtocols),
|
||||
@@ -139,10 +141,18 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
}
|
||||
|
||||
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions?.provideFormatter !== 'boolean');
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof initializationOptions.provideFormatter !== 'boolean');
|
||||
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
|
||||
formatterMaxNumberOfEdits = params.initializationOptions?.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE;
|
||||
formatterMaxNumberOfEdits = initializationOptions.customCapabilities?.rangeFormatting?.editLimit || Number.MAX_VALUE;
|
||||
|
||||
const supportsDiagnosticPull = getClientCapability('textDocument.diagnostic', undefined);
|
||||
if (supportsDiagnosticPull === undefined) {
|
||||
diagnosticsSupport = registerDiagnosticsPushSupport(documents, connection, runtime, validateTextDocument);
|
||||
} else {
|
||||
diagnosticsSupport = registerDiagnosticsPullSupport(documents, connection, runtime, validateTextDocument);
|
||||
}
|
||||
|
||||
const capabilities: ServerCapabilities = {
|
||||
textDocumentSync: TextDocumentSyncKind.Incremental,
|
||||
completionProvider: clientSnippetSupport ? {
|
||||
@@ -151,12 +161,17 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
} : undefined,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
documentRangeFormattingProvider: params.initializationOptions?.provideFormatter === true,
|
||||
documentFormattingProvider: params.initializationOptions?.provideFormatter === true,
|
||||
documentRangeFormattingProvider: initializationOptions.provideFormatter === true,
|
||||
documentFormattingProvider: initializationOptions.provideFormatter === true,
|
||||
colorProvider: {},
|
||||
foldingRangeProvider: true,
|
||||
selectionRangeProvider: true,
|
||||
documentLinkProvider: {}
|
||||
documentLinkProvider: {},
|
||||
diagnosticProvider: {
|
||||
documentSelector: null,
|
||||
interFileDependencies: false,
|
||||
workspaceDiagnostics: false
|
||||
}
|
||||
};
|
||||
|
||||
return { capabilities };
|
||||
@@ -169,6 +184,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
json?: {
|
||||
schemas?: JSONSchemaSettings[];
|
||||
format?: { enable?: boolean };
|
||||
keepLines?: { enable?: boolean };
|
||||
validate?: { enable?: boolean };
|
||||
resultLimit?: number;
|
||||
};
|
||||
@@ -185,58 +201,20 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
}
|
||||
|
||||
|
||||
const limitExceededWarnings = function () {
|
||||
const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: Disposable } } = {};
|
||||
|
||||
const showLimitedNotification = (uri: string, resultLimit: number) => {
|
||||
const warning = pendingWarnings[uri];
|
||||
connection.sendNotification(ResultLimitReachedNotification.type, `${Utils.basename(URI.parse(uri))}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
|
||||
warning.timeout = undefined;
|
||||
};
|
||||
|
||||
return {
|
||||
cancel(uri: string) {
|
||||
const warning = pendingWarnings[uri];
|
||||
if (warning && warning.timeout) {
|
||||
warning.timeout.dispose();
|
||||
delete pendingWarnings[uri];
|
||||
}
|
||||
},
|
||||
|
||||
onResultLimitExceeded(uri: string, resultLimit: number, name: string) {
|
||||
return () => {
|
||||
let warning = pendingWarnings[uri];
|
||||
if (warning) {
|
||||
if (!warning.timeout) {
|
||||
// already shown
|
||||
return;
|
||||
}
|
||||
warning.features[name] = name;
|
||||
warning.timeout.dispose();
|
||||
warning.timeout = runtime.timer.setTimeout(() => showLimitedNotification(uri, resultLimit), 2000);
|
||||
} else {
|
||||
warning = { features: { [name]: name } };
|
||||
warning.timeout = runtime.timer.setTimeout(() => showLimitedNotification(uri, resultLimit), 2000);
|
||||
pendingWarnings[uri] = warning;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}();
|
||||
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
|
||||
let schemaAssociations: ISchemaAssociations | SchemaConfiguration[] | undefined = undefined;
|
||||
let formatterRegistrations: Thenable<Disposable>[] | null = null;
|
||||
let validateEnabled = true;
|
||||
let keepLinesEnabled = false;
|
||||
|
||||
// The settings have changed. Is send on server activation as well.
|
||||
// The settings have changed. Is sent on server activation as well.
|
||||
connection.onDidChangeConfiguration((change) => {
|
||||
let settings = <Settings>change.settings;
|
||||
if (runtime.configureHttpRequests) {
|
||||
runtime.configureHttpRequests(settings?.http?.proxy, !!settings.http?.proxyStrictSSL);
|
||||
}
|
||||
const settings = <Settings>change.settings;
|
||||
runtime.configureHttpRequests?.(settings?.http?.proxy, !!settings.http?.proxyStrictSSL);
|
||||
jsonConfigurationSettings = settings.json?.schemas;
|
||||
validateEnabled = !!settings.json?.validate?.enable;
|
||||
keepLinesEnabled = settings.json?.keepLines?.enable || false;
|
||||
updateConfiguration();
|
||||
|
||||
foldingRangeLimit = Math.trunc(Math.max(settings.json?.resultLimit || foldingRangeLimitDefault, 0));
|
||||
@@ -279,25 +257,18 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
needsRevalidation = languageService.resetSchema(uriOrUris);
|
||||
}
|
||||
if (needsRevalidation) {
|
||||
for (const doc of documents.all()) {
|
||||
triggerValidation(doc);
|
||||
}
|
||||
diagnosticsSupport?.requestRefresh();
|
||||
}
|
||||
});
|
||||
|
||||
// Retry schema validation on all open documents
|
||||
connection.onRequest(ForceValidateRequest.type, uri => {
|
||||
return new Promise<Diagnostic[]>(resolve => {
|
||||
const document = documents.get(uri);
|
||||
if (document) {
|
||||
updateConfiguration();
|
||||
validateTextDocument(document, diagnostics => {
|
||||
resolve(diagnostics);
|
||||
});
|
||||
} else {
|
||||
resolve([]);
|
||||
}
|
||||
});
|
||||
connection.onRequest(ForceValidateRequest.type, async uri => {
|
||||
const document = documents.get(uri);
|
||||
if (document) {
|
||||
updateConfiguration();
|
||||
return await validateTextDocument(document);
|
||||
}
|
||||
return [];
|
||||
});
|
||||
|
||||
connection.onRequest(LanguageStatusRequest.type, async uri => {
|
||||
@@ -343,72 +314,16 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
}
|
||||
languageService.configure(languageSettings);
|
||||
|
||||
// Revalidate any open text documents
|
||||
documents.all().forEach(triggerValidation);
|
||||
diagnosticsSupport?.requestRefresh();
|
||||
}
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent((change) => {
|
||||
limitExceededWarnings.cancel(change.document.uri);
|
||||
triggerValidation(change.document);
|
||||
});
|
||||
|
||||
// a document has closed: clear all diagnostics
|
||||
documents.onDidClose(event => {
|
||||
limitExceededWarnings.cancel(event.document.uri);
|
||||
cleanPendingValidation(event.document);
|
||||
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
|
||||
});
|
||||
|
||||
const pendingValidationRequests: { [uri: string]: Disposable } = {};
|
||||
const validationDelayMs = 300;
|
||||
|
||||
function cleanPendingValidation(textDocument: TextDocument): void {
|
||||
const request = pendingValidationRequests[textDocument.uri];
|
||||
if (request) {
|
||||
request.dispose();
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
}
|
||||
}
|
||||
|
||||
function triggerValidation(textDocument: TextDocument): void {
|
||||
cleanPendingValidation(textDocument);
|
||||
if (validateEnabled) {
|
||||
pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(() => {
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
validateTextDocument(textDocument);
|
||||
}, validationDelayMs);
|
||||
} else {
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
|
||||
}
|
||||
}
|
||||
|
||||
function validateTextDocument(textDocument: TextDocument, callback?: (diagnostics: Diagnostic[]) => void): void {
|
||||
const respond = (diagnostics: Diagnostic[]) => {
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
if (callback) {
|
||||
callback(diagnostics);
|
||||
}
|
||||
};
|
||||
async function validateTextDocument(textDocument: TextDocument): Promise<Diagnostic[]> {
|
||||
if (textDocument.getText().length === 0) {
|
||||
respond([]); // ignore empty documents
|
||||
return;
|
||||
return []; // ignore empty documents
|
||||
}
|
||||
const jsonDocument = getJSONDocument(textDocument);
|
||||
const version = textDocument.version;
|
||||
|
||||
const documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'warning' } : { comments: 'error', trailingCommas: 'error' };
|
||||
languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => {
|
||||
runtime.timer.setImmediate(() => {
|
||||
const currDocument = documents.get(textDocument.uri);
|
||||
if (currDocument && currDocument.version === version) {
|
||||
respond(diagnostics); // Send the computed diagnostics to VSCode.
|
||||
}
|
||||
});
|
||||
}, error => {
|
||||
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, error));
|
||||
});
|
||||
return await languageService.doValidation(textDocument, jsonDocument, documentSettings);
|
||||
}
|
||||
|
||||
connection.onDidChangeWatchedFiles((change) => {
|
||||
@@ -420,7 +335,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
}
|
||||
});
|
||||
if (hasChanges) {
|
||||
documents.all().forEach(triggerValidation);
|
||||
diagnosticsSupport?.requestRefresh();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -463,11 +378,10 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
const document = documents.get(documentSymbolParams.textDocument.uri);
|
||||
if (document) {
|
||||
const jsonDocument = getJSONDocument(document);
|
||||
const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document symbols');
|
||||
if (hierarchicalDocumentSymbolSupport) {
|
||||
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit });
|
||||
} else {
|
||||
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit });
|
||||
}
|
||||
}
|
||||
return [];
|
||||
@@ -475,6 +389,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
});
|
||||
|
||||
function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] {
|
||||
options.keepLines = keepLinesEnabled;
|
||||
const document = documents.get(textDocument.uri);
|
||||
if (document) {
|
||||
const edits = languageService.format(document, range ?? getFullRange(document), options);
|
||||
@@ -499,9 +414,9 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
return runSafeAsync(runtime, async () => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const onResultLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, resultLimit, 'document colors');
|
||||
|
||||
const jsonDocument = getJSONDocument(document);
|
||||
return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
return languageService.findDocumentColors(document, jsonDocument, { resultLimit });
|
||||
}
|
||||
return [];
|
||||
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
|
||||
@@ -522,8 +437,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
|
||||
return runSafe(runtime, () => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
const onRangeLimitExceeded = limitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges');
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded });
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit });
|
||||
}
|
||||
return null;
|
||||
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
|
||||
|
||||
@@ -18,10 +18,10 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
let cleanupInterval: NodeJS.Timer | undefined = undefined;
|
||||
if (cleanupIntervalTimeInSec > 0) {
|
||||
cleanupInterval = setInterval(() => {
|
||||
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
let uris = Object.keys(languageModels);
|
||||
for (let uri of uris) {
|
||||
let languageModelInfo = languageModels[uri];
|
||||
const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
const uris = Object.keys(languageModels);
|
||||
for (const uri of uris) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < cutoffTime) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
@@ -32,14 +32,14 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
|
||||
return {
|
||||
get(document: TextDocument): T {
|
||||
let version = document.version;
|
||||
let languageId = document.languageId;
|
||||
let languageModelInfo = languageModels[document.uri];
|
||||
const version = document.version;
|
||||
const languageId = document.languageId;
|
||||
const languageModelInfo = languageModels[document.uri];
|
||||
if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) {
|
||||
languageModelInfo.cTime = Date.now();
|
||||
return languageModelInfo.languageModel;
|
||||
}
|
||||
let languageModel = parse(document);
|
||||
const languageModel = parse(document);
|
||||
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() };
|
||||
if (!languageModelInfo) {
|
||||
nModels++;
|
||||
@@ -48,8 +48,8 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
if (nModels === maxEntries) {
|
||||
let oldestTime = Number.MAX_VALUE;
|
||||
let oldestUri = null;
|
||||
for (let uri in languageModels) {
|
||||
let languageModelInfo = languageModels[uri];
|
||||
for (const uri in languageModels) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < oldestTime) {
|
||||
oldestUri = uri;
|
||||
oldestTime = languageModelInfo.cTime;
|
||||
@@ -64,7 +64,7 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
|
||||
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
let uri = document.uri;
|
||||
const uri = document.uri;
|
||||
if (languageModels[uri]) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { RuntimeEnvironment } from '../jsonServer';
|
||||
|
||||
export function formatError(message: string, err: any): string {
|
||||
if (err instanceof Error) {
|
||||
let error = <Error>err;
|
||||
const error = <Error>err;
|
||||
return `${message}: ${error.message}\n${error.stack}`;
|
||||
} else if (typeof err === 'string') {
|
||||
return `${message}: ${err}`;
|
||||
@@ -47,7 +47,7 @@ export function runSafe<T, E>(runtime: RuntimeEnvironment, func: () => T, errorV
|
||||
resolve(cancelValue());
|
||||
} else {
|
||||
try {
|
||||
let result = func();
|
||||
const result = func();
|
||||
if (token.isCancellationRequested) {
|
||||
resolve(cancelValue());
|
||||
return;
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
* Determines if haystack ends with needle.
|
||||
*/
|
||||
export function endsWith(haystack: string, needle: string): boolean {
|
||||
let diff = haystack.length - needle.length;
|
||||
const diff = haystack.length - needle.length;
|
||||
if (diff > 0) {
|
||||
return haystack.lastIndexOf(needle) === diff;
|
||||
} else if (diff === 0) {
|
||||
|
||||
108
extensions/json-language-features/server/src/utils/validation.ts
Normal file
108
extensions/json-language-features/server/src/utils/validation.ts
Normal file
@@ -0,0 +1,108 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { CancellationToken, Connection, Diagnostic, Disposable, DocumentDiagnosticParams, DocumentDiagnosticReport, DocumentDiagnosticReportKind, TextDocuments } from 'vscode-languageserver';
|
||||
import { TextDocument } from 'vscode-json-languageservice';
|
||||
import { formatError, runSafeAsync } from './runner';
|
||||
import { RuntimeEnvironment } from '../jsonServer';
|
||||
|
||||
export type Validator = (textDocument: TextDocument) => Promise<Diagnostic[]>;
|
||||
export type DiagnosticsSupport = {
|
||||
dispose(): void;
|
||||
requestRefresh(): void;
|
||||
};
|
||||
|
||||
export function registerDiagnosticsPushSupport(documents: TextDocuments<TextDocument>, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport {
|
||||
|
||||
const pendingValidationRequests: { [uri: string]: Disposable } = {};
|
||||
const validationDelayMs = 500;
|
||||
|
||||
const disposables: Disposable[] = [];
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent(change => {
|
||||
triggerValidation(change.document);
|
||||
}, undefined, disposables);
|
||||
|
||||
// a document has closed: clear all diagnostics
|
||||
documents.onDidClose(event => {
|
||||
cleanPendingValidation(event.document);
|
||||
connection.sendDiagnostics({ uri: event.document.uri, diagnostics: [] });
|
||||
}, undefined, disposables);
|
||||
|
||||
function cleanPendingValidation(textDocument: TextDocument): void {
|
||||
const request = pendingValidationRequests[textDocument.uri];
|
||||
if (request) {
|
||||
request.dispose();
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
}
|
||||
}
|
||||
|
||||
function triggerValidation(textDocument: TextDocument): void {
|
||||
cleanPendingValidation(textDocument);
|
||||
const request = pendingValidationRequests[textDocument.uri] = runtime.timer.setTimeout(async () => {
|
||||
if (request === pendingValidationRequests[textDocument.uri]) {
|
||||
try {
|
||||
const diagnostics = await validate(textDocument);
|
||||
if (request === pendingValidationRequests[textDocument.uri]) {
|
||||
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
|
||||
}
|
||||
delete pendingValidationRequests[textDocument.uri];
|
||||
} catch (e) {
|
||||
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e));
|
||||
}
|
||||
}
|
||||
}, validationDelayMs);
|
||||
}
|
||||
|
||||
return {
|
||||
requestRefresh: () => {
|
||||
documents.all().forEach(triggerValidation);
|
||||
},
|
||||
dispose: () => {
|
||||
disposables.forEach(d => d.dispose());
|
||||
disposables.length = 0;
|
||||
const keys = Object.keys(pendingValidationRequests);
|
||||
for (const key of keys) {
|
||||
pendingValidationRequests[key].dispose();
|
||||
delete pendingValidationRequests[key];
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function registerDiagnosticsPullSupport(documents: TextDocuments<TextDocument>, connection: Connection, runtime: RuntimeEnvironment, validate: Validator): DiagnosticsSupport {
|
||||
|
||||
function newDocumentDiagnosticReport(diagnostics: Diagnostic[]): DocumentDiagnosticReport {
|
||||
return {
|
||||
kind: DocumentDiagnosticReportKind.Full,
|
||||
items: diagnostics
|
||||
};
|
||||
}
|
||||
|
||||
const registration = connection.languages.diagnostics.on(async (params: DocumentDiagnosticParams, token: CancellationToken) => {
|
||||
return runSafeAsync(runtime, async () => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return newDocumentDiagnosticReport(await validate(document));
|
||||
}
|
||||
return newDocumentDiagnosticReport([]);
|
||||
|
||||
}, newDocumentDiagnosticReport([]), `Error while computing diagnostics for ${params.textDocument.uri}`, token);
|
||||
});
|
||||
|
||||
function requestRefresh(): void {
|
||||
connection.languages.diagnostics.refresh();
|
||||
}
|
||||
|
||||
return {
|
||||
requestRefresh,
|
||||
dispose: () => {
|
||||
registration.dispose();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
@@ -12,61 +12,66 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
|
||||
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
|
||||
|
||||
jsonc-parser@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22"
|
||||
integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==
|
||||
jsonc-parser@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d"
|
||||
integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==
|
||||
|
||||
request-light@^0.5.8:
|
||||
version "0.5.8"
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.8.tgz#8bf73a07242b9e7b601fac2fa5dc22a094abcc27"
|
||||
integrity sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==
|
||||
|
||||
vscode-json-languageservice@^4.2.1:
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz#94b6f471ece193bf4a1ef37f6ab5cce86d50a8b4"
|
||||
integrity sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA==
|
||||
vscode-json-languageservice@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-5.1.0.tgz#b1f197a60338cb378189fcb41489a84846724dd9"
|
||||
integrity sha512-D5612D7h/Gh4A0JmdttPveWzT9dur21WXvBHWKPdOt0sLO6ILz8vN6+IzWnvwDOVAEFTpzIAMVMZwbKZkwGGiA==
|
||||
dependencies:
|
||||
jsonc-parser "^3.0.0"
|
||||
vscode-languageserver-textdocument "^1.0.3"
|
||||
vscode-languageserver-types "^3.16.0"
|
||||
vscode-nls "^5.0.0"
|
||||
jsonc-parser "^3.1.0"
|
||||
vscode-languageserver-textdocument "^1.0.4"
|
||||
vscode-languageserver-types "^3.17.1"
|
||||
vscode-nls "^5.0.1"
|
||||
vscode-uri "^3.0.3"
|
||||
|
||||
vscode-jsonrpc@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
|
||||
integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
|
||||
vscode-jsonrpc@8.0.2-next.1:
|
||||
version "8.0.2-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6"
|
||||
integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA==
|
||||
|
||||
vscode-languageserver-protocol@3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
|
||||
integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
|
||||
vscode-languageserver-protocol@3.17.2-next.6:
|
||||
version "3.17.2-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc"
|
||||
integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA==
|
||||
dependencies:
|
||||
vscode-jsonrpc "6.0.0"
|
||||
vscode-languageserver-types "3.16.0"
|
||||
vscode-jsonrpc "8.0.2-next.1"
|
||||
vscode-languageserver-types "3.17.2-next.2"
|
||||
|
||||
vscode-languageserver-textdocument@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.3.tgz#879f2649bfa5a6e07bc8b392c23ede2dfbf43eff"
|
||||
integrity sha512-ynEGytvgTb6HVSUwPJIAZgiHQmPCx8bZ8w5um5Lz+q5DjP0Zj8wTFhQpyg8xaMvefDytw2+HH5yzqS+FhsR28A==
|
||||
vscode-languageserver-textdocument@^1.0.4:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.4.tgz#3cd56dd14cec1d09e86c4bb04b09a246cb3df157"
|
||||
integrity sha512-/xhqXP/2A2RSs+J8JNXpiiNVvvNM0oTosNVmQnunlKvq9o4mupHOBAnnzH0lwIPKazXKvAKsVp1kr+H/K4lgoQ==
|
||||
|
||||
vscode-languageserver-types@3.16.0, vscode-languageserver-types@^3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
|
||||
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
|
||||
vscode-languageserver-types@3.17.2-next.2:
|
||||
version "3.17.2-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596"
|
||||
integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w==
|
||||
|
||||
vscode-languageserver@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0"
|
||||
integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==
|
||||
vscode-languageserver-types@^3.17.1:
|
||||
version "3.17.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16"
|
||||
integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ==
|
||||
|
||||
vscode-languageserver@^8.0.2-next.5:
|
||||
version "8.0.2-next.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-8.0.2-next.5.tgz#39a2dd4c504fb88042375e7ac706a714bdaab4e5"
|
||||
integrity sha512-2ZDb7O/4atS9mJKufPPz637z+51kCyZfgnobFW5eSrUdS3c0UB/nMS4Ng1EavYTX84GVaVMKCrmP0f2ceLmR0A==
|
||||
dependencies:
|
||||
vscode-languageserver-protocol "3.16.0"
|
||||
vscode-languageserver-protocol "3.17.2-next.6"
|
||||
|
||||
vscode-nls@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
|
||||
integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
|
||||
vscode-nls@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2"
|
||||
integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A==
|
||||
|
||||
vscode-uri@^3.0.3:
|
||||
version "3.0.3"
|
||||
|
||||
@@ -2,15 +2,54 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@microsoft/1ds-core-js@3.2.3", "@microsoft/1ds-core-js@^3.2.3":
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/1ds-core-js/-/1ds-core-js-3.2.3.tgz#2217d92ec8b073caa4577a13f40ea3a5c4c4d4e7"
|
||||
integrity sha512-796A8fd90oUKDRO7UXUT9BwZ3G+a9XzJj5v012FcCN/2qRhEsIV3x/0wkx2S08T4FiQEUPkB2uoYHpEjEneM7g==
|
||||
dependencies:
|
||||
"@microsoft/applicationinsights-core-js" "2.8.4"
|
||||
"@microsoft/applicationinsights-shims" "^2.0.1"
|
||||
"@microsoft/dynamicproto-js" "^1.1.6"
|
||||
|
||||
"@microsoft/1ds-post-js@^3.2.3":
|
||||
version "3.2.3"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/1ds-post-js/-/1ds-post-js-3.2.3.tgz#1fa7d51615a44f289632ae8c588007ba943db216"
|
||||
integrity sha512-tcGJQXXr2LYoBbIXPoUVe1KCF3OtBsuKDFL7BXfmNtuSGtWF0yejm6H83DrR8/cUIGMRMUP9lqNlqFGwDYiwAQ==
|
||||
dependencies:
|
||||
"@microsoft/1ds-core-js" "3.2.3"
|
||||
"@microsoft/applicationinsights-shims" "^2.0.1"
|
||||
"@microsoft/dynamicproto-js" "^1.1.6"
|
||||
|
||||
"@microsoft/applicationinsights-core-js@2.8.4":
|
||||
version "2.8.4"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-core-js/-/applicationinsights-core-js-2.8.4.tgz#607e531bb241a8920d43960f68a7c76a6f9af596"
|
||||
integrity sha512-FoA0FNOsFbJnLyTyQlYs6+HR7HMEa6nAOE6WOm9WVejBHMHQ/Bdb+hfVFi6slxwCimr/ner90jchi4/sIYdnyQ==
|
||||
dependencies:
|
||||
"@microsoft/applicationinsights-shims" "2.0.1"
|
||||
"@microsoft/dynamicproto-js" "^1.1.6"
|
||||
|
||||
"@microsoft/applicationinsights-shims@2.0.1", "@microsoft/applicationinsights-shims@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/applicationinsights-shims/-/applicationinsights-shims-2.0.1.tgz#5d72fb7aaf4056c4fda54f9d7c93ccf8ca9bcbfd"
|
||||
integrity sha512-G0MXf6R6HndRbDy9BbEj0zrLeuhwt2nsXk2zKtF0TnYo39KgYqhYC2ayIzKPTm2KAE+xzD7rgyLdZnrcRvt9WQ==
|
||||
|
||||
"@microsoft/dynamicproto-js@^1.1.6":
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/@microsoft/dynamicproto-js/-/dynamicproto-js-1.1.6.tgz#6fe03468862861f5f88ac4c3959a652b3797f1bc"
|
||||
integrity sha512-D1Oivw1A4bIXhzBIy3/BBPn3p2On+kpO2NiYt9shICDK7L/w+cR6FFBUsBZ05l6iqzTeL+Jm8lAYn0g6G7DmDg==
|
||||
|
||||
"@types/node@16.x":
|
||||
version "16.11.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
|
||||
integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
|
||||
|
||||
"@vscode/extension-telemetry@0.5.0":
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.5.0.tgz#8214171e550393d577fc56326fa986c6800b831b"
|
||||
integrity sha512-27FsgeVJvC4zVw7Ar3Ub+7vJswDt8RoBFpbgBwf8Xq/B2gaT8G6a+gkw3s2pQmjWGIqyu7TRA8e9rS8/vxv6NQ==
|
||||
"@vscode/extension-telemetry@0.6.2":
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/@vscode/extension-telemetry/-/extension-telemetry-0.6.2.tgz#b86814ee680615730da94220c2b03ea9c3c14a8e"
|
||||
integrity sha512-yb/wxLuaaCRcBAZtDCjNYSisAXz3FWsSqAha5nhHcYxx2ZPdQdWuZqVXGKq0ZpHVndBWWtK6XqtpCN2/HB4S1w==
|
||||
dependencies:
|
||||
"@microsoft/1ds-core-js" "^3.2.3"
|
||||
"@microsoft/1ds-post-js" "^3.2.3"
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -49,44 +88,44 @@ request-light@^0.5.8:
|
||||
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.5.8.tgz#8bf73a07242b9e7b601fac2fa5dc22a094abcc27"
|
||||
integrity sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==
|
||||
|
||||
semver@^7.3.4:
|
||||
version "7.3.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
|
||||
integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
|
||||
semver@^7.3.5:
|
||||
version "7.3.7"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f"
|
||||
integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
vscode-jsonrpc@6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
|
||||
integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
|
||||
vscode-jsonrpc@8.0.2-next.1:
|
||||
version "8.0.2-next.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.2-next.1.tgz#6bdc39fd194782032e34047eeefce562941259c6"
|
||||
integrity sha512-sbbvGSWja7NVBLHPGawtgezc8DHYJaP4qfr/AaJiyDapWcSFtHyPtm18+LnYMLTmB7bhOUW/lf5PeeuLpP6bKA==
|
||||
|
||||
vscode-languageclient@^7.0.0:
|
||||
version "7.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-7.0.0.tgz#b505c22c21ffcf96e167799757fca07a6bad0fb2"
|
||||
integrity sha512-P9AXdAPlsCgslpP9pRxYPqkNYV7Xq8300/aZDpO35j1fJm/ncize8iGswzYlcvFw5DQUx4eVk+KvfXdL0rehNg==
|
||||
vscode-languageclient@^8.0.2-next.5:
|
||||
version "8.0.2-next.5"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.2-next.5.tgz#3238a388585c3119e247f761b4355273cc2fd909"
|
||||
integrity sha512-g87RJLHz0XlRyk6DOTbAk4JHcj8CKggXy4JiFL7OlhETkcYzTOR8d+Qdb4GqZr37PDs1Cl21omtTNK5LyR/RQg==
|
||||
dependencies:
|
||||
minimatch "^3.0.4"
|
||||
semver "^7.3.4"
|
||||
vscode-languageserver-protocol "3.16.0"
|
||||
semver "^7.3.5"
|
||||
vscode-languageserver-protocol "3.17.2-next.6"
|
||||
|
||||
vscode-languageserver-protocol@3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
|
||||
integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
|
||||
vscode-languageserver-protocol@3.17.2-next.6:
|
||||
version "3.17.2-next.6"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.2-next.6.tgz#8f1dc0fcb29366b85f623a3f9af726de433b5fcc"
|
||||
integrity sha512-WtsebNOOkWyNn4oFYoAMPC8Q/ZDoJ/K7Ja53OzTixiitvrl/RpXZETrtzH79R8P5kqCyx6VFBPb6KQILJfkDkA==
|
||||
dependencies:
|
||||
vscode-jsonrpc "6.0.0"
|
||||
vscode-languageserver-types "3.16.0"
|
||||
vscode-jsonrpc "8.0.2-next.1"
|
||||
vscode-languageserver-types "3.17.2-next.2"
|
||||
|
||||
vscode-languageserver-types@3.16.0:
|
||||
version "3.16.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
|
||||
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
|
||||
vscode-languageserver-types@3.17.2-next.2:
|
||||
version "3.17.2-next.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.2-next.2.tgz#af5d6978eee7682aab87c1419323f5b141ac6596"
|
||||
integrity sha512-TiAkLABgqkVWdAlC3XlOfdhdjIAdVU4YntPUm9kKGbXr+MGwpVnKz2KZMNBcvG0CFx8Hi8qliL0iq+ndPB720w==
|
||||
|
||||
vscode-nls@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.0.tgz#99f0da0bd9ea7cda44e565a74c54b1f2bc257840"
|
||||
integrity sha512-u0Lw+IYlgbEJFF6/qAqG2d1jQmJl0eyAGJHoAJqr2HT4M2BNuQYSEiSE75f52pXHSJm8AlTjnLLbBFPrdz2hpA==
|
||||
vscode-nls@^5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.0.1.tgz#ba23fc4d4420d25e7f886c8e83cbdcec47aa48b2"
|
||||
integrity sha512-hHQV6iig+M21lTdItKPkJAaWrxALQb/nqpVffakO4knJOh3DrU2SXOMzUzNgo1eADPzu3qSsJY1weCzvR52q9A==
|
||||
|
||||
yallist@^4.0.0:
|
||||
version "4.0.0"
|
||||
|
||||
Reference in New Issue
Block a user