Skip to content

Commit

Permalink
fix: multiple document-builder listeners (#1738)
Browse files Browse the repository at this point in the history
Signed-off-by: Christian Dietrich <christian.dietrich.opensource@gmail.com>
  • Loading branch information
cdietrich authored Nov 5, 2024
1 parent 516fe4c commit 21b1051
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 2 deletions.
6 changes: 4 additions & 2 deletions packages/langium/src/workspace/document-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,8 @@ export class DefaultDocumentBuilder implements DocumentBuilder {

protected async notifyDocumentPhase(document: LangiumDocument, state: DocumentState, cancelToken: CancellationToken): Promise<void> {
const listeners = this.documentPhaseListeners.get(state);
for (const listener of listeners) {
const listenersCopy = listeners.slice();
for (const listener of listenersCopy) {
try {
await listener(document, cancelToken);
} catch (err) {
Expand All @@ -471,7 +472,8 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
return;
}
const listeners = this.buildPhaseListeners.get(state);
for (const listener of listeners) {
const listenersCopy = listeners.slice();
for (const listener of listenersCopy) {
await interruptAndCheck(cancelToken);
await listener(documents, cancelToken);
}
Expand Down
54 changes: 54 additions & 0 deletions packages/langium/test/workspace/document-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,60 @@ describe('DefaultDocumentBuilder', () => {
]);
});

test('can handle multiple listeners (buildPhase)', async () => {
const services = await createServices();
const workspace = services.shared.workspace;
const documentFactory = workspace.LangiumDocumentFactory;
const documents = workspace.LangiumDocuments;
const uri = URI.parse('file:///test1.txt');
const document1 = documentFactory.fromString(`
foo 1 A
foo 11 B
bar A
bar B
`, uri);
documents.addDocument(document1);

const builder = workspace.DocumentBuilder;
const p1 = builder.waitUntil(DocumentState.IndexedReferences, uri).then(() => {
});
const p2 = builder.waitUntil(DocumentState.IndexedReferences, uri).then(() => {
});
await builder.build([document1], {});
await Promise.all([p1, p2]);
expect(document1.state).toBe(DocumentState.IndexedReferences);
});

test('can handle multiple listeners (documentPhase)', async () => {
const services = await createServices();
const workspace = services.shared.workspace;
const documentFactory = workspace.LangiumDocumentFactory;
const documents = workspace.LangiumDocuments;
const uri = URI.parse('file:///test1.txt');
const document1 = documentFactory.fromString(`
foo 1 A
foo 11 B
bar A
bar B
`, uri);
documents.addDocument(document1);

const builder = workspace.DocumentBuilder;
let p1called = false;
const p1 = builder.onDocumentPhase(DocumentState.IndexedReferences, (_d) => {
p1called = true;
p1.dispose();
});
let p2called = false;
const p2 = builder.onDocumentPhase(DocumentState.IndexedReferences, (_d) => {
p2called = true;
p2.dispose();
});
await builder.build([document1], {});
expect(p1called).toBe(true);
expect(p2called).toBe(true);
});

test('waits until a specific workspace stage has been reached', async () => {
const services = await createServices();
const documentFactory = services.shared.workspace.LangiumDocumentFactory;
Expand Down

0 comments on commit 21b1051

Please sign in to comment.