mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-23 01:25:38 -05:00
Merge from vscode merge-base (#22780)
* Revert "Revert "Merge from vscode merge-base (#22769)" (#22779)"
This reverts commit 47a1745180.
* Fix notebook download task
* Remove done call from extensions-ci
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user