Skip to content

Commit 06c1fff

Browse files
committed
address review comments
1 parent d0fcb7d commit 06c1fff

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

javascript/extractor/lib/typescript/src/type_table.ts

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -421,32 +421,43 @@ export class TypeTable {
421421
return id;
422422
}
423423

424-
// type -> [id (not unfolded), id (unfolded)]
425-
private idCache = new WeakMap<ts.Type, [number | undefined, number | undefined]>();
424+
/**
425+
* Caches the result of `getId`: `type -> [id (not unfolded), id (unfolded)]`.
426+
*
427+
* A value of `undefined` means the value is not yet computed,
428+
* and `number | null` corresponds to the return value of `getId`.
429+
*/
430+
private idCache = new WeakMap<ts.Type, [number | null | undefined, number | null | undefined]>();
426431

427432
/**
428433
* Gets the canonical ID for the given type, generating a fresh ID if necessary.
429434
*
430435
* Returns `null` if we do not support extraction of this type.
431436
*/
432437
public getId(type: ts.Type, unfoldAlias: boolean): number | null {
433-
const cached = this.idCache.get(type);
434-
if (typeof cached !== "undefined") {
435-
let value = cached[unfoldAlias ? 1 : 0];
436-
if (typeof value !== "undefined") return value;
437-
}
438-
const setAndReturn = (v: number | null) => {
439-
let cached = this.idCache.get(type) || [undefined, undefined];
440-
cached[unfoldAlias ? 1 : 0] = v;
441-
this.idCache.set(type, cached);
442-
return v;
443-
}
444-
438+
let cached = this.idCache.get(type) ?? [undefined, undefined];
439+
let cachedValue = cached[unfoldAlias ? 1 : 0];
440+
if (cachedValue !== undefined) return cachedValue;
441+
442+
let result = this.getIdRaw(type, unfoldAlias);
443+
cached[unfoldAlias ? 1 : 0] = result;
444+
return result;
445+
}
446+
447+
/**
448+
* Gets the canonical ID for the given type, generating a fresh ID if necessary.
449+
*
450+
* Returns `null` if we do not support extraction of this type.
451+
*/
452+
public getIdRaw(type: ts.Type, unfoldAlias: boolean): number | null {
445453
if (this.typeRecursionDepth > 100) {
446454
// Ignore infinitely nested anonymous types, such as `{x: {x: {x: ... }}}`.
447455
// Such a type can't be written directly with TypeScript syntax (as it would need to be named),
448456
// but it can occur rarely as a result of type inference.
449-
return setAndReturn(null);
457+
458+
// Caching this value is technically incorrect, as a type might be seen at depth 101 and then we cache the fact that it can't be extracted.
459+
// Then later the type is seen at a lower depth and could be extracted, but then we immediately give up because of the cached failure.
460+
return null;
450461
}
451462
// Replace very long string literal types with `string`.
452463
if ((type.flags & ts.TypeFlags.StringLiteral) && ((type as ts.LiteralType).value as string).length > 30) {
@@ -455,12 +466,12 @@ export class TypeTable {
455466
++this.typeRecursionDepth;
456467
let content = this.getTypeString(type, unfoldAlias);
457468
--this.typeRecursionDepth;
458-
if (content == null) return setAndReturn(null); // Type not supported.
469+
if (content == null) return null; // Type not supported.
459470
let id = this.typeIds.get(content);
460471
if (id == null) {
461472
let stringValue = this.stringifyType(type, unfoldAlias);
462473
if (stringValue == null) {
463-
return setAndReturn(null); // Type not supported.
474+
return null; // Type not supported.
464475
}
465476
id = this.typeIds.size;
466477
this.typeIds.set(content, id);
@@ -485,7 +496,7 @@ export class TypeTable {
485496
this.buildTypeWorklist.push([type, id, unfoldAlias]);
486497
}
487498
}
488-
return setAndReturn(id);
499+
return id;
489500
}
490501

491502
private stringifyType(type: ts.Type, unfoldAlias: boolean): string {

0 commit comments

Comments
 (0)