• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*@internal*/
2namespace ts.server {
3    declare const addEventListener: any;
4    declare const postMessage: any;
5    declare const close: any;
6    declare const location: any;
7    declare const XMLHttpRequest: any;
8    declare const self: any;
9
10    const nullLogger: Logger = {
11        close: noop,
12        hasLevel: returnFalse,
13        loggingEnabled: returnFalse,
14        perftrc: noop,
15        info: noop,
16        msg: noop,
17        startGroup: noop,
18        endGroup: noop,
19        getLogFileName: returnUndefined,
20    };
21
22    function parseServerMode(): LanguageServiceMode | string | undefined {
23        const mode = findArgument("--serverMode");
24        if (!mode) return undefined;
25        switch (mode.toLowerCase()) {
26            case "partialsemantic":
27                return LanguageServiceMode.PartialSemantic;
28            case "syntactic":
29                return LanguageServiceMode.Syntactic;
30            default:
31                return mode;
32        }
33    }
34
35    export function initializeWebSystem(args: string[]): StartInput {
36        createWebSystem(args);
37        const modeOrUnknown = parseServerMode();
38        let serverMode: LanguageServiceMode | undefined;
39        let unknownServerMode: string | undefined;
40        if (typeof modeOrUnknown === "number") serverMode = modeOrUnknown;
41        else unknownServerMode = modeOrUnknown;
42        return {
43            args,
44            logger: createLogger(),
45            cancellationToken: nullCancellationToken,
46            // Webserver defaults to partial semantic mode
47            serverMode: serverMode ?? LanguageServiceMode.PartialSemantic,
48            unknownServerMode,
49            startSession: startWebSession
50        };
51    }
52
53    function createLogger() {
54        const cmdLineVerbosity = getLogLevel(findArgument("--logVerbosity"));
55        return cmdLineVerbosity !== undefined ? new MainProcessLogger(cmdLineVerbosity, { writeMessage }) : nullLogger;
56    }
57
58    function writeMessage(s: any) {
59        postMessage(s);
60    }
61
62    function createWebSystem(args: string[]) {
63        Debug.assert(ts.sys === undefined);
64        const webHost: WebHost = {
65            readFile: webPath => {
66                const request = new XMLHttpRequest();
67                request.open("GET", webPath, /* asynchronous */ false);
68                request.send();
69                return request.status === 200 ? request.responseText : undefined;
70            },
71            fileExists: webPath => {
72                const request = new XMLHttpRequest();
73                request.open("HEAD", webPath, /* asynchronous */ false);
74                request.send();
75                return request.status === 200;
76            },
77            writeMessage,
78        };
79        // Do this after sys has been set as findArguments is going to work only then
80        const sys = server.createWebSystem(webHost, args, () => findArgument("--executingFilePath") || location + "");
81        ts.sys = sys;
82        const localeStr = findArgument("--locale");
83        if (localeStr) {
84            validateLocaleAndSetLanguage(localeStr, sys);
85        }
86    }
87
88    function hrtime(previous?: [number, number]) {
89        const now = self.performance.now(performance) * 1e-3;
90        let seconds = Math.floor(now);
91        let nanoseconds = Math.floor((now % 1) * 1e9);
92        if (previous) {
93            seconds = seconds - previous[0];
94            nanoseconds = nanoseconds - previous[1];
95            if (nanoseconds < 0) {
96                seconds--;
97                nanoseconds += 1e9;
98            }
99        }
100        return [seconds, nanoseconds];
101    }
102
103    function startWebSession(options: StartSessionOptions, logger: Logger, cancellationToken: ServerCancellationToken) {
104        class WorkerSession extends server.WorkerSession {
105            constructor() {
106                super(sys as ServerHost, { writeMessage }, options, logger, cancellationToken, hrtime);
107            }
108
109            exit() {
110                this.logger.info("Exiting...");
111                this.projectService.closeLog();
112                close(0);
113            }
114
115            listen() {
116                addEventListener("message", (message: any) => {
117                    this.onMessage(message.data);
118                });
119            }
120        }
121
122        const session = new WorkerSession();
123
124        // Start listening
125        session.listen();
126    }
127}
128