Reuse start position in binarySearchKey (#49641)

* Reuse start position in binarySearchKey

* Kick out early if end < position
This commit is contained in:
Andrew Casey
2022-06-27 14:31:22 -07:00
committed by GitHub
parent 2bc91a6b46
commit 8ed846c73b

View File

@@ -1147,13 +1147,20 @@ namespace ts {
// position and whose end is greater than the position.
// There are more sophisticated end tests later, but this one is very fast
// and allows us to skip a bunch of work
const end = children[middle].getEnd();
if (end < position) {
return Comparison.LessThan;
}
const start = allowPositionInLeadingTrivia ? children[middle].getFullStart() : children[middle].getStart(sourceFile, /*includeJsDoc*/ true);
if (start > position) {
return Comparison.GreaterThan;
}
// first element whose start position is before the input and whose end position is after or equal to the input
if (nodeContainsPosition(children[middle])) {
if (nodeContainsPosition(children[middle], start, end)) {
if (children[middle - 1]) {
// we want the _first_ element that contains the position, so left-recur if the prior node also contains the position
if (nodeContainsPosition(children[middle - 1])) {
@@ -1181,13 +1188,16 @@ namespace ts {
return current;
}
function nodeContainsPosition(node: Node) {
const start = allowPositionInLeadingTrivia ? node.getFullStart() : node.getStart(sourceFile, /*includeJsDoc*/ true);
function nodeContainsPosition(node: Node, start?: number, end?: number) {
end ??= node.getEnd();
if (end < position) {
return false;
}
start ??= allowPositionInLeadingTrivia ? node.getFullStart() : node.getStart(sourceFile, /*includeJsDoc*/ true);
if (start > position) {
// If this child begins after position, then all subsequent children will as well.
return false;
}
const end = node.getEnd();
if (position < end || (position === end && (node.kind === SyntaxKind.EndOfFileToken || includeEndPosition))) {
return true;
}