Add variance results to tracing, capture variance verification on annotated type params (#49712)

* Add variance results to tracing

* Tweak format, prohibit `results` on `E` events
This commit is contained in:
Andrew Branch
2022-06-29 16:30:57 -07:00
committed by GitHub
parent bd11ce2aeb
commit 93f2d2b9a1
3 changed files with 25 additions and 5 deletions
+3 -1
View File
@@ -20785,7 +20785,7 @@ namespace ts {
variances.push(variance);
}
links.variances = variances;
tracing?.pop();
tracing?.pop({ variances: variances.map(Debug.formatVariance) });
}
return links.variances;
}
@@ -35055,12 +35055,14 @@ namespace ts {
error(node, Diagnostics.Variance_annotations_are_only_supported_in_type_aliases_for_object_function_constructor_and_mapped_types);
}
else if (modifiers === ModifierFlags.In || modifiers === ModifierFlags.Out) {
tracing?.push(tracing.Phase.CheckTypes, "checkTypeParameterDeferred", { parent: getTypeId(getDeclaredTypeOfSymbol(symbol)), id: getTypeId(typeParameter) });
const source = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSubTypeForCheck : markerSuperTypeForCheck);
const target = createMarkerType(symbol, typeParameter, modifiers === ModifierFlags.Out ? markerSuperTypeForCheck : markerSubTypeForCheck);
const saveVarianceTypeParameter = typeParameter;
varianceTypeParameter = typeParameter;
checkTypeAssignableTo(source, target, node, Diagnostics.Type_0_is_not_assignable_to_type_1_as_implied_by_variance_annotation);
varianceTypeParameter = saveVarianceTypeParameter;
tracing?.pop();
}
}
}
+17
View File
@@ -748,5 +748,22 @@ namespace ts {
const deprecation = createDeprecation(options?.name ?? getFunctionName(func), options);
return wrapFunction(deprecation, func);
}
export function formatVariance(varianceFlags: VarianceFlags) {
const variance = varianceFlags & VarianceFlags.VarianceMask;
let result =
variance === VarianceFlags.Invariant ? "in out" :
variance === VarianceFlags.Bivariant ? "[bivariant]" :
variance === VarianceFlags.Contravariant ? "in" :
variance === VarianceFlags.Covariant ? "out" :
variance === VarianceFlags.Independent ? "[independent]" : "";
if (varianceFlags & VarianceFlags.Unmeasurable) {
result += " (unmeasurable)";
}
else if (varianceFlags & VarianceFlags.Unreliable) {
result += " (unreliable)";
}
return result;
}
}
}
+5 -4
View File
@@ -131,9 +131,9 @@ namespace ts { // eslint-disable-line one-namespace-per-file
}
eventStack.push({ phase, name, args, time: 1000 * timestamp(), separateBeginAndEnd });
}
export function pop() {
export function pop(results?: Args) {
Debug.assert(eventStack.length > 0);
writeStackEvent(eventStack.length - 1, 1000 * timestamp());
writeStackEvent(eventStack.length - 1, 1000 * timestamp(), results);
eventStack.length--;
}
export function popAll() {
@@ -145,14 +145,15 @@ namespace ts { // eslint-disable-line one-namespace-per-file
}
// sample every 10ms
const sampleInterval = 1000 * 10;
function writeStackEvent(index: number, endTime: number) {
function writeStackEvent(index: number, endTime: number, results?: Args) {
const { phase, name, args, time, separateBeginAndEnd } = eventStack[index];
if (separateBeginAndEnd) {
Debug.assert(!results, "`results` are not supported for events with `separateBeginAndEnd`");
writeEvent("E", phase, name, args, /*extras*/ undefined, endTime);
}
// test if [time,endTime) straddles a sampling point
else if (sampleInterval - (time % sampleInterval) <= endTime - time) {
writeEvent("X", phase, name, args, `"dur":${endTime - time}`, time);
writeEvent("X", phase, name, { ...args, results }, `"dur":${endTime - time}`, time);
}
}