mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 01:49:57 -05:00
Back to booleans.
I totally have an infinite amount of time to work on this.
This commit is contained in:
@@ -2,24 +2,6 @@
|
||||
|
||||
/* @internal */
|
||||
namespace ts {
|
||||
const enum ReportErrors {
|
||||
/**
|
||||
* Do not report errors at all.
|
||||
*/
|
||||
None,
|
||||
/**
|
||||
* Report errors in any fashion if any are encountered.
|
||||
* This option implies that if an error has already been cached for a relationship
|
||||
* between two types, it is okay to use the top-level error without elaboration.
|
||||
*/
|
||||
Basic,
|
||||
/**
|
||||
* Always force elaboration when comparing two types,
|
||||
* even if the relation has been cached
|
||||
*/
|
||||
Elaborate,
|
||||
}
|
||||
|
||||
let nextSymbolId = 1;
|
||||
let nextNodeId = 1;
|
||||
let nextMergeId = 1;
|
||||
@@ -4937,7 +4919,7 @@ namespace ts {
|
||||
function isSignatureAssignableTo(source: Signature,
|
||||
target: Signature,
|
||||
ignoreReturnTypes: boolean): boolean {
|
||||
return compareSignaturesRelated(source, target, ignoreReturnTypes, ReportErrors.None, /*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
|
||||
return compareSignaturesRelated(source, target, ignoreReturnTypes, /*reportErrors*/ false, /*errorReporter*/ undefined, compareTypesAssignable) !== Ternary.False;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4946,9 +4928,9 @@ namespace ts {
|
||||
function compareSignaturesRelated(source: Signature,
|
||||
target: Signature,
|
||||
ignoreReturnTypes: boolean,
|
||||
reportErrors: ReportErrors,
|
||||
reportErrors: boolean,
|
||||
errorReporter: (d: DiagnosticMessage, arg0?: string, arg1?: string) => void,
|
||||
compareTypes: (s: Type, t: Type, reportErrors?: ReportErrors) => Ternary): Ternary {
|
||||
compareTypes: (s: Type, t: Type, reportErrors?: boolean) => Ternary): Ternary {
|
||||
// TODO (drosen): De-duplicate code between related functions.
|
||||
if (source === target) {
|
||||
return Ternary.True;
|
||||
@@ -4972,7 +4954,7 @@ namespace ts {
|
||||
for (let i = 0; i < checkCount; i++) {
|
||||
const s = i < sourceMax ? getTypeOfSymbol(sourceParams[i]) : getRestTypeOfSignature(source);
|
||||
const t = i < targetMax ? getTypeOfSymbol(targetParams[i]) : getRestTypeOfSignature(target);
|
||||
const related = compareTypes(t, s, /*reportErrors*/ ReportErrors.None) || compareTypes(s, t, reportErrors);
|
||||
const related = compareTypes(t, s, /*reportErrors*/ false) || compareTypes(s, t, reportErrors);
|
||||
if (!related) {
|
||||
if (reportErrors) {
|
||||
errorReporter(Diagnostics.Types_of_parameters_0_and_1_are_incompatible,
|
||||
@@ -5078,19 +5060,11 @@ namespace ts {
|
||||
|
||||
Debug.assert(relation !== identityRelation || !errorNode, "no error reporting in identity checking");
|
||||
|
||||
const result = isRelatedTo(source, target, !!errorNode ? ReportErrors.Basic : ReportErrors.None, headMessage);
|
||||
const result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage);
|
||||
if (overflow) {
|
||||
error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target));
|
||||
}
|
||||
else if (errorInfo) {
|
||||
// If we already computed this relation, but in a context where we didn't want to report errors (e.g. overload resolution),
|
||||
// then we'll only have a top-level error (e.g. 'Class X does not implement interface Y') without any details. If this happened,
|
||||
// request a recompuation to get a complete error message. This will be skipped if we've already done this computation in a context
|
||||
// where errors were being reported.
|
||||
if (errorInfo.next === undefined) {
|
||||
errorInfo = undefined;
|
||||
isRelatedTo(source, target, !!errorNode ? ReportErrors.Elaborate : ReportErrors.None, headMessage);
|
||||
}
|
||||
if (containingMessageChain) {
|
||||
errorInfo = concatenateDiagnosticMessageChains(containingMessageChain, errorInfo);
|
||||
}
|
||||
@@ -5118,7 +5092,7 @@ namespace ts {
|
||||
// Ternary.True if they are related with no assumptions,
|
||||
// Ternary.Maybe if they are related with assumptions of other relationships, or
|
||||
// Ternary.False if they are not related.
|
||||
function isRelatedTo(source: Type, target: Type, reportErrors?: ReportErrors, headMessage?: DiagnosticMessage): Ternary {
|
||||
function isRelatedTo(source: Type, target: Type, reportErrors?: boolean, headMessage?: DiagnosticMessage): Ternary {
|
||||
let result: Ternary;
|
||||
// both types are the same - covers 'they are the same primitive type or both are Any' or the same type parameter cases
|
||||
if (source === target) return Ternary.True;
|
||||
@@ -5206,7 +5180,7 @@ namespace ts {
|
||||
// A & B = (A & B) | (C & D).
|
||||
if (source.flags & TypeFlags.Intersection) {
|
||||
// If target is a union type the following check will report errors so we suppress them here
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, !(target.flags & TypeFlags.Union) ? reportErrors : ReportErrors.None)) {
|
||||
if (result = someTypeRelatedToType(<IntersectionType>source, target, reportErrors && !(target.flags & TypeFlags.Union))) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -5223,7 +5197,7 @@ namespace ts {
|
||||
constraint = emptyObjectType;
|
||||
}
|
||||
// Report constraint errors only if the constraint is not the empty object type
|
||||
const reportConstraintErrors = constraint !== emptyObjectType ? reportErrors : ReportErrors.None;
|
||||
const reportConstraintErrors = reportErrors && constraint !== emptyObjectType;
|
||||
if (result = isRelatedTo(constraint, target, reportConstraintErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
@@ -5244,9 +5218,7 @@ namespace ts {
|
||||
// relates to X. Thus, we include intersection types on the source side here.
|
||||
if (apparentSource.flags & (TypeFlags.ObjectType | TypeFlags.Intersection) && target.flags & TypeFlags.ObjectType) {
|
||||
// Report structural errors only if we haven't reported any errors yet
|
||||
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive)
|
||||
? ReportErrors.Elaborate
|
||||
: ReportErrors.None;
|
||||
const reportStructuralErrors = reportErrors && errorInfo === saveErrorInfo && !(source.flags & TypeFlags.Primitive);
|
||||
if (result = objectTypeRelatedTo(apparentSource, source, target, reportStructuralErrors)) {
|
||||
errorInfo = saveErrorInfo;
|
||||
return result;
|
||||
@@ -5265,11 +5237,11 @@ namespace ts {
|
||||
if (source.flags & TypeFlags.ObjectType && target.flags & TypeFlags.ObjectType) {
|
||||
if (source.flags & TypeFlags.Reference && target.flags & TypeFlags.Reference && (<TypeReference>source).target === (<TypeReference>target).target) {
|
||||
// We have type references to same target type, see if all type arguments are identical
|
||||
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>target, ReportErrors.None)) {
|
||||
if (result = typeArgumentsRelatedTo(<TypeReference>source, <TypeReference>target, /*reportErrors*/ false)) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return objectTypeRelatedTo(source, source, target, ReportErrors.None);
|
||||
return objectTypeRelatedTo(source, source, target, /*reportErrors*/ false);
|
||||
}
|
||||
if (source.flags & TypeFlags.Union && target.flags & TypeFlags.Union ||
|
||||
source.flags & TypeFlags.Intersection && target.flags & TypeFlags.Intersection) {
|
||||
@@ -5304,7 +5276,7 @@ namespace ts {
|
||||
return false;
|
||||
}
|
||||
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: ReportErrors): boolean {
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
|
||||
if (!(target.flags & TypeFlags.ObjectLiteralPatternWithComputedProperties) && someConstituentTypeHasKind(target, TypeFlags.ObjectType)) {
|
||||
for (const prop of getPropertiesOfObjectType(source)) {
|
||||
if (!isKnownProperty(target, prop.name)) {
|
||||
@@ -5328,7 +5300,7 @@ namespace ts {
|
||||
let result = Ternary.True;
|
||||
const sourceTypes = source.types;
|
||||
for (const sourceType of sourceTypes) {
|
||||
const related = typeRelatedToSomeType(sourceType, target, ReportErrors.None);
|
||||
const related = typeRelatedToSomeType(sourceType, target, /*reportErrors*/ false);
|
||||
if (!related) {
|
||||
return Ternary.False;
|
||||
}
|
||||
@@ -5337,10 +5309,10 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: ReportErrors): Ternary {
|
||||
function typeRelatedToSomeType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
|
||||
const targetTypes = target.types;
|
||||
for (let i = 0, len = targetTypes.length; i < len; i++) {
|
||||
const related = isRelatedTo(source, targetTypes[i], i === len - 1 ? reportErrors : ReportErrors.None);
|
||||
const related = isRelatedTo(source, targetTypes[i], reportErrors && i === len - 1);
|
||||
if (related) {
|
||||
return related;
|
||||
}
|
||||
@@ -5348,7 +5320,7 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function typeRelatedToEachType(source: Type, target: UnionOrIntersectionType, reportErrors: ReportErrors): Ternary {
|
||||
function typeRelatedToEachType(source: Type, target: UnionOrIntersectionType, reportErrors: boolean): Ternary {
|
||||
let result = Ternary.True;
|
||||
const targetTypes = target.types;
|
||||
for (const targetType of targetTypes) {
|
||||
@@ -5361,10 +5333,10 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function someTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function someTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean): Ternary {
|
||||
const sourceTypes = source.types;
|
||||
for (let i = 0, len = sourceTypes.length; i < len; i++) {
|
||||
const related = isRelatedTo(sourceTypes[i], target, i === len - 1 ? reportErrors : ReportErrors.None);
|
||||
const related = isRelatedTo(sourceTypes[i], target, reportErrors && i === len - 1);
|
||||
if (related) {
|
||||
return related;
|
||||
}
|
||||
@@ -5372,7 +5344,7 @@ namespace ts {
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
function eachTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function eachTypeRelatedToType(source: UnionOrIntersectionType, target: Type, reportErrors: boolean): Ternary {
|
||||
let result = Ternary.True;
|
||||
const sourceTypes = source.types;
|
||||
for (const sourceType of sourceTypes) {
|
||||
@@ -5385,7 +5357,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function typeArgumentsRelatedTo(source: TypeReference, target: TypeReference, reportErrors: ReportErrors): Ternary {
|
||||
function typeArgumentsRelatedTo(source: TypeReference, target: TypeReference, reportErrors: boolean): Ternary {
|
||||
const sources = source.typeArguments || emptyArray;
|
||||
const targets = target.typeArguments || emptyArray;
|
||||
if (sources.length !== targets.length && relation === identityRelation) {
|
||||
@@ -5408,14 +5380,14 @@ namespace ts {
|
||||
// Third, check if both types are part of deeply nested chains of generic type instantiations and if so assume the types are
|
||||
// equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion
|
||||
// and issue an error. Otherwise, actually compare the structure of the two types.
|
||||
function objectTypeRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function objectTypeRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
|
||||
if (overflow) {
|
||||
return Ternary.False;
|
||||
}
|
||||
const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
|
||||
const related = relation[id];
|
||||
if (related !== undefined) {
|
||||
if (reportErrors === ReportErrors.Elaborate && related === RelationComparisonResult.Failed) {
|
||||
if (reportErrors && related === RelationComparisonResult.Failed) {
|
||||
// We are elaborating errors and the cached result is an unreported failure. Record the result as a reported
|
||||
// failure and continue computing the relation such that errors get reported.
|
||||
relation[id] = RelationComparisonResult.FailedAndReported;
|
||||
@@ -5485,7 +5457,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function propertiesRelatedTo(source: Type, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function propertiesRelatedTo(source: Type, target: Type, reportErrors: boolean): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return propertiesIdenticalTo(source, target);
|
||||
}
|
||||
@@ -5593,7 +5565,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function signaturesRelatedTo(source: Type, target: Type, kind: SignatureKind, reportErrors: ReportErrors): Ternary {
|
||||
function signaturesRelatedTo(source: Type, target: Type, kind: SignatureKind, reportErrors: boolean): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return signaturesIdenticalTo(source, target, kind);
|
||||
}
|
||||
@@ -5630,7 +5602,7 @@ namespace ts {
|
||||
errorInfo = saveErrorInfo;
|
||||
continue outer;
|
||||
}
|
||||
shouldElaborateErrors = ReportErrors.None;
|
||||
shouldElaborateErrors = false;
|
||||
}
|
||||
}
|
||||
// don't elaborate the primitive apparent types (like Number)
|
||||
@@ -5649,7 +5621,7 @@ namespace ts {
|
||||
/**
|
||||
* See signatureAssignableTo, compareSignaturesIdentical
|
||||
*/
|
||||
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: ReportErrors): Ternary {
|
||||
function signatureRelatedTo(source: Signature, target: Signature, reportErrors: boolean): Ternary {
|
||||
return compareSignaturesRelated(source, target, /*ignoreReturnTypes*/ false, reportErrors, reportError, isRelatedTo);
|
||||
}
|
||||
|
||||
@@ -5670,7 +5642,7 @@ namespace ts {
|
||||
return result;
|
||||
}
|
||||
|
||||
function stringIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function stringIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return indexTypesIdenticalTo(IndexKind.String, source, target);
|
||||
}
|
||||
@@ -5700,7 +5672,7 @@ namespace ts {
|
||||
return Ternary.True;
|
||||
}
|
||||
|
||||
function numberIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: ReportErrors): Ternary {
|
||||
function numberIndexTypesRelatedTo(source: Type, originalSource: Type, target: Type, reportErrors: boolean): Ternary {
|
||||
if (relation === identityRelation) {
|
||||
return indexTypesIdenticalTo(IndexKind.Number, source, target);
|
||||
}
|
||||
@@ -5722,7 +5694,7 @@ namespace ts {
|
||||
let related: Ternary;
|
||||
if (sourceStringType && sourceNumberType) {
|
||||
// If we know for sure we're testing both string and numeric index types then only report errors from the second one
|
||||
related = isRelatedTo(sourceStringType, targetType, ReportErrors.None) || isRelatedTo(sourceNumberType, targetType, reportErrors);
|
||||
related = isRelatedTo(sourceStringType, targetType, /*reportErrors*/ false) || isRelatedTo(sourceNumberType, targetType, reportErrors);
|
||||
}
|
||||
else {
|
||||
related = isRelatedTo(sourceStringType || sourceNumberType, targetType, reportErrors);
|
||||
@@ -9003,7 +8975,7 @@ namespace ts {
|
||||
getInferredTypes(context);
|
||||
}
|
||||
|
||||
function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: ReportErrors, headMessage?: DiagnosticMessage): boolean {
|
||||
function checkTypeArguments(signature: Signature, typeArgumentNodes: TypeNode[], typeArgumentTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean {
|
||||
const typeParameters = signature.typeParameters;
|
||||
let typeArgumentsAreAssignable = true;
|
||||
let mapper: TypeMapper;
|
||||
@@ -9033,7 +9005,7 @@ namespace ts {
|
||||
return typeArgumentsAreAssignable;
|
||||
}
|
||||
|
||||
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: ReportErrors) {
|
||||
function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map<RelationComparisonResult>, excludeArgument: boolean[], reportErrors: boolean) {
|
||||
const argCount = getEffectiveArgumentCount(node, args, signature);
|
||||
for (let i = 0; i < argCount; i++) {
|
||||
const arg = getEffectiveArgument(node, args, i);
|
||||
@@ -9481,12 +9453,12 @@ namespace ts {
|
||||
// in arguments too early. If possible, we'd like to only type them once we know the correct
|
||||
// overload. However, this matters for the case where the call is correct. When the call is
|
||||
// an error, we don't need to exclude any arguments, although it would cause no harm to do so.
|
||||
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, ReportErrors.Basic);
|
||||
checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true);
|
||||
}
|
||||
else if (candidateForTypeArgumentError) {
|
||||
if (!isTaggedTemplate && !isDecorator && typeArguments) {
|
||||
const typeArguments = (<CallExpression>node).typeArguments;
|
||||
checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), ReportErrors.Basic, headMessage);
|
||||
checkTypeArguments(candidateForTypeArgumentError, typeArguments, map(typeArguments, getTypeFromTypeNode), /*reportErrors*/ true, headMessage);
|
||||
}
|
||||
else {
|
||||
Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0);
|
||||
@@ -9554,7 +9526,7 @@ namespace ts {
|
||||
let typeArgumentTypes: Type[];
|
||||
if (typeArguments) {
|
||||
typeArgumentTypes = map(typeArguments, getTypeFromTypeNode);
|
||||
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, ReportErrors.None);
|
||||
typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false);
|
||||
}
|
||||
else {
|
||||
inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext);
|
||||
@@ -9566,7 +9538,7 @@ namespace ts {
|
||||
}
|
||||
candidate = getSignatureInstantiation(candidate, typeArgumentTypes);
|
||||
}
|
||||
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, ReportErrors.None)) {
|
||||
if (!checkApplicableSignature(node, args, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
|
||||
break;
|
||||
}
|
||||
const index = excludeArgument ? indexOf(excludeArgument, true) : -1;
|
||||
|
||||
Reference in New Issue
Block a user