extensions/typescript-language-features/src/tsServer/server.ts/SyntaxRoutingTsServer/constructor
class SyntaxRoutingTsServer:	public constructor(
		servers: { syntax: ITypeScriptServer, semantic: ITypeScriptServer },
		delegate: TsServerDelegate,
		enableDynamicRouting: boolean,
	) {
		super();

		this.syntaxServer = servers.syntax;
		this.semanticServer = servers.semantic;

		this.router = new RequestRouter(
			[
				{
					server: this.syntaxServer,
					canRun: (command, execInfo) => {
						switch (execInfo.executionTarget) {
							case ExecutionTarget.Semantic: return false;
							case ExecutionTarget.Syntax: return true;
						}

						if (SyntaxRoutingTsServer.syntaxAlwaysCommands.has(command)) {
							return true;
						}
						if (SyntaxRoutingTsServer.semanticCommands.has(command)) {
							return false;
						}
						if (enableDynamicRouting && this.projectLoading && SyntaxRoutingTsServer.syntaxAllowedCommands.has(command)) {
							return true;
						}
						return false;
					}
				}, {
					server: this.semanticServer,
					canRun: undefined /* gets all other commands */
				}
			],
			delegate);

		this._register(this.syntaxServer.onEvent(e => {
			return this._onEvent.fire(e);
		}));

		this._register(this.semanticServer.onEvent(e => {
			switch (e.event) {
				case EventName.projectLoadingStart:
					this._projectLoading = true;
					break;

				case EventName.projectLoadingFinish:
				case EventName.semanticDiag:
				case EventName.syntaxDiag:
				case EventName.suggestionDiag:
				case EventName.configFileDiag:
					this._projectLoading = false;
					break;
			}
			return this._onEvent.fire(e);
		}));

		this._register(this.semanticServer.onExit(e => {
			this._onExit.fire(e);
			this.syntaxServer.kill();
		}));

		this._register(this.semanticServer.onError(e => this._onError.fire(e)));
	}