@@ -16,6 +16,7 @@ import { Reader } from '../utils/wireProtocol';
1616import { CallbackMap } from './callbackMap' ;
1717import { RequestItem , RequestQueue , RequestQueueingType } from './requestQueue' ;
1818import { TypeScriptServerError } from './serverError' ;
19+ import { EventName } from '../protocol.const' ;
1920
2021export interface OngoingRequestCanceller {
2122 tryCancelOngoingRequest ( seq : number ) : boolean ;
@@ -309,7 +310,7 @@ class RequestRouter {
309310 ] ) ;
310311
311312 constructor (
312- private readonly servers : ReadonlyArray < { readonly server : ITypeScriptServer , readonly preferredCommands ?: ReadonlySet < keyof TypeScriptRequests > } > ,
313+ private readonly servers : ReadonlyArray < { readonly server : ITypeScriptServer , canRun ? ( command : keyof TypeScriptRequests ) : void } > ,
313314 private readonly delegate : TsServerDelegate ,
314315 ) { }
315316
@@ -368,8 +369,8 @@ class RequestRouter {
368369 return firstRequest ;
369370 }
370371
371- for ( const { preferredCommands , server } of this . servers ) {
372- if ( ! preferredCommands || preferredCommands . has ( command ) ) {
372+ for ( const { canRun , server } of this . servers ) {
373+ if ( ! canRun || canRun ( command ) ) {
373374 return server . executeImpl ( command , args , executeInfo ) ;
374375 }
375376 }
@@ -379,17 +380,17 @@ class RequestRouter {
379380}
380381
381382
382- export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServer {
383+ const syntaxCommands : ReadonlySet < keyof TypeScriptRequests > = new Set < keyof TypeScriptRequests > ( [
384+ 'navtree' ,
385+ 'getOutliningSpans' ,
386+ 'jsxClosingTag' ,
387+ 'selectionRange' ,
388+ 'format' ,
389+ 'formatonkey' ,
390+ 'docCommentTemplate' ,
391+ ] ) ;
383392
384- private static readonly syntaxCommands = new Set < keyof TypeScriptRequests > ( [
385- 'navtree' ,
386- 'getOutliningSpans' ,
387- 'jsxClosingTag' ,
388- 'selectionRange' ,
389- 'format' ,
390- 'formatonkey' ,
391- 'docCommentTemplate' ,
392- ] ) ;
393+ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServer {
393394
394395 private readonly syntaxServer : ITypeScriptServer ;
395396 private readonly semanticServer : ITypeScriptServer ;
@@ -406,8 +407,8 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
406407
407408 this . router = new RequestRouter (
408409 [
409- { server : this . syntaxServer , preferredCommands : SyntaxRoutingTsServer . syntaxCommands } ,
410- { server : this . semanticServer , preferredCommands : undefined /* gets all other commands */ }
410+ { server : this . syntaxServer , canRun : ( command ) => syntaxCommands . has ( command ) } ,
411+ { server : this . semanticServer , canRun : undefined /* gets all other commands */ }
411412 ] ,
412413 delegate ) ;
413414
@@ -449,11 +450,11 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
449450
450451export class GetErrRoutingTsServer extends Disposable implements ITypeScriptServer {
451452
452- private static readonly diagnosticEvents = new Set ( [
453- ' configFileDiag' ,
454- ' syntaxDiag' ,
455- ' semanticDiag' ,
456- ' suggestionDiag'
453+ private static readonly diagnosticEvents = new Set < string > ( [
454+ EventName . configFileDiag ,
455+ EventName . syntaxDiag ,
456+ EventName . semanticDiag ,
457+ EventName . suggestionDiag
457458 ] ) ;
458459
459460 private readonly getErrServer : ITypeScriptServer ;
@@ -471,8 +472,8 @@ export class GetErrRoutingTsServer extends Disposable implements ITypeScriptServ
471472
472473 this . router = new RequestRouter (
473474 [
474- { server : this . getErrServer , preferredCommands : new Set < keyof TypeScriptRequests > ( [ 'geterr' , 'geterrForProject' ] ) } ,
475- { server : this . mainServer , preferredCommands : undefined /* gets all other commands */ }
475+ { server : this . getErrServer , canRun : ( command ) => [ 'geterr' , 'geterrForProject' ] . includes ( command ) } ,
476+ { server : this . mainServer , canRun : undefined /* gets all other commands */ }
476477 ] ,
477478 delegate ) ;
478479
@@ -524,6 +525,105 @@ export class GetErrRoutingTsServer extends Disposable implements ITypeScriptServ
524525}
525526
526527
528+ export class ProjectLoadingRoutingSyntaxTsServer extends Disposable implements ITypeScriptServer {
529+
530+ private static readonly semanticCommands = new Set < keyof TypeScriptRequests > ( [
531+ 'geterr' ,
532+ 'geterrForProject'
533+ ] ) ;
534+
535+ private readonly syntaxServer : ITypeScriptServer ;
536+ private readonly semanticServer : ITypeScriptServer ;
537+ private readonly router : RequestRouter ;
538+
539+ private _projectLoading = true ;
540+
541+ public constructor (
542+ servers : { syntax : ITypeScriptServer , semantic : ITypeScriptServer } ,
543+ delegate : TsServerDelegate ,
544+ ) {
545+ super ( ) ;
546+
547+ this . syntaxServer = servers . syntax ;
548+ this . semanticServer = servers . semantic ;
549+
550+ this . router = new RequestRouter (
551+ [
552+ {
553+ server : this . syntaxServer ,
554+ canRun : ( command ) => {
555+ if ( syntaxCommands . has ( command ) ) {
556+ return true ;
557+ }
558+ if ( ProjectLoadingRoutingSyntaxTsServer . semanticCommands . has ( command ) ) {
559+ return false ;
560+ }
561+ if ( this . _projectLoading ) {
562+ return true ;
563+ }
564+ return false ;
565+ }
566+ } , {
567+ server : this . semanticServer ,
568+ canRun : undefined /* gets all other commands */
569+ }
570+ ] ,
571+ delegate ) ;
572+
573+ this . _register ( this . syntaxServer . onEvent ( e => {
574+ return this . _onEvent . fire ( e ) ;
575+ } ) ) ;
576+
577+ this . _register ( this . semanticServer . onEvent ( e => {
578+ switch ( e . event ) {
579+ case EventName . projectLoadingStart :
580+ this . _projectLoading = true ;
581+ break ;
582+
583+ case EventName . projectLoadingFinish :
584+ case EventName . semanticDiag :
585+ case EventName . syntaxDiag :
586+ case EventName . suggestionDiag :
587+ case EventName . configFileDiag :
588+ this . _projectLoading = false ;
589+ break ;
590+ }
591+ return this . _onEvent . fire ( e ) ;
592+ } ) ) ;
593+
594+ this . _register ( this . semanticServer . onExit ( e => {
595+ this . _onExit . fire ( e ) ;
596+ this . syntaxServer . kill ( ) ;
597+ } ) ) ;
598+
599+ this . _register ( this . semanticServer . onError ( e => this . _onError . fire ( e ) ) ) ;
600+ }
601+
602+ private readonly _onEvent = this . _register ( new vscode . EventEmitter < Proto . Event > ( ) ) ;
603+ public readonly onEvent = this . _onEvent . event ;
604+
605+ private readonly _onExit = this . _register ( new vscode . EventEmitter < any > ( ) ) ;
606+ public readonly onExit = this . _onExit . event ;
607+
608+ private readonly _onError = this . _register ( new vscode . EventEmitter < any > ( ) ) ;
609+ public readonly onError = this . _onError . event ;
610+
611+ public get onReaderError ( ) { return this . semanticServer . onReaderError ; }
612+
613+ public get tsServerLogFile ( ) { return this . semanticServer . tsServerLogFile ; }
614+
615+ public kill ( ) : void {
616+ this . syntaxServer . kill ( ) ;
617+ this . semanticServer . kill ( ) ;
618+ }
619+
620+ public executeImpl ( command : keyof TypeScriptRequests , args : any , executeInfo : { isAsync : boolean , token ?: vscode . CancellationToken , expectsResult : false , lowPriority ?: boolean } ) : undefined ;
621+ public executeImpl ( command : keyof TypeScriptRequests , args : any , executeInfo : { isAsync : boolean , token ?: vscode . CancellationToken , expectsResult : boolean , lowPriority ?: boolean } ) : Promise < ServerResponse . Response < Proto . Response > > ;
622+ public executeImpl ( command : keyof TypeScriptRequests , args : any , executeInfo : { isAsync : boolean , token ?: vscode . CancellationToken , expectsResult : boolean , lowPriority ?: boolean } ) : Promise < ServerResponse . Response < Proto . Response > > | undefined {
623+ return this . router . execute ( command , args , executeInfo ) ;
624+ }
625+ }
626+
527627namespace RequestState {
528628 export const enum Type { Unresolved , Resolved , Errored }
529629
0 commit comments