mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-13 02:45:24 -05:00
Add text-based fastpaths into LS token matching (#41924)
* Add text-based fastpaths into LS token matching * Update src/services/utilities.ts Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * Update src/services/utilities.ts Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * Update src/services/utilities.ts Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * Limit search a bit * Secretly, this was allowed to be `undefined` and was in fact used as such Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com>
This commit is contained in:
@@ -1391,7 +1391,23 @@ namespace ts {
|
||||
return isInsideJsxElementTraversal(getTokenAtPosition(sourceFile, position));
|
||||
}
|
||||
|
||||
export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind, sourceFile: SourceFile) {
|
||||
export function findPrecedingMatchingToken(token: Node, matchingTokenKind: SyntaxKind.OpenBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.OpenBracketToken, sourceFile: SourceFile) {
|
||||
const closeTokenText = tokenToString(token.kind)!;
|
||||
const matchingTokenText = tokenToString(matchingTokenKind)!;
|
||||
const tokenFullStart = token.getFullStart();
|
||||
// Text-scan based fast path - can be bamboozled by comments and other trivia, but often provides
|
||||
// a good, fast approximation without too much extra work in the cases where it fails.
|
||||
const bestGuessIndex = sourceFile.text.lastIndexOf(matchingTokenText, tokenFullStart);
|
||||
if (bestGuessIndex === -1) {
|
||||
return undefined; // if the token text doesn't appear in the file, there can't be a match - super fast bail
|
||||
}
|
||||
// we can only use the textual result directly if we didn't have to count any close tokens within the range
|
||||
if (sourceFile.text.lastIndexOf(closeTokenText, tokenFullStart - 1) < bestGuessIndex) {
|
||||
const nodeAtGuess = findPrecedingToken(bestGuessIndex + 1, sourceFile);
|
||||
if (nodeAtGuess && nodeAtGuess.kind === matchingTokenKind) {
|
||||
return nodeAtGuess;
|
||||
}
|
||||
}
|
||||
const tokenKind = token.kind;
|
||||
let remainingMatchingTokens = 0;
|
||||
while (true) {
|
||||
@@ -1447,7 +1463,14 @@ namespace ts {
|
||||
}
|
||||
|
||||
// Get info for an expression like `f <` that may be the start of type arguments.
|
||||
export function getPossibleTypeArgumentsInfo(tokenIn: Node, sourceFile: SourceFile): PossibleTypeArgumentInfo | undefined {
|
||||
export function getPossibleTypeArgumentsInfo(tokenIn: Node | undefined, sourceFile: SourceFile): PossibleTypeArgumentInfo | undefined {
|
||||
// This is a rare case, but one that saves on a _lot_ of work if true - if the source file has _no_ `<` character,
|
||||
// then there obviously can't be any type arguments - no expensive brace-matching backwards scanning required
|
||||
|
||||
if (sourceFile.text.lastIndexOf("<", tokenIn ? tokenIn.pos : sourceFile.text.length) === -1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let token: Node | undefined = tokenIn;
|
||||
// This function determines if the node could be type argument position
|
||||
// Since during editing, when type argument list is not complete,
|
||||
|
||||
Reference in New Issue
Block a user