Skip to content

Commit

Permalink
optimize document sorting and update documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
snarkipus committed Jul 27, 2024
1 parent 3b007c2 commit cfe7ef4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 17 deletions.
7 changes: 4 additions & 3 deletions packages/langium/src/references/scope-computation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,9 @@ export class DefaultScopeComputation implements ScopeComputation {
this.descriptions = services.workspace.AstNodeDescriptionProvider;
}

async computeExports(document: LangiumDocument, cancelToken = CancellationToken.None): Promise<AstNodeDescription[]> {
return this.computeExportsForNode(document.parseResult.value, document, undefined, cancelToken);
async computeExports(document: LangiumDocument, cancelToken?: CancellationToken): Promise<AstNodeDescription[]> {
const token = cancelToken ?? CancellationToken.None;
return this.computeExportsForNode(document.parseResult.value, document, undefined, token);
}

/**
Expand All @@ -86,7 +87,7 @@ export class DefaultScopeComputation implements ScopeComputation {
* @param document The document containing the AST node to be exported.
* @param children A function called with {@link parentNode} as single argument and returning an {@link Iterable} supplying the children to be visited, which must be directly or transitively contained in {@link parentNode}.
* @param cancelToken Indicates when to cancel the current operation.
* @throws `OperationCanceled` if a user action occurs during execution.
* @throws `OperationCancelled` if a user action occurs during execution.
* @returns A list of {@link AstNodeDescription AstNodeDescriptions} to be published to index.
*/
async computeExportsForNode(parentNode: AstNode, document: LangiumDocument<AstNode>, children: (root: AstNode) => Iterable<AstNode> = streamContents, cancelToken: CancellationToken = CancellationToken.None): Promise<AstNodeDescription[]> {
Expand Down
56 changes: 42 additions & 14 deletions packages/langium/src/workspace/document-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,21 +251,28 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
* in files that are currently not opened in the editor.
*/
protected sortDocuments(documents: LangiumDocument[]): LangiumDocument[] {
const hasTextDocument = new Map<LangiumDocument, boolean>();
for (const doc of documents) {
hasTextDocument.set(doc, Boolean(this.textDocuments?.get(doc.uri.toString())));
}
return documents.sort((a, b) => {
const aHasDoc = hasTextDocument.get(a);
const bHasDoc = hasTextDocument.get(b);
if (aHasDoc && !bHasDoc) {
return -1;
} else if (!aHasDoc && bHasDoc) {
return 1;
} else {
return 0;
let left = 0;
let right = documents.length - 1;

while (left < right) {
while (left < documents.length && this.hasTextDocument(documents[left])) {
left++;
}
});

while (right >= 0 && !this.hasTextDocument(documents[right])) {
right--;
}

if (left < right) {
[documents[left], documents[right]] = [documents[right], documents[left]];
}
}

return documents;
}

private hasTextDocument(doc: LangiumDocument): boolean {
return Boolean(this.textDocuments?.get(doc.uri.toString()));
}

/**
Expand Down Expand Up @@ -293,6 +300,11 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
/**
* Build the given documents by stepping through all build phases. If a document's state indicates
* that a certain build phase is already done, the phase is skipped for that document.
*
* @param documents The documents to build.
* @param options the {@link BuildOptions} to use.
* @param cancelToken A cancellation token that can be used to cancel the build.
* @returns A promise that resolves when the build is done.
*/
protected async buildDocuments(documents: LangiumDocument[], options: BuildOptions, cancelToken: CancellationToken): Promise<void> {
this.prepareBuild(documents, options);
Expand Down Expand Up @@ -333,6 +345,12 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
}
}

/**
* Runs prior to beginning the build process to update the {@link DocumentBuildState} for each document
*
* @param documents collection of documents to be built
* @param options the {@link BuildOptions} to use
*/
protected prepareBuild(documents: LangiumDocument[], options: BuildOptions): void {
for (const doc of documents) {
const key = doc.uri.toString();
Expand All @@ -350,6 +368,16 @@ export class DefaultDocumentBuilder implements DocumentBuilder {
}
}

/**
* Runs a cancelable operation on a set of documents to bring them to a specified {@link DocumentState}.
*
* @param documents The array of documents to process.
* @param targetState The target {@link DocumentState} to bring the documents to.
* @param cancelToken A token that can be used to cancel the operation.
* @param callback A function to be called for each document.
* @returns A promise that resolves when all documents have been processed or the operation is canceled.
* @throws Will throw `OperationCancelled` if the operation is canceled via a `CancellationToken`.
*/
protected async runCancelable(documents: LangiumDocument[], targetState: DocumentState, cancelToken: CancellationToken,
callback: (document: LangiumDocument) => MaybePromise<unknown>): Promise<void> {
const filtered = documents.filter(doc => doc.state < targetState);
Expand Down

0 comments on commit cfe7ef4

Please sign in to comment.