1
1
/* @internal */
2
2
namespace ts {
3
+ function ternaryToString(ret: Ternary) {
4
+ return ret === Ternary.True
5
+ ? "True"
6
+ : ret === Ternary.False
7
+ ? "False"
8
+ : ret === Ternary.Maybe
9
+ ? "Maybe"
10
+ : "Error";
11
+ }
12
+
3
13
const ambientModuleSymbolRegex = /^".+"$/;
4
14
5
15
let nextSymbolId = 1;
@@ -44,6 +54,52 @@ namespace ts {
44
54
let requestedExternalEmitHelpers: ExternalEmitHelpers;
45
55
let externalHelpersModule: Symbol;
46
56
57
+ // @ts-ignore
58
+ const logEnable = process.env.CALL_TREE && process.env.CALL_TREE.match(/full_steam/gi);
59
+ const excludes = (process.env.CALL_TREE || "").split("-").slice(1);
60
+
61
+ // Log stuff
62
+ let level = 0;
63
+ let currentFnNames: string[] = [];
64
+ const log = (...args: any[]) => {
65
+ const fnName = currentFnNames[currentFnNames.length-1]
66
+ // @ts-ignore
67
+ if (logEnable && !excludes.includes(fnName)) {
68
+ // @ts-ignore
69
+ console.log(" → ".repeat(level) + args.join(" "));
70
+ }
71
+ };
72
+
73
+ const callsToBreakOn = ["propertiesRelatedTo(C<T>,A,true)"];
74
+
75
+ const wrapLogCustom = <M extends any[], T>(printArgs: (...args: M) => string, printRet: (ret: T) => string) => {
76
+ return (fn: (...args: M) => T) => {
77
+ const functionName = fn.name;
78
+ return (...args: M) => {
79
+ const fnCallString = `${functionName}(${printArgs(...args)})`;
80
+ currentFnNames.push(functionName);
81
+ log(`${fnCallString}`);
82
+ level += 1;
83
+ if (callsToBreakOn.indexOf(fnCallString) !== -1) {
84
+ debugger;
85
+ }
86
+ const ret = fn(...args);
87
+ level -= 1;
88
+ log(`${fnCallString} = ${printRet(ret)}`);
89
+ currentFnNames.pop();
90
+ return ret;
91
+ };
92
+ };
93
+ };
94
+
95
+ const wrapLogUsual = wrapLogCustom(
96
+ (type: Type, ...args: any[]) => `${typeToString(type)}${args.length > 0 ? "," + args.join(",") : ""}`,
97
+ (ret: Type | undefined) => `${ret && typeToString(ret)}`
98
+ );
99
+ const wrapLog = <M extends any[], A extends Type | undefined>(fn: (type: Type, ...args: M) => A): (type: Type, ...args: M) => A => {
100
+ return wrapLogUsual(fn as any) as any;
101
+ };
102
+
47
103
// tslint:disable variable-name
48
104
const Symbol = objectAllocator.getSymbolConstructor();
49
105
const Type = objectAllocator.getTypeConstructor();
@@ -81,6 +137,29 @@ namespace ts {
81
137
/** This will be set during calls to `getResolvedSignature` where services determines an apparent number of arguments greater than what is actually provided. */
82
138
let apparentArgumentCount: number | undefined;
83
139
140
+ // @ts-ignore
141
+ getBaseConstraintOfType = wrapLog(getBaseConstraintOfType)
142
+ // @ts-ignore
143
+ getConstraintOfType = wrapLog(getConstraintOfType)
144
+ // @ts-ignore
145
+ getConstraintOfDistributiveConditionalType = wrapLog(getConstraintOfDistributiveConditionalType)
146
+ // @ts-ignore
147
+ getResolvedBaseConstraint = wrapLog(getResolvedBaseConstraint)
148
+
149
+ const wrapIsDeeplyNestedType = wrapLogCustom(
150
+ (type: Type) => `${typeToString(type)}`,
151
+ (ret: boolean) => `${ret}`
152
+ )
153
+ // @ts-ignore
154
+ isDeeplyNestedType = wrapIsDeeplyNestedType(isDeeplyNestedType)
155
+
156
+ const wrapCheckTypeRelatedTo = wrapLogCustom(
157
+ (source: Type, target: Type, ..._rest: any[]) => `${typeToString(source)}, ${typeToString(target)}`,
158
+ (ret: boolean) => ret ? "true" : "false"
159
+ );
160
+ // @ts-ignore
161
+ checkTypeRelatedTo = wrapCheckTypeRelatedTo(checkTypeRelatedTo)
162
+
84
163
// for public members that accept a Node or one of its subtypes, we must guard against
85
164
// synthetic nodes created during transformations by calling `getParseTreeNode`.
86
165
// for most of these, we perform the guard only on `checker` to avoid any possible
@@ -3035,7 +3114,11 @@ namespace ts {
3035
3114
if (maxLength && result && result.length >= maxLength) {
3036
3115
return result.substr(0, maxLength - "...".length) + "...";
3037
3116
}
3038
- return result;
3117
+ function toZeroOne(str: "Z" | "O") { return str === "O" ? 1 : 0 }
3118
+ return result.replace(
3119
+ /(Z|O), (Z|O), (Z|O), (Z|O)/gi,
3120
+ (_a: any, ...match: any[]) => `${toZeroOne(match[0])*1 + toZeroOne(match[1])*2 + toZeroOne(match[2])*4 + toZeroOne(match[3])*8}`
3121
+ );
3039
3122
}
3040
3123
3041
3124
function toNodeBuilderFlags(flags = TypeFormatFlags.None): NodeBuilderFlags {
@@ -6921,12 +7004,14 @@ namespace ts {
6921
7004
// over the conditional type and possibly reduced. For example, 'T extends undefined ? never : T'
6922
7005
// removes 'undefined' from T.
6923
7006
if (type.root.isDistributive) {
7007
+ log(`ConditionalType ${typeToString(type)} isDistributive`);
6924
7008
const simplified = getSimplifiedType(type.checkType);
6925
7009
const constraint = simplified === type.checkType ? getConstraintOfType(simplified) : simplified;
6926
7010
if (constraint) {
6927
7011
const mapper = makeUnaryTypeMapper(type.root.checkType, constraint);
6928
7012
const instantiated = getConditionalTypeInstantiation(type, combineTypeMappers(mapper, type.mapper));
6929
7013
if (!(instantiated.flags & TypeFlags.Never)) {
7014
+ log(`getConditionalTypeInstantiation(${typeToString(type)}, combineTypeMappers(makeUnaryTypeMapper(${typeToString(type.root.checkType)}, ${typeToString(constraint)}), type.mapper)) = ${typeToString(instantiated)}`);
6930
7015
return instantiated;
6931
7016
}
6932
7017
}
@@ -6981,9 +7066,11 @@ namespace ts {
6981
7066
6982
7067
function getBaseConstraintOfType(type: Type): Type | undefined {
6983
7068
if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection)) {
7069
+ log(`(getResolvedBaseConstraint/undefined path)`);
6984
7070
const constraint = getResolvedBaseConstraint(<InstantiableType | UnionOrIntersectionType>type);
6985
7071
return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined;
6986
7072
}
7073
+ log(`(keyofConstraintType/undefined path)`);
6987
7074
return type.flags & TypeFlags.Index ? keyofConstraintType : undefined;
6988
7075
}
6989
7076
@@ -7005,6 +7092,13 @@ namespace ts {
7005
7092
* circularly references the type variable.
7006
7093
*/
7007
7094
function getResolvedBaseConstraint(type: InstantiableType | UnionOrIntersectionType): Type {
7095
+ // @ts-ignore
7096
+ getImmediateBaseConstraint = wrapLog(getImmediateBaseConstraint)
7097
+ // @ts-ignore
7098
+ getBaseConstraint = wrapLog(getBaseConstraint)
7099
+ // @ts-ignore
7100
+ computeBaseConstraint = wrapLog(computeBaseConstraint)
7101
+
7008
7102
let nonTerminating = false;
7009
7103
return type.resolvedBaseConstraint ||
7010
7104
(type.resolvedBaseConstraint = getTypeWithThisArgument(getImmediateBaseConstraint(type), type));
@@ -7045,11 +7139,18 @@ namespace ts {
7045
7139
constraint :
7046
7140
getBaseConstraint(constraint);
7047
7141
}
7142
+ const UNIA = TypeFlags.Union;
7143
+ const INTERSECTIA = TypeFlags.Intersection;
7048
7144
if (t.flags & TypeFlags.UnionOrIntersection) {
7145
+ if (typeToString(t) === "any[] & T") {
7146
+ log(UNIA + " " + INTERSECTIA);
7147
+ debugger;
7148
+ }
7049
7149
const types = (<UnionOrIntersectionType>t).types;
7050
7150
const baseTypes: Type[] = [];
7051
7151
for (const type of types) {
7052
7152
const baseType = getBaseConstraint(type);
7153
+ log(`getBaseConstraint(${typeToString(type)}) = ${baseType && typeToString(baseType)}`);
7053
7154
if (baseType) {
7054
7155
baseTypes.push(baseType);
7055
7156
}
@@ -11002,6 +11103,27 @@ namespace ts {
11002
11103
errorOutputContainer?: { error?: Diagnostic }
11003
11104
): boolean {
11004
11105
11106
+ const wrapIsRelatedTo = wrapLogCustom(
11107
+ (source: Type, target: Type, ..._rest: any[]) => `${typeToString(source)},${typeToString(target)}`,
11108
+ ternaryToString
11109
+ );
11110
+ // @ts-ignore
11111
+ isRelatedTo = wrapIsRelatedTo(isRelatedTo)
11112
+
11113
+ const wrapStructuredTypeRelatedTo = wrapLogCustom(
11114
+ (source: Type, target: Type, reportErrors: boolean) => `${typeToString(source)},${typeToString(target)},${reportErrors}`,
11115
+ ternaryToString
11116
+ );
11117
+ // @ts-ignore
11118
+ structuredTypeRelatedTo = wrapStructuredTypeRelatedTo(structuredTypeRelatedTo)
11119
+
11120
+ const wrapPropertiesRelatedTo = wrapLogCustom(
11121
+ (source: Type, target: Type, reportErrors: boolean) => `${typeToString(source)},${typeToString(target)},${reportErrors}`,
11122
+ ternaryToString
11123
+ );
11124
+ // @ts-ignore
11125
+ propertiesRelatedTo = wrapPropertiesRelatedTo(propertiesRelatedTo)
11126
+
11005
11127
let errorInfo: DiagnosticMessageChain | undefined;
11006
11128
let maybeKeys: string[];
11007
11129
let sourceStack: Type[];
@@ -11114,6 +11236,26 @@ namespace ts {
11114
11236
* * Ternary.False if they are not related.
11115
11237
*/
11116
11238
function isRelatedTo(source: Type, target: Type, reportErrors = false, headMessage?: DiagnosticMessage): Ternary {
11239
+ const relationType =
11240
+ relation === assignableRelation
11241
+ ? "assignable"
11242
+ : relation === identityRelation
11243
+ ? "identical"
11244
+ : relation === comparableRelation
11245
+ ? "comparable"
11246
+ : relation === definitelyAssignableRelation
11247
+ ? "definitely assignable"
11248
+ : relation === subtypeRelation
11249
+ ? "subtype"
11250
+ : relation === enumRelation
11251
+ ? "enum"
11252
+ : "unknown relation";
11253
+ log(relationType + ": " + typeToString(source) + " -> " + typeToString(target));
11254
+ // @ts-ignore
11255
+ if (process.env.BREAK_ON && typeToString(source) === process.env.BREAK_ON) {
11256
+ debugger;
11257
+ }
11258
+
11117
11259
if (source.flags & TypeFlags.StringOrNumberLiteral && source.flags & TypeFlags.FreshLiteral) {
11118
11260
source = (<LiteralType>source).regularType;
11119
11261
}
@@ -11749,13 +11891,19 @@ namespace ts {
11749
11891
}
11750
11892
else if (relation !== definitelyAssignableRelation) {
11751
11893
const distributiveConstraint = getConstraintOfDistributiveConditionalType(<ConditionalType>source);
11894
+ const defaultConstraint = getDefaultConstraintOfConditionalType(<ConditionalType>source);
11895
+
11896
+ log("distributive constraint of", typeToString(source), "is", distributiveConstraint && typeToString(distributiveConstraint));
11897
+ log("default constraint of", typeToString(source), "is", defaultConstraint && typeToString(defaultConstraint));
11898
+
11752
11899
if (distributiveConstraint) {
11900
+ log("distributive constraint of", typeToString(source), "is", typeToString(distributiveConstraint));
11753
11901
if (result = isRelatedTo(distributiveConstraint, target, reportErrors)) {
11754
11902
errorInfo = saveErrorInfo;
11755
11903
return result;
11756
11904
}
11757
11905
}
11758
- const defaultConstraint = getDefaultConstraintOfConditionalType(<ConditionalType>source);
11906
+
11759
11907
if (defaultConstraint) {
11760
11908
if (result = isRelatedTo(defaultConstraint, target, reportErrors)) {
11761
11909
errorInfo = saveErrorInfo;
@@ -11923,6 +12071,7 @@ namespace ts {
11923
12071
const properties = getPropertiesOfObjectType(target);
11924
12072
for (const targetProp of properties) {
11925
12073
if (!(targetProp.flags & SymbolFlags.Prototype)) {
12074
+ log(`Verifying: `, targetProp.escapedName)
11926
12075
const sourceProp = getPropertyOfType(source, targetProp.escapedName);
11927
12076
if (sourceProp && sourceProp !== targetProp) {
11928
12077
if (isIgnoredJsxProperty(source, sourceProp, getTypeOfSymbol(targetProp))) {
@@ -12443,6 +12592,7 @@ namespace ts {
12443
12592
if (count >= 5) return true;
12444
12593
}
12445
12594
}
12595
+ log(`nesting depth ${typeToString(type)}: ${count}`);
12446
12596
}
12447
12597
}
12448
12598
return false;
0 commit comments