@azure/cosmos-language-service
Version:
Cosmos DB SQL Language Service for the Monaco editor
92 lines (78 loc) • 4.1 kB
text/typescript
import * as Q from "q";
import {editor, languages, MarkerSeverity} from "monaco-editor";
export enum ParseReason {
GetCompletionWords = 1,
GetErrors = 2
}
export class LanguageServiceFacade {
private static readonly timeout : number = 2000;
private static workingWorkerForCompletion : Worker = null;
private static workingWorkerForGettingError : Worker = null;
public static GetLanguageServiceParseResult(str : string, parseReason : ParseReason) : Q.Promise<any> {
const timeExceeded = Q.Promise<any>((resolve : any, reject : any) => {
const wait = setTimeout(() => {
const words : any = {};
resolve(words);
}, LanguageServiceFacade.timeout);
});
const result = LanguageServiceFacade.GetParseResult(str, parseReason);
let workingWorker = (parseReason === ParseReason.GetCompletionWords ? LanguageServiceFacade.workingWorkerForCompletion : LanguageServiceFacade.workingWorkerForGettingError);
return Q.race([timeExceeded, result]).then(function(words) {
workingWorker.terminate();
return words;
});
}
private static GetParseResult = (str : string, parseReason : ParseReason) : Q.Promise<any> => {
return Q.Promise((resolve : any) => {
let workingWorker = (parseReason === ParseReason.GetCompletionWords ? LanguageServiceFacade.workingWorkerForCompletion : LanguageServiceFacade.workingWorkerForGettingError);
// terminate the expired worker.
if (workingWorker != null) {
workingWorker.terminate();
}
const currentUrlWithoutQueryParamsAndHashRoute: string = `${window.location.protocol}//${window.location.host}${window.location.pathname}`;
let url = currentUrlWithoutQueryParamsAndHashRoute.replace(/\/[^\/]*$/, '/node_modules/@azure/cosmos-language-service/dist/worker/dist/LanguageServiceWorker.js');
if(parseReason === ParseReason.GetCompletionWords) {
LanguageServiceFacade.workingWorkerForCompletion = new Worker(url);
workingWorker = LanguageServiceFacade.workingWorkerForCompletion;
} else {
LanguageServiceFacade.workingWorkerForGettingError = new Worker(url);
workingWorker = LanguageServiceFacade.workingWorkerForGettingError;
}
workingWorker.onmessage = (ev : MessageEvent) => {
var processedResults: any[] = [];
var parseResults: any[] = ev.data;
if (parseReason === ParseReason.GetCompletionWords) {
parseResults.forEach((label: string) => {
if (!!label) {
processedResults.push({
label: label,
insertText: label,
kind: languages.CompletionItemKind.Keyword
});
}
});
let finalResult : languages.CompletionList = {suggestions : processedResults};
resolve(finalResult);
} else if (parseReason === ParseReason.GetErrors) {
parseResults.forEach((err: any) => {
const mark: editor.IMarkerData = {
severity: MarkerSeverity.Error,
message: err.Message,
startLineNumber: err.line,
startColumn: err.column,
endLineNumber: err.line,
endColumn: err.column
};
processedResults.push(mark);
});
resolve(processedResults);
}
}
const source = {
code : str,
reason : parseReason
};
workingWorker.postMessage(source);
});
}
}