mirror of
https://github.com/denoland/deno.git
synced 2025-09-26 12:19:12 +00:00
fix(lint): don't recurse infinitely for large ASTs (#28265)
We previously failed to lint `./cli/tsc/00_typescript.js` with plugins, because every "next" node would cause a new stack frame to be added.
This commit is contained in:
parent
f373a20a6f
commit
55dc6f4b93
1 changed files with 35 additions and 37 deletions
|
@ -1150,54 +1150,52 @@ export function runPluginsForFile(fileName, serializedAst) {
|
||||||
* @param {CancellationToken} cancellationToken
|
* @param {CancellationToken} cancellationToken
|
||||||
*/
|
*/
|
||||||
function traverse(ctx, visitors, idx, cancellationToken) {
|
function traverse(ctx, visitors, idx, cancellationToken) {
|
||||||
if (idx === AST_IDX_INVALID) return;
|
while (idx !== AST_IDX_INVALID) {
|
||||||
if (cancellationToken.isCancellationRequested()) return;
|
if (cancellationToken.isCancellationRequested()) return;
|
||||||
|
|
||||||
const { buf } = ctx;
|
const { buf } = ctx;
|
||||||
const nodeType = readType(ctx.buf, idx);
|
const nodeType = readType(ctx.buf, idx);
|
||||||
|
|
||||||
/** @type {VisitorFn[] | null} */
|
/** @type {VisitorFn[] | null} */
|
||||||
let exits = null;
|
let exits = null;
|
||||||
|
|
||||||
// Only visit if it's an actual node
|
// Only visit if it's an actual node
|
||||||
if (nodeType !== AST_GROUP_TYPE) {
|
if (nodeType !== AST_GROUP_TYPE) {
|
||||||
// Loop over visitors and check if any selector matches
|
// Loop over visitors and check if any selector matches
|
||||||
for (let i = 0; i < visitors.length; i++) {
|
for (let i = 0; i < visitors.length; i++) {
|
||||||
const v = visitors[i];
|
const v = visitors[i];
|
||||||
if (v.matcher(ctx.matcher, idx)) {
|
if (v.matcher(ctx.matcher, idx)) {
|
||||||
if (v.info.exit !== NOOP) {
|
if (v.info.exit !== NOOP) {
|
||||||
if (exits === null) {
|
if (exits === null) {
|
||||||
exits = [v.info.exit];
|
exits = [v.info.exit];
|
||||||
} else {
|
} else {
|
||||||
exits.push(v.info.exit);
|
exits.push(v.info.exit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v.info.enter !== NOOP) {
|
||||||
|
const node = /** @type {*} */ (getNode(ctx, idx));
|
||||||
|
v.info.enter(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (v.info.enter !== NOOP) {
|
try {
|
||||||
|
const childIdx = readChild(buf, idx);
|
||||||
|
if (childIdx > AST_IDX_INVALID) {
|
||||||
|
traverse(ctx, visitors, childIdx, cancellationToken);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (exits !== null) {
|
||||||
|
for (let i = 0; i < exits.length; i++) {
|
||||||
const node = /** @type {*} */ (getNode(ctx, idx));
|
const node = /** @type {*} */ (getNode(ctx, idx));
|
||||||
v.info.enter(node);
|
exits[i](node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
idx = readNext(buf, idx);
|
||||||
const childIdx = readChild(buf, idx);
|
|
||||||
if (childIdx > AST_IDX_INVALID) {
|
|
||||||
traverse(ctx, visitors, childIdx, cancellationToken);
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (exits !== null) {
|
|
||||||
for (let i = 0; i < exits.length; i++) {
|
|
||||||
const node = /** @type {*} */ (getNode(ctx, idx));
|
|
||||||
exits[i](node);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextIdx = readNext(buf, idx);
|
|
||||||
if (nextIdx > AST_IDX_INVALID) {
|
|
||||||
traverse(ctx, visitors, nextIdx, cancellationToken);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue