Skip to content

Commit

Permalink
More optimizing
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Feb 8, 2022
1 parent 1c69acb commit 530c876
Showing 1 changed file with 38 additions and 38 deletions.
76 changes: 38 additions & 38 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
@@ -17929,13 +17929,13 @@ namespace ts {
let overflow = false;
let overrideNextErrorInfo = 0; // How many `reportRelationError` calls should be skipped in the elaboration pyramid
let lastSkippedInfo: [Type, Type] | undefined;
let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = [];
let incompatibleStack: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] | undefined;
let inPropertyCheck = false;

Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");

const result = isRelatedTo(source, target, RecursionFlags.Both, /*reportErrors*/ !!errorNode, headMessage);
if (incompatibleStack.length) {
if (incompatibleStack) {
reportIncompatibleStack();
}
if (overflow) {
@@ -17997,21 +17997,21 @@ namespace ts {
return {
errorInfo,
lastSkippedInfo,
incompatibleStack: incompatibleStack.slice(),
incompatibleStack: incompatibleStack ? incompatibleStack.slice() : undefined,
overrideNextErrorInfo,
relatedInfo: !relatedInfo ? undefined : relatedInfo.slice() as ([DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined)
relatedInfo: relatedInfo ? relatedInfo.slice() as [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] : undefined,
};
}

function reportIncompatibleError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number) {
overrideNextErrorInfo++; // Suppress the next relation error
lastSkippedInfo = undefined; // Reset skipped info cache
incompatibleStack.push([message, arg0, arg1, arg2, arg3]);
(incompatibleStack || (incompatibleStack = [])).push([message, arg0, arg1, arg2, arg3]);
}

function reportIncompatibleStack() {
const stack = incompatibleStack;
incompatibleStack = [];
const stack = incompatibleStack || [];
incompatibleStack = undefined;
const info = lastSkippedInfo;
lastSkippedInfo = undefined;
if (stack.length === 1) {
@@ -18025,7 +18025,7 @@ namespace ts {
// The first error will be the innermost, while the last will be the outermost - so by popping off the end,
// we can build from left to right
let path = "";
const secondaryRootErrors: typeof incompatibleStack = [];
const secondaryRootErrors: [DiagnosticMessage, (string | number)?, (string | number)?, (string | number)?, (string | number)?][] = [];
while (stack.length) {
const [msg, ...args] = stack.pop()!;
switch (msg.code) {
@@ -18119,7 +18119,7 @@ namespace ts {

function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
Debug.assert(!!errorNode);
if (incompatibleStack.length) reportIncompatibleStack();
if (incompatibleStack) reportIncompatibleStack();
if (message.elidedInCompatabilityPyramid) return;
errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2, arg3);
}
@@ -18135,7 +18135,7 @@ namespace ts {
}

function reportRelationError(message: DiagnosticMessage | undefined, source: Type, target: Type) {
if (incompatibleStack.length) reportIncompatibleStack();
if (incompatibleStack) reportIncompatibleStack();
const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target);
let generalizedSource = source;
let generalizedSourceType = sourceType;
@@ -18308,41 +18308,41 @@ namespace ts {
if (relation === comparableRelation && !(target.flags & TypeFlags.Never) && isSimpleTypeRelatedTo(target, source, relation) ||
isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) return Ternary.True;

const isPerformingExcessPropertyChecks = !(intersectionState & IntersectionState.Target) && (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral);
if (isPerformingExcessPropertyChecks) {
if (hasExcessProperties(source as FreshObjectLiteralType, target, reportErrors)) {
if (reportErrors) {
reportRelationError(headMessage, source, originalTarget.aliasSymbol ? originalTarget : target);
if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) {
const isPerformingExcessPropertyChecks = !(intersectionState & IntersectionState.Target) && (isObjectLiteralType(source) && getObjectFlags(source) & ObjectFlags.FreshLiteral);
if (isPerformingExcessPropertyChecks) {
if (hasExcessProperties(source as FreshObjectLiteralType, target, reportErrors)) {
if (reportErrors) {
reportRelationError(headMessage, source, originalTarget.aliasSymbol ? originalTarget : target);
}
return Ternary.False;
}
return Ternary.False;
}
}

const isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & IntersectionState.Target) &&
source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType &&
target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) &&
(getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source));
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
if (isPerformingCommonPropertyChecks && !hasCommonProperties(source, target, isComparingJsxAttributes)) {
if (reportErrors) {
const sourceString = typeToString(originalSource.aliasSymbol ? originalSource : source);
const targetString = typeToString(originalTarget.aliasSymbol ? originalTarget : target);
const calls = getSignaturesOfType(source, SignatureKind.Call);
const constructs = getSignaturesOfType(source, SignatureKind.Construct);
if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, RecursionFlags.Source, /*reportErrors*/ false) ||
constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, RecursionFlags.Source, /*reportErrors*/ false)) {
reportError(Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString);
}
else {
reportError(Diagnostics.Type_0_has_no_properties_in_common_with_type_1, sourceString, targetString);
const isPerformingCommonPropertyChecks = relation !== comparableRelation && !(intersectionState & IntersectionState.Target) &&
source.flags & (TypeFlags.Primitive | TypeFlags.Object | TypeFlags.Intersection) && source !== globalObjectType &&
target.flags & (TypeFlags.Object | TypeFlags.Intersection) && isWeakType(target) &&
(getPropertiesOfType(source).length > 0 || typeHasCallOrConstructSignatures(source));
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
if (isPerformingCommonPropertyChecks && !hasCommonProperties(source, target, isComparingJsxAttributes)) {
if (reportErrors) {
const sourceString = typeToString(originalSource.aliasSymbol ? originalSource : source);
const targetString = typeToString(originalTarget.aliasSymbol ? originalTarget : target);
const calls = getSignaturesOfType(source, SignatureKind.Call);
const constructs = getSignaturesOfType(source, SignatureKind.Construct);
if (calls.length > 0 && isRelatedTo(getReturnTypeOfSignature(calls[0]), target, RecursionFlags.Source, /*reportErrors*/ false) ||
constructs.length > 0 && isRelatedTo(getReturnTypeOfSignature(constructs[0]), target, RecursionFlags.Source, /*reportErrors*/ false)) {
reportError(Diagnostics.Value_of_type_0_has_no_properties_in_common_with_type_1_Did_you_mean_to_call_it, sourceString, targetString);
}
else {
reportError(Diagnostics.Type_0_has_no_properties_in_common_with_type_1, sourceString, targetString);
}
}
return Ternary.False;
}
return Ternary.False;
}

traceUnionsOrIntersectionsTooLarge(source, target);
traceUnionsOrIntersectionsTooLarge(source, target);

if (source.flags & TypeFlags.StructuredOrInstantiable || target.flags & TypeFlags.StructuredOrInstantiable) {
const skipCaching = source.flags & TypeFlags.Union && (source as UnionType).types.length < 4 && !(target.flags & TypeFlags.Union) ||
target.flags & TypeFlags.Union && (target as UnionType).types.length < 4 && !(source.flags & TypeFlags.StructuredOrInstantiable);
let result = skipCaching ?

0 comments on commit 530c876

Please sign in to comment.