Skip to content

Commit

Permalink
Emit onUpdate event on DocumentBuilder#build (#1190)
Browse files Browse the repository at this point in the history
  • Loading branch information
msujew authored Sep 15, 2023
1 parent 03da179 commit f3cf206
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 9 deletions.
11 changes: 7 additions & 4 deletions packages/langium/src/workspace/document-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export interface DocumentBuilder {
onBuildPhase(targetState: DocumentState, callback: DocumentBuildListener): Disposable;
}

export type DocumentUpdateListener = (changed: URI[], deleted: URI[]) => void
export type DocumentUpdateListener = (changed: URI[], deleted: URI[]) => void | Promise<void>
export type DocumentBuildListener = (built: LangiumDocument[], cancelToken: CancellationToken) => void | Promise<void>
export class DefaultDocumentBuilder implements DocumentBuilder {

Expand Down Expand Up @@ -144,6 +144,7 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
this.buildState.delete(key);
}
}
await this.emitUpdate(documents.map(e => e.uri), []);
await this.buildDocuments(documents, options, cancelToken);
}

Expand Down Expand Up @@ -173,9 +174,7 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
doc.diagnostics = undefined;
});
// Notify listeners of the update
for (const listener of this.updateListeners) {
listener(changed, deleted);
}
await this.emitUpdate(changed, deleted);
// Only allow interrupting the execution after all state changes are done
await interruptAndCheck(cancelToken);

Expand All @@ -191,6 +190,10 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
await this.buildDocuments(rebuildDocuments, this.updateBuildOptions, cancelToken);
}

protected async emitUpdate(changed: URI[], deleted: URI[]): Promise<void> {
await Promise.all(this.updateListeners.map(listener => listener(changed, deleted)));
}

/**
* Check whether the given document should be relinked after changes were found in the given URIs.
*/
Expand Down
10 changes: 5 additions & 5 deletions packages/langium/test/grammar/type-system/inferred-types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ describe('Inferred types', () => {
});

test('Should infer data type rules as unions', async () => {
expectTypes(`
await expectTypes(`
Strings returns string: 'a' | 'b' | 'c';
MoreStrings returns string: Strings | 'd' | 'e';
Complex returns string: ID ('.' ID)*;
Expand Down Expand Up @@ -323,7 +323,7 @@ describe('Inferred types', () => {
});

test('Infers X as a super interface of Y and Z with property `id`', async () => {
expectTypes(`
await expectTypes(`
entry X: id=ID ({infer Y} 'a' | {infer Z} 'b');
terminal ID: /[a-zA-Z_][a-zA-Z0-9_]*/;
`, expandToString`
Expand All @@ -343,7 +343,7 @@ describe('Inferred types', () => {

describe('inferred types that are used by the grammar', () => {
test('B is defined and A is not', async () => {
expectTypes(`
await expectTypes(`
A infers B: 'a' name=ID (otherA=[B])?;
hidden terminal WS: /\\s+/;
terminal ID: /[a-zA-Z_][a-zA-Z0-9_]*/;
Expand All @@ -359,7 +359,7 @@ describe('inferred types that are used by the grammar', () => {

describe('inferred and declared types', () => {
test('Declared interfaces should be preserved as interfaces', async () => {
expectTypes(`
await expectTypes(`
X returns X: Y | Z;
Y: y='y';
Z: z='z';
Expand Down Expand Up @@ -881,10 +881,10 @@ describe('generated types from declared types include all of them', () => {
// });

const services = createLangiumGrammarServices(EmptyFileSystem).grammar;
const helper = parseHelper<Grammar>(services);

async function getTypes(grammar: string): Promise<AstTypes> {
await clearDocuments(services);
const helper = parseHelper<Grammar>(services);
const result = await helper(grammar);
const gram = result.parseResult.value;
return collectAst(gram);
Expand Down
36 changes: 36 additions & 0 deletions packages/langium/test/workspace/document-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ describe('DefaultDocumentBuilder', () => {
return services;
}

test('emits `onUpdate` on `update` call', async () => {
const services = await createServices();
const documentFactory = services.shared.workspace.LangiumDocumentFactory;
const documents = services.shared.workspace.LangiumDocuments;
const document = documentFactory.fromString('', URI.parse('file:///test1.txt'));
documents.addDocument(document);

const builder = services.shared.workspace.DocumentBuilder;
await builder.build([document], {});
addTextDocument(document, services);
let called = false;
builder.onUpdate(() => {
called = true;
});
await builder.update([document.uri], []);
expect(called).toBe(true);
});

test('emits `onUpdate` on `build` call', async () => {
const services = await createServices();
const documentFactory = services.shared.workspace.LangiumDocumentFactory;
const documents = services.shared.workspace.LangiumDocuments;
const document = documentFactory.fromString('', URI.parse('file:///test1.txt'));
documents.addDocument(document);

const builder = services.shared.workspace.DocumentBuilder;
await builder.build([document], {});
addTextDocument(document, services);
let called = false;
builder.onUpdate(() => {
called = true;
});
await builder.build([document]);
expect(called).toBe(true);
});

test('resumes document build after cancellation', async () => {
const services = await createServices();
const documentFactory = services.shared.workspace.LangiumDocumentFactory;
Expand Down

0 comments on commit f3cf206

Please sign in to comment.