Skip to content

Commit efbfab3

Browse files
authored
Improve unknown file type handling in language server (#1455)
1 parent 39e55c4 commit efbfab3

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

packages/langium/src/lsp/document-update-handler.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import type { TextDocument } from '../workspace/documents.js';
1212
import type { WorkspaceLock } from '../workspace/workspace-lock.js';
1313
import type { LangiumSharedServices } from './lsp-services.js';
1414
import type { WorkspaceManager } from '../workspace/workspace-manager.js';
15+
import type { ServiceRegistry } from '../service-registry.js';
1516

1617
/**
1718
* Shared service for handling text document changes and watching relevant files.
@@ -35,11 +36,13 @@ export class DefaultDocumentUpdateHandler implements DocumentUpdateHandler {
3536
protected readonly workspaceManager: WorkspaceManager;
3637
protected readonly documentBuilder: DocumentBuilder;
3738
protected readonly workspaceLock: WorkspaceLock;
39+
protected readonly serviceRegistry: ServiceRegistry;
3840

3941
constructor(services: LangiumSharedServices) {
4042
this.workspaceManager = services.workspace.WorkspaceManager;
4143
this.documentBuilder = services.workspace.DocumentBuilder;
4244
this.workspaceLock = services.workspace.WorkspaceLock;
45+
this.serviceRegistry = services.ServiceRegistry;
4346

4447
let canRegisterFileWatcher = false;
4548
services.lsp.LanguageServer.onInitialize(params => {
@@ -73,6 +76,9 @@ export class DefaultDocumentUpdateHandler implements DocumentUpdateHandler {
7376
}
7477

7578
protected fireDocumentUpdate(changed: URI[], deleted: URI[]): void {
79+
// Filter out URIs that do not have a service in the registry
80+
// Running the document builder update will fail for those URIs
81+
changed = changed.filter(uri => this.serviceRegistry.hasServices(uri));
7682
// Only fire the document update when the workspace manager is ready
7783
// Otherwise, we might miss the initial indexing of the workspace
7884
this.workspaceManager.ready.then(() => {

packages/langium/src/lsp/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ export * from './default-lsp-module.js';
1515
export * from './document-highlight-provider.js';
1616
export * from './document-link-provider.js';
1717
export * from './document-symbol-provider.js';
18+
export * from './document-update-handler.js';
1819
export * from './execute-command-handler.js';
20+
export * from './file-operation-handler.js';
1921
export * from './folding-range-provider.js';
2022
export * from './formatter.js';
2123
export * from './fuzzy-matcher.js';

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -640,12 +640,12 @@ export function createHierarchyRequestHandler<P extends TypeHierarchySupertypesP
640640
if (cancellationError) {
641641
return cancellationError;
642642
}
643-
const language = serviceRegistry.getServices(uri);
644-
if (!language) {
645-
const message = `Could not find service instance for uri: '${uri.toString()}'`;
646-
console.error(message);
647-
throw new Error(message);
643+
if (!serviceRegistry.hasServices(uri)) {
644+
const errorText = `Could not find service instance for uri: '${uri}'`;
645+
console.debug(errorText);
646+
return responseError<E>(new Error(errorText));
648647
}
648+
const language = serviceRegistry.getServices(uri);
649649
try {
650650
return await serviceCall(language, params, cancelToken);
651651
} catch (err) {
@@ -667,14 +667,14 @@ export function createServerRequestHandler<P extends { textDocument: TextDocumen
667667
if (cancellationError) {
668668
return cancellationError;
669669
}
670-
const language = serviceRegistry.getServices(uri);
671-
if (!language) {
670+
if (!serviceRegistry.hasServices(uri)) {
672671
const errorText = `Could not find service instance for uri: '${uri}'`;
673-
console.error(errorText);
674-
throw new Error(errorText);
672+
console.debug(errorText);
673+
return responseError<E>(new Error(errorText));
675674
}
676-
const document = await documents.getOrCreateDocument(uri);
675+
const language = serviceRegistry.getServices(uri);
677676
try {
677+
const document = await documents.getOrCreateDocument(uri);
678678
return await serviceCall(language, document, params, cancelToken);
679679
} catch (err) {
680680
return responseError<E>(err);
@@ -695,16 +695,13 @@ export function createRequestHandler<P extends { textDocument: TextDocumentIdent
695695
if (cancellationError) {
696696
return cancellationError;
697697
}
698-
const language = serviceRegistry.getServices(uri);
699-
if (!language) {
700-
console.error(`Could not find service instance for uri: '${uri.toString()}'`);
701-
return null;
702-
}
703-
const document = documents.getDocument(uri);
704-
if (!document) {
698+
if (!serviceRegistry.hasServices(uri)) {
699+
console.debug(`Could not find service instance for uri: '${uri.toString()}'`);
705700
return null;
706701
}
702+
const language = serviceRegistry.getServices(uri);
707703
try {
704+
const document = await documents.getOrCreateDocument(uri);
708705
return await serviceCall(language, document, params, cancelToken);
709706
} catch (err) {
710707
return responseError<E>(err);

packages/langium/src/service-registry.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ export interface ServiceRegistry {
2424
*/
2525
getServices(uri: URI): LangiumCoreServices;
2626

27+
/**
28+
* Check whether services are available for the given URI.
29+
*/
30+
hasServices(uri: URI): boolean;
31+
2732
/**
2833
* The full set of registered language services.
2934
*/
@@ -78,6 +83,15 @@ export class DefaultServiceRegistry implements ServiceRegistry {
7883
return services;
7984
}
8085

86+
hasServices(uri: URI): boolean {
87+
try {
88+
this.getServices(uri);
89+
return true;
90+
} catch {
91+
return false;
92+
}
93+
}
94+
8195
get all(): readonly LangiumCoreServices[] {
8296
if (this.singleton !== undefined) {
8397
return [this.singleton];

0 commit comments

Comments
 (0)