Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve the performance of requesting completions within a massive array literal #40953

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion src/services/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1158,6 +1158,35 @@ namespace ts {
}
}

/**
* Psuedo-binary searches the list of children for the first element whose end position exceeds the input position
* Returns `undefined` if no element satisfies the condition, or the index of the satisfying element otherwise.
* This could probably be written using our `binarySeach` helper, but the `keyComparator` would be hairy enough
* that it's probably worth just writing out the algorithm in full.
* @param {number} start - Start search index, inclusive
* @param {number} end - End search index, inclusive
*/
function searchChildrenSlice(position: number, children: Node[], start = 0, end = children.length - 1): number | undefined {
const pivot = Math.floor((end - start)/2) + start;
if (!children[pivot]) {
return undefined;
}
if (position < children[pivot].end) {
// first element whose end position is greater than the input position
if (!children[pivot - 1] || position >= children[pivot - 1].end) {
return pivot;
}
if (pivot === start) {
weswigham marked this conversation as resolved.
Show resolved Hide resolved
return undefined;
}
return searchChildrenSlice(position, children, start, pivot - 1);
weswigham marked this conversation as resolved.
Show resolved Hide resolved
}
if (pivot === end) {
return undefined;
}
return searchChildrenSlice(position, children, pivot + 1, end);
}

/**
* Finds the rightmost token satisfying `token.end <= position`,
* excluding `JsxText` tokens containing only whitespace.
Expand All @@ -1173,7 +1202,8 @@ namespace ts {
}

const children = n.getChildren(sourceFile);
for (let i = 0; i < children.length; i++) {
const i = searchChildrenSlice(position, children);
if (typeof i !== "undefined") {
const child = children[i];
// Note that the span of a node's tokens is [node.getStart(...), node.end).
// Given that `position < child.end` and child has constituent tokens, we distinguish these cases:
Expand Down
19 changes: 19 additions & 0 deletions tests/cases/fourslash/excessivelyLargeArrayLiteralCompletions.ts

Large diffs are not rendered by default.