faster TypeScript extraction by not having to compute the "type-string" for a type every time

This commit is contained in:
erik-krogh
2024-01-09 14:30:55 +01:00
parent 0bc1463ab0
commit d0fcb7d1ed

View File

@@ -421,17 +421,32 @@ export class TypeTable {
return id;
}
// type -> [id (not unfolded), id (unfolded)]
private idCache = new WeakMap<ts.Type, [number | undefined, number | undefined]>();
/**
* Gets the canonical ID for the given type, generating a fresh ID if necessary.
*
* Returns `null` if we do not support extraction of this type.
*/
public getId(type: ts.Type, unfoldAlias: boolean): number | null {
const cached = this.idCache.get(type);
if (typeof cached !== "undefined") {
let value = cached[unfoldAlias ? 1 : 0];
if (typeof value !== "undefined") return value;
}
const setAndReturn = (v: number | null) => {
let cached = this.idCache.get(type) || [undefined, undefined];
cached[unfoldAlias ? 1 : 0] = v;
this.idCache.set(type, cached);
return v;
}
if (this.typeRecursionDepth > 100) {
// Ignore infinitely nested anonymous types, such as `{x: {x: {x: ... }}}`.
// Such a type can't be written directly with TypeScript syntax (as it would need to be named),
// but it can occur rarely as a result of type inference.
return null;
return setAndReturn(null);
}
// Replace very long string literal types with `string`.
if ((type.flags & ts.TypeFlags.StringLiteral) && ((type as ts.LiteralType).value as string).length > 30) {
@@ -440,12 +455,12 @@ export class TypeTable {
++this.typeRecursionDepth;
let content = this.getTypeString(type, unfoldAlias);
--this.typeRecursionDepth;
if (content == null) return null; // Type not supported.
if (content == null) return setAndReturn(null); // Type not supported.
let id = this.typeIds.get(content);
if (id == null) {
let stringValue = this.stringifyType(type, unfoldAlias);
if (stringValue == null) {
return null; // Type not supported.
return setAndReturn(null); // Type not supported.
}
id = this.typeIds.size;
this.typeIds.set(content, id);
@@ -470,7 +485,7 @@ export class TypeTable {
this.buildTypeWorklist.push([type, id, unfoldAlias]);
}
}
return id;
return setAndReturn(id);
}
private stringifyType(type: ts.Type, unfoldAlias: boolean): string {