提交 8d703ff0 编写于 作者: M Martin Aeschlimann

[css extension] cache stylesheets ASTs

上级 1fe6e953
......@@ -10,7 +10,7 @@ import {
} from 'vscode-languageserver';
import {getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService} from './cssLanguageService';
import {Stylesheet} from './parser/cssNodes';
import {getStylesheetCache} from './stylesheetCache';
import * as nls from 'vscode-nls';
nls.config(process.env['VSCODE_NLS_CONFIG']);
......@@ -29,6 +29,9 @@ export interface Settings {
// stdin / stdout for message passing
let connection: IConnection = createConnection(new IPCMessageReader(process), new IPCMessageWriter(process));
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
// Create a simple text document manager. The text document manager
// supports full document sync only
let documents: TextDocuments = new TextDocuments();
......@@ -36,6 +39,13 @@ let documents: TextDocuments = new TextDocuments();
// for open, change and close text document events
documents.listen(connection);
let stylesheets = getStylesheetCache(10, 60, document => getLanguageService(document).parseStylesheet(document));
documents.onDidClose(e => {
stylesheets.onDocumentRemoved(e.document);
});
connection.onShutdown(() => {
stylesheets.dispose();
});
// After the server has started the client sends an initilize request. The server receives
// in the passed params the rootPath of the workspace plus the client capabilites.
......@@ -87,62 +97,58 @@ function updateConfiguration(settings: Settings) {
}
function validateTextDocument(textDocument: TextDocument): void {
let stylesheet = getStylesheet(textDocument);
let stylesheet = stylesheets.getStylesheet(textDocument);
getLanguageService(textDocument).doValidation(textDocument, stylesheet).then(diagnostics => {
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});
}
function getStylesheet(document: TextDocument): Stylesheet {
return getLanguageService(document).parseStylesheet(document);
}
connection.onCompletion(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).doComplete(document, textDocumentPosition.position, stylesheet);
});
connection.onHover(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let styleSheet = getStylesheet(document);
let styleSheet = stylesheets.getStylesheet(document);
return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet);
});
connection.onDocumentSymbol(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).findDocumentSymbols(document, stylesheet);
});
connection.onDefinition(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).findDefinition(document, documentSymbolParams.position, stylesheet);
});
connection.onDocumentHighlight(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).findDocumentHighlights(document, documentSymbolParams.position, stylesheet);
});
connection.onReferences(referenceParams => {
let document = documents.get(referenceParams.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).findReferences(document, referenceParams.position, stylesheet);
});
connection.onCodeAction(codeActionParams => {
let document = documents.get(codeActionParams.textDocument.uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).doCodeActions(document, codeActionParams.range, codeActionParams.context, stylesheet);
});
connection.onRequest(ColorSymbolRequest.type, uri => {
let document = documents.get(uri);
let stylesheet = getStylesheet(document);
let stylesheet = stylesheets.getStylesheet(document);
return getLanguageService(document).findColorSymbols(document, stylesheet);
});
......
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import {TextDocument} from 'vscode-languageserver';
import {Stylesheet} from './parser/cssNodes';
export interface StylesheetCache {
getStylesheet(document: TextDocument): Stylesheet;
onDocumentRemoved(document: TextDocument): void;
dispose(): void;
}
export function getStylesheetCache(maxEntries: number, cleanupIntervalTimeInSec: number, parseStylesheet: (document: TextDocument) => Stylesheet) : StylesheetCache {
let styleSheets: { [uri:string]: {version:number, languageId: string, cTime: number, stylesheet: Stylesheet}} = {};
let nStyleSheets = 0;
let cleanupInterval = void 0;
if (cleanupIntervalTimeInSec > 0) {
cleanupInterval = setInterval(() => {
let cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
let uris = Object.keys(styleSheets);
for (let uri of uris) {
let stylesheetInfo = styleSheets[uri];
if (stylesheetInfo.cTime < cutoffTime) {
delete styleSheets[uri];
nStyleSheets--;
}
}
}, cleanupIntervalTimeInSec * 1000);
}
return {
getStylesheet(document: TextDocument) {
let version = document.version;
let languageId = document.languageId;
let stylesheetInfo = styleSheets[document.uri];
if (stylesheetInfo && stylesheetInfo.version === version && stylesheetInfo.languageId === languageId) {
stylesheetInfo.cTime = Date.now();
return stylesheetInfo.stylesheet;
}
let stylesheet = parseStylesheet(document);
styleSheets[document.uri] = { stylesheet, version, languageId, cTime: Date.now()};
if (!stylesheetInfo) {
nStyleSheets++;
}
if (nStyleSheets === maxEntries) {
let oldestTime = Number.MAX_VALUE;
let oldestUri = null;
for (let uri in styleSheets) {
let stylesheetInfo = styleSheets[uri];
if (stylesheetInfo.cTime < oldestTime) {
oldestUri = uri;
oldestTime = stylesheetInfo.cTime;
}
}
if (oldestUri) {
delete styleSheets[oldestUri];
nStyleSheets--;
}
}
return stylesheet;
},
onDocumentRemoved(document: TextDocument) {
let uri = document.uri;
if (styleSheets[uri]) {
delete styleSheets[uri];
nStyleSheets--;
}
},
dispose() {
if (typeof cleanupInterval !== 'undefined') {
clearInterval(cleanupInterval);
cleanupInterval = void 0;
styleSheets = {};
nStyleSheets = 0;
}
}
};
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册