From 18b0fc0040689a978d5c097ded37651a00a6d43e Mon Sep 17 00:00:00 2001 From: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> Date: Thu, 21 Oct 2021 14:57:14 -0700 Subject: [PATCH] Dump variance to stdout --- src/compiler/checker.ts | 29 ++++++++++++++++++++++++++++- src/compiler/tracing.ts | 8 +++++++- src/compiler/types.ts | 1 + src/compiler/watch.ts | 1 + 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d149b044284..666c05ea0da 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -621,6 +621,7 @@ namespace ts { return tryFindAmbientModule(moduleName, /*withAugmentations*/ false); }, getApparentType, + dumpVariances, getUnionType, isTypeAssignableTo, createAnonymousType, @@ -3980,7 +3981,7 @@ namespace ts { typeCount++; result.id = typeCount; if (produceDiagnostics) { // Only record types from one checker - tracing?.recordType(result); + tracingEnabled.recordType(result); } return result; } @@ -20188,6 +20189,24 @@ namespace ts { return variances; } + + function getVariancesUltra(type: GenericType, refid: number): { variances: string[], how: 'static' | 'check' | 'dump', refid: number, targetid: number } { + // Arrays and tuples are known to be covariant, no need to spend time computing this. + if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { + return { variances: arrayVariances.map(translateEnum), how: 'static', targetid: type.id, refid }; + } + return { + how: type.variances ? 'check' : 'dump', + variances: getVariancesWorker(type.typeParameters, type, getMarkerTypeReference).map(translateEnum), + targetid: type.id, + refid, + } + } + + function translateEnum(flag: VarianceFlags): string { + return flag.toString() // laters! (once I find out the distribution) + } + function getVariances(type: GenericType): VarianceFlags[] { // Arrays and tuples are known to be covariant, no need to spend time computing this. if (type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) { @@ -40282,6 +40301,14 @@ namespace ts { return diagnostics.getDiagnostics(); } + function dumpVariances() { + tracingEnabled.iterTypes(t => { + if (getObjectFlags(t) & ObjectFlags.Reference) { + console.log(JSON.stringify(getVariancesUltra((t as TypeReference).target, t.id))) + } + }) + } + function getGlobalDiagnostics(): Diagnostic[] { throwIfNonDiagnosticsProducing(); return diagnostics.getGlobalDiagnostics(); diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 31c1c8910cf..8fe980f2e4e 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -7,7 +7,7 @@ namespace ts { // eslint-disable-line one-namespace-per-file // enable the above using startTracing() // `tracingEnabled` should never be used directly, only through the above - namespace tracingEnabled { // eslint-disable-line one-namespace-per-file + export namespace tracingEnabled { // eslint-disable-line one-namespace-per-file type Mode = "project" | "build" | "server"; let fs: typeof import("fs"); @@ -103,6 +103,12 @@ namespace ts { // eslint-disable-line one-namespace-per-file } } + export function iterTypes(action: (t: Type) => void): void { + for (const t of typeCatalog) { + action(t) + } + } + export const enum Phase { Parse = "parse", Program = "program", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 6c7cb7b5187..25a7d586b46 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -4152,6 +4152,7 @@ namespace ts { } export interface TypeChecker { + dumpVariances(): void; getTypeOfSymbolAtLocation(symbol: Symbol, node: Node): Type; getDeclaredTypeOfSymbol(symbol: Symbol): Type; getPropertiesOfType(type: Type): Symbol[]; diff --git a/src/compiler/watch.ts b/src/compiler/watch.ts index 71853f4f34b..e473ef7a652 100644 --- a/src/compiler/watch.ts +++ b/src/compiler/watch.ts @@ -327,6 +327,7 @@ namespace ts { if (allDiagnostics.length === configFileParsingDiagnosticsLength) { addRange(allDiagnostics, program.getSemanticDiagnostics(/*sourceFile*/ undefined, cancellationToken)); + (program as Program).getTypeChecker().dumpVariances(); } } }