Avoid infinite loops in type inference logic (#12390)
This commit is contained in:
parent
243d3b2dfd
commit
4f9ad5cc3a
@ -14,6 +14,11 @@ export function getTypeAnnotation(): Object {
|
||||
return (this.typeAnnotation = type);
|
||||
}
|
||||
|
||||
// Used to avoid infinite recursion in cases like
|
||||
// var b, c; if (0) { c = 1; b = c; } c = b;
|
||||
// It also works with indirect recursion.
|
||||
const typeAnnotationInferringNodes = new WeakSet();
|
||||
|
||||
/**
|
||||
* todo: split up this method
|
||||
*/
|
||||
@ -47,6 +52,13 @@ export function _getTypeAnnotation(): ?Object {
|
||||
return node.typeAnnotation;
|
||||
}
|
||||
|
||||
if (typeAnnotationInferringNodes.has(node)) {
|
||||
// Bail out from type inference to avoid infinite loops
|
||||
return;
|
||||
}
|
||||
typeAnnotationInferringNodes.add(node);
|
||||
|
||||
try {
|
||||
let inferer = inferers[node.type];
|
||||
if (inferer) {
|
||||
return inferer.call(this, node);
|
||||
@ -56,6 +68,9 @@ export function _getTypeAnnotation(): ?Object {
|
||||
if (inferer?.validParent) {
|
||||
return this.parentPath.getTypeAnnotation();
|
||||
}
|
||||
} finally {
|
||||
typeAnnotationInferringNodes.delete(node);
|
||||
}
|
||||
}
|
||||
|
||||
export function isBaseType(baseName: string, soft?: boolean): boolean {
|
||||
|
||||
@ -289,5 +289,21 @@ describe("inference", function () {
|
||||
const type = path.getTypeAnnotation();
|
||||
expect(t.isAnyTypeAnnotation(type)).toBeTruthy();
|
||||
});
|
||||
it("should not cause a stack overflow when two variable depend on eachother", function () {
|
||||
const path = getPath(`
|
||||
var b, c;
|
||||
while (0) {
|
||||
c = 1;
|
||||
b = c;
|
||||
}
|
||||
c = b;
|
||||
`).get("body.2.expression");
|
||||
|
||||
expect(path.toString()).toBe("c = b");
|
||||
|
||||
// Note: this could technically be "number | void", but the cycle detection
|
||||
// logic just bails out to "any" to avoid infinite loops.
|
||||
expect(path.getTypeAnnotation()).toEqual({ type: "AnyTypeAnnotation" });
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user