Ensure findPrecedingToken recurses into JSDoc children when needed (#53487)

This commit is contained in:
Jake Bailey
2023-04-12 12:00:47 -07:00
committed by GitHub
parent bec204c844
commit a26175bffb
3 changed files with 29 additions and 1 deletions

View File

@@ -1739,7 +1739,14 @@ export function findPrecedingToken(position: number, sourceFile: SourceFileLike,
if (lookInPreviousChild) {
// actual start of the node is past the position - previous token should be at the end of previous child
const candidate = findRightmostChildNodeWithTokens(children, /*exclusiveStartPosition*/ i, sourceFile, n.kind);
return candidate && findRightmostToken(candidate, sourceFile);
if (candidate) {
// Ensure we recurse into JSDoc nodes with children.
if (!excludeJsdoc && isJSDocCommentContainingNode(candidate) && candidate.getChildren(sourceFile).length) {
return find(candidate);
}
return findRightmostToken(candidate, sourceFile);
}
return undefined;
}
else {
// candidate should be in this node

View File

@@ -61,6 +61,7 @@ import "./unittests/services/patternMatcher";
import "./unittests/services/preProcessFile";
import "./unittests/services/textChanges";
import "./unittests/services/transpile";
import "./unittests/services/utilities";
import "./unittests/tsbuild/amdModulesWithOut";
import "./unittests/tsbuild/clean";
import "./unittests/tsbuild/commandLine";

View File

@@ -0,0 +1,20 @@
import * as ts from "../../_namespaces/ts";
describe("unittests:: services:: utilities", () => {
describe("Test findPrecedingMatchingToken,", () => {
it("should not infinite loop finding opening brace", () => {
const sourceFile = ts.createSourceFile("file.ts", `/// <reference path="./compiler.d.ts" />
(/** @window => {
/** @type {Abcd123} */
const core = window.Abcd.core;
})();`, ts.ScriptTarget.ESNext, /*setParentNodes*/ true);
// can't use ts.getTokenAtPosition because it returns back the wrong token
const param = ts.forEachChildRecursively(sourceFile, node => node.kind === ts.SyntaxKind.Parameter ? node : undefined)!;
const jsDoc = param.getChildren()[0];
const token = jsDoc.getLastToken()!;
const result = ts.findPrecedingMatchingToken(token, ts.SyntaxKind.OpenBraceToken, sourceFile);
assert.isDefined(result);
});
});
});