Skip to content

Commit 43a29ef

Browse files
committed
langium/lsp: externalized LSP service minimum document state configs into the DI modules
* relaxed some doc state requirements to increase the LS' responsiveness from 'IndexedReferences' to 'Linked' as it is sufficient that all required documents are in state 'ComputedScopes', and current document should (ideally) be linked: completion, declaration, definition, implementation, typeDefinition, hover, semanticToken
1 parent 910e8a0 commit 43a29ef

File tree

3 files changed

+97
-34
lines changed

3 files changed

+97
-34
lines changed

packages/langium/src/lsp/default-lsp-module.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type { Connection } from 'vscode-languageserver';
88
import { createDefaultCoreModule, createDefaultSharedCoreModule, type DefaultCoreModuleContext, type DefaultSharedCoreModuleContext } from '../default-module.js';
99
import { Module } from '../dependency-injection.js';
1010
import type { LangiumDefaultCoreServices, LangiumDefaultSharedCoreServices } from '../services.js';
11-
import { TextDocument } from '../workspace/documents.js';
11+
import { DocumentState, TextDocument } from '../workspace/documents.js';
1212
import { DefaultCompletionProvider } from './completion/completion-provider.js';
1313
import { DefaultDefinitionProvider } from './definition-provider.js';
1414
import { DefaultDocumentHighlightProvider } from './document-highlight-provider.js';
@@ -94,6 +94,29 @@ export function createDefaultSharedLSPModule(context: DefaultSharedModuleContext
9494
WorkspaceSymbolProvider: (services) => new DefaultWorkspaceSymbolProvider(services),
9595
NodeKindProvider: () => new DefaultNodeKindProvider(),
9696
FuzzyMatcher: () => new DefaultFuzzyMatcher(),
97+
serviceRequirements: {
98+
CallHierarchyProvider: DocumentState.IndexedReferences,
99+
CodeActionProvider: DocumentState.Validated,
100+
CodeLensProvider: DocumentState.IndexedReferences,
101+
CompletionProvider: DocumentState.Linked,
102+
DeclarationProvider: DocumentState.Linked,
103+
DefinitionProvider: DocumentState.Linked,
104+
DocumentHighlightProvider: DocumentState.IndexedReferences,
105+
DocumentLinkProvider: DocumentState.Parsed,
106+
DocumentSymbolProvider: DocumentState.Parsed,
107+
FoldingRangeProvider: DocumentState.Parsed,
108+
Formatter: DocumentState.Parsed,
109+
HoverProvider: DocumentState.Linked,
110+
ImplementationProvider: DocumentState.Linked,
111+
InlayHintProvider: DocumentState.IndexedReferences,
112+
ReferencesProvider: DocumentState.IndexedReferences,
113+
RenameProvider: DocumentState.IndexedReferences,
114+
SemanticTokenProvider: DocumentState.Linked,
115+
SignatureHelp: DocumentState. IndexedReferences,
116+
TypeHierarchyProvider: DocumentState.IndexedReferences,
117+
TypeProvider: DocumentState.Linked,
118+
WorkspaceSymbolProvider: DocumentState.IndexedContent
119+
}
97120
},
98121
workspace: {
99122
TextDocuments: () => new NormalizedTextDocuments(TextDocument),

packages/langium/src/lsp/language-server.ts

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -349,130 +349,136 @@ export function addCompletionHandler(connection: Connection, services: LangiumSh
349349
return services.lsp?.CompletionProvider?.getCompletion(document, params, cancelToken);
350350
},
351351
services,
352-
DocumentState.IndexedReferences
352+
services.lsp.serviceRequirements.CompletionProvider
353353
));
354354
}
355355

356356
export function addFindReferencesHandler(connection: Connection, services: LangiumSharedServices): void {
357357
connection.onReferences(createRequestHandler(
358358
(services, document, params, cancelToken) => services.lsp?.ReferencesProvider?.findReferences(document, params, cancelToken),
359359
services,
360-
DocumentState.IndexedReferences
360+
services.lsp.serviceRequirements.ReferencesProvider
361361
));
362362
}
363363

364364
export function addCodeActionHandler(connection: Connection, services: LangiumSharedServices): void {
365365
connection.onCodeAction(createRequestHandler(
366366
(services, document, params, cancelToken) => services.lsp?.CodeActionProvider?.getCodeActions(document, params, cancelToken),
367367
services,
368-
DocumentState.Validated
368+
services.lsp.serviceRequirements.CodeActionProvider
369369
));
370370
}
371371

372372
export function addDocumentSymbolHandler(connection: Connection, services: LangiumSharedServices): void {
373373
connection.onDocumentSymbol(createRequestHandler(
374374
(services, document, params, cancelToken) => services.lsp?.DocumentSymbolProvider?.getSymbols(document, params, cancelToken),
375375
services,
376-
DocumentState.Parsed
376+
services.lsp.serviceRequirements.DocumentSymbolProvider
377377
));
378378
}
379379

380380
export function addGotoDefinitionHandler(connection: Connection, services: LangiumSharedServices): void {
381381
connection.onDefinition(createRequestHandler(
382382
(services, document, params, cancelToken) => services.lsp?.DefinitionProvider?.getDefinition(document, params, cancelToken),
383383
services,
384-
DocumentState.IndexedReferences
384+
services.lsp.serviceRequirements.DefinitionProvider
385385
));
386386
}
387387

388388
export function addGoToTypeDefinitionHandler(connection: Connection, services: LangiumSharedServices): void {
389389
connection.onTypeDefinition(createRequestHandler(
390390
(services, document, params, cancelToken) => services.lsp?.TypeProvider?.getTypeDefinition(document, params, cancelToken),
391391
services,
392-
DocumentState.IndexedReferences
392+
services.lsp.serviceRequirements.TypeProvider
393393
));
394394
}
395395

396396
export function addGoToImplementationHandler(connection: Connection, services: LangiumSharedServices) {
397397
connection.onImplementation(createRequestHandler(
398398
(services, document, params, cancelToken) => services.lsp?.ImplementationProvider?.getImplementation(document, params, cancelToken),
399399
services,
400-
DocumentState.IndexedReferences
400+
services.lsp.serviceRequirements.ImplementationProvider
401401
));
402402
}
403403

404404
export function addGoToDeclarationHandler(connection: Connection, services: LangiumSharedServices) {
405405
connection.onDeclaration(createRequestHandler(
406406
(services, document, params, cancelToken) => services.lsp?.DeclarationProvider?.getDeclaration(document, params, cancelToken),
407407
services,
408-
DocumentState.IndexedReferences
408+
services.lsp.serviceRequirements.DeclarationProvider
409409
));
410410
}
411411

412412
export function addDocumentHighlightsHandler(connection: Connection, services: LangiumSharedServices): void {
413413
connection.onDocumentHighlight(createRequestHandler(
414414
(services, document, params, cancelToken) => services.lsp?.DocumentHighlightProvider?.getDocumentHighlight(document, params, cancelToken),
415415
services,
416-
DocumentState.IndexedReferences
416+
services.lsp.serviceRequirements.DocumentHighlightProvider
417417
));
418418
}
419419

420420
export function addHoverHandler(connection: Connection, services: LangiumSharedServices): void {
421421
connection.onHover(createRequestHandler(
422422
(services, document, params, cancelToken) => services.lsp?.HoverProvider?.getHoverContent(document, params, cancelToken),
423423
services,
424-
DocumentState.IndexedReferences
424+
services.lsp.serviceRequirements.HoverProvider
425425
));
426426
}
427427

428428
export function addFoldingRangeHandler(connection: Connection, services: LangiumSharedServices): void {
429429
connection.onFoldingRanges(createRequestHandler(
430430
(services, document, params, cancelToken) => services.lsp?.FoldingRangeProvider?.getFoldingRanges(document, params, cancelToken),
431431
services,
432-
DocumentState.Parsed
432+
services.lsp.serviceRequirements.FoldingRangeProvider
433433
));
434434
}
435435

436436
export function addFormattingHandler(connection: Connection, services: LangiumSharedServices): void {
437+
const targetState = services.lsp.serviceRequirements.Formatter;
438+
437439
connection.onDocumentFormatting(createRequestHandler(
438440
(services, document, params, cancelToken) => services.lsp?.Formatter?.formatDocument(document, params, cancelToken),
439441
services,
440-
DocumentState.Parsed
442+
targetState
441443
));
442444
connection.onDocumentRangeFormatting(createRequestHandler(
443445
(services, document, params, cancelToken) => services.lsp?.Formatter?.formatDocumentRange(document, params, cancelToken),
444446
services,
445-
DocumentState.Parsed
447+
targetState
446448
));
447449
connection.onDocumentOnTypeFormatting(createRequestHandler(
448450
(services, document, params, cancelToken) => services.lsp?.Formatter?.formatDocumentOnType(document, params, cancelToken),
449451
services,
450-
DocumentState.Parsed
452+
targetState
451453
));
452454
}
453455

454456
export function addRenameHandler(connection: Connection, services: LangiumSharedServices): void {
457+
const targetState = services.lsp.serviceRequirements.RenameProvider;
458+
455459
connection.onRenameRequest(createRequestHandler(
456460
(services, document, params, cancelToken) => services.lsp?.RenameProvider?.rename(document, params, cancelToken),
457461
services,
458-
DocumentState.IndexedReferences
462+
targetState
459463
));
460464
connection.onPrepareRename(createRequestHandler(
461465
(services, document, params, cancelToken) => services.lsp?.RenameProvider?.prepareRename(document, params, cancelToken),
462466
services,
463-
DocumentState.IndexedReferences
467+
targetState
464468
));
465469
}
466470

467471
export function addInlayHintHandler(connection: Connection, services: LangiumSharedServices): void {
468472
connection.languages.inlayHint.on(createServerRequestHandler(
469473
(services, document, params, cancelToken) => services.lsp?.InlayHintProvider?.getInlayHints(document, params, cancelToken),
470474
services,
471-
DocumentState.IndexedReferences
475+
services.lsp.serviceRequirements.InlayHintProvider
472476
));
473477
}
474478

475479
export function addSemanticTokenHandler(connection: Connection, services: LangiumSharedServices): void {
480+
const targetState = services.lsp.serviceRequirements.SemanticTokenProvider;
481+
476482
// If no semantic token provider is registered that's fine. Just return an empty result
477483
const emptyResult: SemanticTokens = { data: [] };
478484
connection.languages.semanticTokens.on(createServerRequestHandler<SemanticTokensParams, SemanticTokens, SemanticTokensPartialResult, void>(
@@ -483,7 +489,7 @@ export function addSemanticTokenHandler(connection: Connection, services: Langiu
483489
return emptyResult;
484490
},
485491
services,
486-
DocumentState.IndexedReferences
492+
targetState
487493
));
488494
connection.languages.semanticTokens.onDelta(createServerRequestHandler<SemanticTokensDeltaParams, SemanticTokens | SemanticTokensDelta, SemanticTokensDeltaPartialResult, void>(
489495
(services, document, params, cancelToken) => {
@@ -493,7 +499,7 @@ export function addSemanticTokenHandler(connection: Connection, services: Langiu
493499
return emptyResult;
494500
},
495501
services,
496-
DocumentState.IndexedReferences
502+
targetState
497503
));
498504
connection.languages.semanticTokens.onRange(createServerRequestHandler<SemanticTokensRangeParams, SemanticTokens, SemanticTokensPartialResult, void>(
499505
(services, document, params, cancelToken) => {
@@ -503,7 +509,7 @@ export function addSemanticTokenHandler(connection: Connection, services: Langiu
503509
return emptyResult;
504510
},
505511
services,
506-
DocumentState.IndexedReferences
512+
targetState
507513
));
508514
}
509515
export function addConfigurationChangeHandler(connection: Connection, services: LangiumSharedServices): void {
@@ -529,33 +535,35 @@ export function addDocumentLinkHandler(connection: Connection, services: Langium
529535
connection.onDocumentLinks(createServerRequestHandler(
530536
(services, document, params, cancelToken) => services.lsp?.DocumentLinkProvider?.getDocumentLinks(document, params, cancelToken),
531537
services,
532-
DocumentState.Parsed
538+
services.lsp.serviceRequirements.DocumentLinkProvider
533539
));
534540
}
535541

536542
export function addSignatureHelpHandler(connection: Connection, services: LangiumSharedServices): void {
537543
connection.onSignatureHelp(createServerRequestHandler(
538544
(services, document, params, cancelToken) => services.lsp?.SignatureHelp?.provideSignatureHelp(document, params, cancelToken),
539545
services,
540-
DocumentState.IndexedReferences
546+
services.lsp.serviceRequirements.SignatureHelp
541547
));
542548
}
543549

544550
export function addCodeLensHandler(connection: Connection, services: LangiumSharedServices): void {
545551
connection.onCodeLens(createServerRequestHandler(
546552
(services, document, params, cancelToken) => services.lsp?.CodeLensProvider?.provideCodeLens(document, params, cancelToken),
547553
services,
548-
DocumentState.IndexedReferences
554+
services.lsp.serviceRequirements.CodeLensProvider
549555
));
550556
}
551557

552558
export function addWorkspaceSymbolHandler(connection: Connection, services: LangiumSharedServices): void {
553559
const workspaceSymbolProvider = services.lsp.WorkspaceSymbolProvider;
554560
if (workspaceSymbolProvider) {
561+
const targetState = services.lsp.serviceRequirements.WorkspaceSymbolProvider;
562+
555563
const documentBuilder = services.workspace.DocumentBuilder;
556564
connection.onWorkspaceSymbol(async (params, token) => {
557565
try {
558-
await documentBuilder.waitUntil(DocumentState.IndexedContent, token);
566+
await documentBuilder.waitUntil(targetState, token);
559567
return await workspaceSymbolProvider.getSymbols(params, token);
560568
} catch (err) {
561569
return responseError(err);
@@ -565,7 +573,7 @@ export function addWorkspaceSymbolHandler(connection: Connection, services: Lang
565573
if (resolveWorkspaceSymbol) {
566574
connection.onWorkspaceSymbolResolve(async (workspaceSymbol, token) => {
567575
try {
568-
await documentBuilder.waitUntil(DocumentState.IndexedContent, token);
576+
await documentBuilder.waitUntil(targetState, token);
569577
return await resolveWorkspaceSymbol(workspaceSymbol, token);
570578
} catch (err) {
571579
return responseError(err);
@@ -576,6 +584,8 @@ export function addWorkspaceSymbolHandler(connection: Connection, services: Lang
576584
}
577585

578586
export function addCallHierarchyHandler(connection: Connection, services: LangiumSharedServices): void {
587+
const targetState = services.lsp.serviceRequirements.CallHierarchyProvider;
588+
579589
connection.languages.callHierarchy.onPrepare(createServerRequestHandler(
580590
async (services, document, params, cancelToken) => {
581591
if (services.lsp?.CallHierarchyProvider) {
@@ -585,7 +595,7 @@ export function addCallHierarchyHandler(connection: Connection, services: Langiu
585595
return null;
586596
},
587597
services,
588-
DocumentState.IndexedReferences
598+
targetState
589599
));
590600

591601
connection.languages.callHierarchy.onIncomingCalls(createHierarchyRequestHandler(
@@ -596,7 +606,8 @@ export function addCallHierarchyHandler(connection: Connection, services: Langiu
596606
}
597607
return null;
598608
},
599-
services
609+
services,
610+
targetState
600611
));
601612

602613
connection.languages.callHierarchy.onOutgoingCalls(createHierarchyRequestHandler(
@@ -607,7 +618,8 @@ export function addCallHierarchyHandler(connection: Connection, services: Langiu
607618
}
608619
return null;
609620
},
610-
services
621+
services,
622+
targetState
611623
));
612624
}
613625

@@ -617,14 +629,16 @@ export function addTypeHierarchyHandler(connection: Connection, sharedServices:
617629
return;
618630
}
619631

632+
const targetState = sharedServices.lsp.serviceRequirements.TypeHierarchyProvider;
633+
620634
connection.languages.typeHierarchy.onPrepare(
621635
createServerRequestHandler(
622636
async (services, document, params, cancelToken) => {
623637
const result = await services.lsp?.TypeHierarchyProvider?.prepareTypeHierarchy(document, params, cancelToken);
624638
return result ?? null;
625639
},
626640
sharedServices,
627-
DocumentState.IndexedReferences
641+
targetState
628642
),
629643
);
630644

@@ -634,7 +648,8 @@ export function addTypeHierarchyHandler(connection: Connection, sharedServices:
634648
const result = await services.lsp?.TypeHierarchyProvider?.supertypes(params, cancelToken);
635649
return result ?? null;
636650
},
637-
sharedServices
651+
sharedServices,
652+
targetState
638653
),
639654
);
640655

@@ -644,19 +659,21 @@ export function addTypeHierarchyHandler(connection: Connection, sharedServices:
644659
const result = await services.lsp?.TypeHierarchyProvider?.subtypes(params, cancelToken);
645660
return result ?? null;
646661
},
647-
sharedServices
662+
sharedServices,
663+
targetState
648664
),
649665
);
650666
}
651667

652668
export function createHierarchyRequestHandler<P extends TypeHierarchySupertypesParams | TypeHierarchySubtypesParams | CallHierarchyIncomingCallsParams | CallHierarchyOutgoingCallsParams, R, PR, E = void>(
653669
serviceCall: (services: LangiumCoreAndPartialLSPServices, params: P, cancelToken: CancellationToken) => HandlerResult<R, E>,
654670
sharedServices: LangiumSharedServices,
671+
targetState: DocumentState
655672
): ServerRequestHandler<P, R, PR, E> {
656673
const serviceRegistry = sharedServices.ServiceRegistry;
657674
return async (params: P, cancelToken: CancellationToken) => {
658675
const uri = URI.parse(params.item.uri);
659-
const cancellationError = await waitUntilPhase<E>(sharedServices, cancelToken, uri, DocumentState.IndexedReferences);
676+
const cancellationError = await waitUntilPhase<E>(sharedServices, cancelToken, uri, targetState);
660677
if (cancellationError) {
661678
return cancellationError;
662679
}

packages/langium/src/lsp/lsp-services.ts

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
import type { Connection } from 'vscode-languageserver';
88
import type { DeepPartial, LangiumCoreServices, LangiumSharedCoreServices } from '../services.js';
9-
import type { TextDocument } from '../workspace/documents.js';
9+
import type { DocumentState, TextDocument } from '../workspace/documents.js';
1010
import type { CallHierarchyProvider } from './call-hierarchy-provider.js';
1111
import type { CodeActionProvider } from './code-action.js';
1212
import type { CodeLensProvider } from './code-lens-provider.js';
@@ -88,6 +88,29 @@ export type LangiumSharedLSPServices = {
8888
readonly LanguageServer: LanguageServer
8989
readonly NodeKindProvider: NodeKindProvider
9090
readonly WorkspaceSymbolProvider?: WorkspaceSymbolProvider
91+
readonly serviceRequirements: {
92+
readonly CallHierarchyProvider: DocumentState
93+
readonly CodeActionProvider: DocumentState
94+
readonly CodeLensProvider: DocumentState
95+
readonly CompletionProvider: DocumentState
96+
readonly DeclarationProvider: DocumentState
97+
readonly DefinitionProvider: DocumentState
98+
readonly DocumentHighlightProvider: DocumentState
99+
readonly DocumentLinkProvider: DocumentState
100+
readonly DocumentSymbolProvider: DocumentState
101+
readonly FoldingRangeProvider: DocumentState
102+
readonly Formatter: DocumentState
103+
readonly HoverProvider: DocumentState
104+
readonly ImplementationProvider: DocumentState
105+
readonly InlayHintProvider: DocumentState
106+
readonly ReferencesProvider: DocumentState
107+
readonly RenameProvider: DocumentState
108+
readonly SemanticTokenProvider: DocumentState
109+
readonly SignatureHelp: DocumentState
110+
readonly TypeHierarchyProvider: DocumentState
111+
readonly TypeProvider: DocumentState
112+
readonly WorkspaceSymbolProvider: DocumentState
113+
}
91114
},
92115
readonly workspace: {
93116
readonly TextDocuments: TextDocuments<TextDocument>

0 commit comments

Comments
 (0)