mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-01-20 17:22:51 -05:00
Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c (#8525)
* Merge from vscode a5cf1da01d5db3d2557132be8d30f89c38019f6c * remove files we don't want * fix hygiene * update distro * update distro * fix hygiene * fix strict nulls * distro * distro * fix tests * fix tests * add another edit * fix viewlet icon * fix azure dialog * fix some padding * fix more padding issues
This commit is contained in:
@@ -5,16 +5,18 @@
|
||||
|
||||
import {
|
||||
createConnection, IConnection,
|
||||
TextDocuments, TextDocument, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, Diagnostic
|
||||
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
|
||||
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind
|
||||
} from 'vscode-languageserver';
|
||||
|
||||
import { xhr, XHRResponse, configure as configureHttpRequests, getErrorStatusDescription } from 'request-light';
|
||||
import * as fs from 'fs';
|
||||
import { URI } from 'vscode-uri';
|
||||
import * as URL from 'url';
|
||||
import { posix } from 'path';
|
||||
import { setTimeout, clearTimeout } from 'timers';
|
||||
import { formatError, runSafe, runSafeAsync } from './utils/runner';
|
||||
import { JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities } from 'vscode-json-languageservice';
|
||||
import { TextDocument, JSONDocument, JSONSchema, getLanguageService, DocumentLanguageSettings, SchemaConfiguration, ClientCapabilities, SchemaRequestService, Diagnostic } from 'vscode-json-languageservice';
|
||||
import { getLanguageModelCache } from './languageModelCache';
|
||||
|
||||
interface ISchemaAssociations {
|
||||
@@ -56,40 +58,40 @@ const workspaceContext = {
|
||||
return URL.resolve(resource, relativePath);
|
||||
}
|
||||
};
|
||||
function getSchemaRequestService(handledSchemas: { [schema: string]: boolean }) {
|
||||
|
||||
const fileRequestService: SchemaRequestService = (uri: string) => {
|
||||
const fsPath = URI.parse(uri).fsPath;
|
||||
return new Promise<string>((c, e) => {
|
||||
fs.readFile(fsPath, 'UTF-8', (err, result) => {
|
||||
err ? e(err.message || err.toString()) : c(result.toString());
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const httpRequestService: SchemaRequestService = (uri: string) => {
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
};
|
||||
|
||||
function getSchemaRequestService(handledSchemas: string[] = ['https', 'http', 'file']) {
|
||||
const builtInHandlers: { [protocol: string]: SchemaRequestService } = {};
|
||||
for (let protocol of handledSchemas) {
|
||||
if (protocol === 'file') {
|
||||
builtInHandlers[protocol] = fileRequestService;
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
builtInHandlers[protocol] = httpRequestService;
|
||||
}
|
||||
}
|
||||
return (uri: string): Thenable<string> => {
|
||||
const protocol = uri.substr(0, uri.indexOf(':'));
|
||||
|
||||
if (!handledSchemas || handledSchemas[protocol]) {
|
||||
if (protocol === 'file') {
|
||||
const fsPath = URI.parse(uri).fsPath;
|
||||
return new Promise<string>((c, e) => {
|
||||
fs.readFile(fsPath, 'UTF-8', (err, result) => {
|
||||
err ? e(err.message || err.toString()) : c(result.toString());
|
||||
});
|
||||
});
|
||||
} else if (protocol === 'http' || protocol === 'https') {
|
||||
if (uri.indexOf('//schema.management.azure.com/') !== -1) {
|
||||
/* __GDPR__
|
||||
"json.schema" : {
|
||||
"schemaURL" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
connection.telemetry.logEvent({
|
||||
key: 'json.schema',
|
||||
value: {
|
||||
schemaURL: uri
|
||||
}
|
||||
});
|
||||
}
|
||||
const headers = { 'Accept-Encoding': 'gzip, deflate' };
|
||||
return xhr({ url: uri, followRedirects: 5, headers }).then(response => {
|
||||
return response.responseText;
|
||||
}, (error: XHRResponse) => {
|
||||
return Promise.reject(error.responseText || getErrorStatusDescription(error.status) || error.toString());
|
||||
});
|
||||
}
|
||||
const builtInHandler = builtInHandlers[protocol];
|
||||
if (builtInHandler) {
|
||||
return builtInHandler(uri);
|
||||
}
|
||||
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
|
||||
return responseText;
|
||||
@@ -107,7 +109,7 @@ let languageService = getLanguageService({
|
||||
});
|
||||
|
||||
// Create a text document manager.
|
||||
const documents: TextDocuments = new TextDocuments();
|
||||
const documents = new TextDocuments(TextDocument);
|
||||
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
@@ -115,9 +117,12 @@ documents.listen(connection);
|
||||
|
||||
let clientSnippetSupport = false;
|
||||
let dynamicFormatterRegistration = false;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let hierarchicalDocumentSymbolSupport = false;
|
||||
|
||||
let foldingRangeLimitDefault = Number.MAX_VALUE;
|
||||
let foldingRangeLimit = Number.MAX_VALUE;
|
||||
let resultLimit = Number.MAX_VALUE;
|
||||
|
||||
// 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 => {
|
||||
@@ -145,11 +150,10 @@ connection.onInitialize((params: InitializeParams): InitializeResult => {
|
||||
|
||||
clientSnippetSupport = getClientCapability('textDocument.completion.completionItem.snippetSupport', false);
|
||||
dynamicFormatterRegistration = getClientCapability('textDocument.rangeFormatting.dynamicRegistration', false) && (typeof params.initializationOptions.provideFormatter !== 'boolean');
|
||||
foldingRangeLimit = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
foldingRangeLimitDefault = getClientCapability('textDocument.foldingRange.rangeLimit', Number.MAX_VALUE);
|
||||
hierarchicalDocumentSymbolSupport = getClientCapability('textDocument.documentSymbol.hierarchicalDocumentSymbolSupport', false);
|
||||
const capabilities: ServerCapabilities = {
|
||||
// Tell the client that the server works in FULL text document sync mode
|
||||
textDocumentSync: documents.syncKind,
|
||||
textDocumentSync: TextDocumentSyncKind.Incremental,
|
||||
completionProvider: clientSnippetSupport ? { resolveProvider: true, triggerCharacters: ['"', ':'] } : undefined,
|
||||
hoverProvider: true,
|
||||
documentSymbolProvider: true,
|
||||
@@ -169,6 +173,7 @@ interface Settings {
|
||||
json: {
|
||||
schemas: JSONSchemaSettings[];
|
||||
format: { enable: boolean; };
|
||||
resultLimit?: number;
|
||||
};
|
||||
http: {
|
||||
proxy: string;
|
||||
@@ -182,6 +187,39 @@ interface JSONSchemaSettings {
|
||||
schema?: JSONSchema;
|
||||
}
|
||||
|
||||
namespace LimitExceededWarnings {
|
||||
const pendingWarnings: { [uri: string]: { features: { [name: string]: string }; timeout?: NodeJS.Timeout; } } = {};
|
||||
|
||||
export function cancel(uri: string) {
|
||||
const warning = pendingWarnings[uri];
|
||||
if (warning && warning.timeout) {
|
||||
clearTimeout(warning.timeout);
|
||||
delete pendingWarnings[uri];
|
||||
}
|
||||
}
|
||||
|
||||
export function 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.refresh();
|
||||
} else {
|
||||
warning = { features: { [name]: name } };
|
||||
warning.timeout = setTimeout(() => {
|
||||
connection.window.showInformationMessage(`${posix.basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
|
||||
warning.timeout = undefined;
|
||||
}, 2000);
|
||||
pendingWarnings[uri] = warning;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
|
||||
let schemaAssociations: ISchemaAssociations | undefined = undefined;
|
||||
let formatterRegistration: Thenable<Disposable> | null = null;
|
||||
@@ -194,6 +232,9 @@ connection.onDidChangeConfiguration((change) => {
|
||||
jsonConfigurationSettings = settings.json && settings.json.schemas;
|
||||
updateConfiguration();
|
||||
|
||||
foldingRangeLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || foldingRangeLimitDefault, 0));
|
||||
resultLimit = Math.trunc(Math.max(settings.json && settings.json.resultLimit || Number.MAX_VALUE, 0));
|
||||
|
||||
// dynamically enable & disable the formatter
|
||||
if (dynamicFormatterRegistration) {
|
||||
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
|
||||
@@ -270,11 +311,13 @@ function updateConfiguration() {
|
||||
// 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: [] });
|
||||
});
|
||||
@@ -383,10 +426,11 @@ connection.onDocumentSymbol((documentSymbolParams, token) => {
|
||||
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);
|
||||
return languageService.findDocumentSymbols2(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
} else {
|
||||
return languageService.findDocumentSymbols(document, jsonDocument);
|
||||
return languageService.findDocumentSymbols(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
}
|
||||
}
|
||||
return [];
|
||||
@@ -407,8 +451,9 @@ connection.onDocumentColor((params, token) => {
|
||||
return runSafeAsync(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);
|
||||
return languageService.findDocumentColors(document, jsonDocument, { resultLimit, onResultLimitExceeded });
|
||||
}
|
||||
return [];
|
||||
}, [], `Error while computing document colors for ${params.textDocument.uri}`, token);
|
||||
@@ -429,7 +474,8 @@ connection.onFoldingRanges((params, token) => {
|
||||
return runSafe(() => {
|
||||
const document = documents.get(params.textDocument.uri);
|
||||
if (document) {
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit });
|
||||
const onRangeLimitExceeded = LimitExceededWarnings.onResultLimitExceeded(document.uri, foldingRangeLimit, 'folding ranges');
|
||||
return languageService.getFoldingRanges(document, { rangeLimit: foldingRangeLimit, onRangeLimitExceeded });
|
||||
}
|
||||
return null;
|
||||
}, null, `Error while computing folding ranges for ${params.textDocument.uri}`, token);
|
||||
|
||||
Reference in New Issue
Block a user