https://github.com/Microsoft/TypeScript
Tip revision: 5a7d3ba776a591e4338826a2ab15ead560a7dfee authored by Daniel Rosenwasser on 15 November 2022, 07:18:09 UTC
Switch to classes?
Switch to classes?
Tip revision: 5a7d3ba
webServer.ts
/// <reference lib="webworker" />
import * as ts from "./_namespaces/ts";
import * as server from "./_namespaces/ts.server";
import {
findArgument, getLogLevel, Logger, MainProcessLogger, Msg, nullCancellationToken, ServerCancellationToken,
ServerHost, StartInput, StartSessionOptions, WebHost,
} from "./_namespaces/ts.server";
import {
Debug, LanguageServiceMode, LogLevel, noop, returnFalse, returnUndefined, setSys, sys, validateLocaleAndSetLanguage,
} from "./_namespaces/ts";
const nullLogger: Logger = {
close: noop,
hasLevel: returnFalse,
loggingEnabled: returnFalse,
perftrc: noop,
info: noop,
msg: noop,
startGroup: noop,
endGroup: noop,
getLogFileName: returnUndefined,
};
function parseServerMode(): LanguageServiceMode | string | undefined {
const mode = findArgument("--serverMode");
if (!mode) return undefined;
switch (mode.toLowerCase()) {
case "partialsemantic":
return LanguageServiceMode.PartialSemantic;
case "syntactic":
return LanguageServiceMode.Syntactic;
default:
return mode;
}
}
/** @internal */
export function initializeWebSystem(args: string[]): StartInput {
createWebSystem(args);
const modeOrUnknown = parseServerMode();
let serverMode: LanguageServiceMode | undefined;
let unknownServerMode: string | undefined;
if (typeof modeOrUnknown === "number") serverMode = modeOrUnknown;
else unknownServerMode = modeOrUnknown;
const logger = createLogger();
// enable deprecation logging
Debug.loggingHost = {
log(level, s) {
switch (level) {
case LogLevel.Error:
case LogLevel.Warning:
return logger.msg(s, Msg.Err);
case LogLevel.Info:
case LogLevel.Verbose:
return logger.msg(s, Msg.Info);
}
}
};
return {
args,
logger,
cancellationToken: nullCancellationToken,
// Webserver defaults to partial semantic mode
serverMode: serverMode ?? LanguageServiceMode.PartialSemantic,
unknownServerMode,
startSession: startWebSession
};
}
function createLogger() {
const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity"));
return cmdLineVerbosity !== undefined ? new MainProcessLogger(cmdLineVerbosity, { writeMessage }) : nullLogger;
}
function writeMessage(s: any) {
postMessage(s);
}
function createWebSystem(args: string[]) {
Debug.assert(ts.sys === undefined);
const webHost: WebHost = {
readFile: webPath => {
const request = new XMLHttpRequest();
request.open("GET", webPath, /* asynchronous */ false);
request.send();
return request.status === 200 ? request.responseText : undefined;
},
fileExists: webPath => {
const request = new XMLHttpRequest();
request.open("HEAD", webPath, /* asynchronous */ false);
request.send();
return request.status === 200;
},
writeMessage,
};
// Do this after sys has been set as findArguments is going to work only then
const sys = server.createWebSystem(webHost, args, () => findArgument("--executingFilePath") || location + "");
setSys(sys);
const localeStr = findArgument("--locale");
if (localeStr) {
validateLocaleAndSetLanguage(localeStr, sys);
}
}
function hrtime(previous?: [number, number]) {
const now = self.performance.now() * 1e-3;
let seconds = Math.floor(now);
let nanoseconds = Math.floor((now % 1) * 1e9);
if (previous) {
seconds = seconds - previous[0];
nanoseconds = nanoseconds - previous[1];
if (nanoseconds < 0) {
seconds--;
nanoseconds += 1e9;
}
}
return [seconds, nanoseconds];
}
function startWebSession(options: StartSessionOptions, logger: Logger, cancellationToken: ServerCancellationToken) {
class WorkerSession extends server.WorkerSession {
constructor() {
super(sys as ServerHost, { writeMessage }, options, logger, cancellationToken, hrtime);
}
exit() {
this.logger.info("Exiting...");
this.projectService.closeLog();
close();
}
listen() {
addEventListener("message", (message: any) => {
this.onMessage(message.data);
});
}
}
const session = new WorkerSession();
// Start listening
session.listen();
}