diff --git a/tsc/internal/checker/checker.go b/tsc/internal/checker/checker.go index 4c57dd37910f2..81b1b321e9d21 100644 --- a/tsc/internal/checker/checker.go +++ b/tsc/internal/checker/checker.go @@ -17885,7 +17885,7 @@ func (b *keyBuilder) writeAlias(alias *TypeAlias) { } } -func (b *keyBuilder) writeGenericTypeReferences(source *Type, target *Type, ignoreConstraints bool) bool { +func (b *keyBuilder) writeGenericTypeReferences(c *Checker, source *Type, target *Type, ignoreConstraints bool) bool { var constrained bool typeParameters := make([]*Type, 0, 8) var writeTypeReference func(*Type, int) @@ -17893,7 +17893,7 @@ func (b *keyBuilder) writeGenericTypeReferences(source *Type, target *Type, igno b.writeType(ref.Target()) for _, t := range ref.AsTypeReference().resolvedTypeArguments { if t.flags&TypeFlagsTypeParameter != 0 { - if ignoreConstraints || t.checker.getConstraintOfTypeParameter(t) == nil { + if ignoreConstraints || c.getConstraintOfTypeParameter(t) == nil { index := slices.Index(typeParameters, t) if index < 0 { index = len(typeParameters) @@ -17904,7 +17904,7 @@ func (b *keyBuilder) writeGenericTypeReferences(source *Type, target *Type, igno continue } constrained = true - } else if depth < 4 && isTypeReferenceWithGenericArguments(t) { + } else if depth < 4 && c.isTypeReferenceWithGenericArguments(t) { b.writeByte('<') writeTypeReference(t, depth+1) b.writeByte('>') @@ -18047,15 +18047,15 @@ func getConditionalTypeKey(typeArguments []*Type, alias *TypeAlias, forConstrain return b.hash() } -func getRelationKey(source *Type, target *Type, intersectionState IntersectionState, isIdentity bool, ignoreConstraints bool) (CacheHashKey, bool) { +func (c *Checker) getRelationKey(source *Type, target *Type, intersectionState IntersectionState, isIdentity bool, ignoreConstraints bool) (CacheHashKey, bool) { if isIdentity && source.id > target.id { source, target = target, source } var b keyBuilder var constrained bool - if isTypeReferenceWithGenericArguments(source) && isTypeReferenceWithGenericArguments(target) { + if c.isTypeReferenceWithGenericArguments(source) && c.isTypeReferenceWithGenericArguments(target) { b.writeByte('g') - constrained = b.writeGenericTypeReferences(source, target, ignoreConstraints) + constrained = b.writeGenericTypeReferences(c, source, target, ignoreConstraints) } else { b.writeByte('s') b.writeType(source) @@ -18074,9 +18074,9 @@ func getNodeListKey(nodes []*ast.Node) CacheHashKey { return b.hash() } -func isTypeReferenceWithGenericArguments(t *Type) bool { - return isNonDeferredTypeReference(t) && core.Some(t.checker.getTypeArguments(t), func(t *Type) bool { - return t.flags&TypeFlagsTypeParameter != 0 || isTypeReferenceWithGenericArguments(t) +func (c *Checker) isTypeReferenceWithGenericArguments(t *Type) bool { + return isNonDeferredTypeReference(t) && core.Some(c.getTypeArguments(t), func(t *Type) bool { + return t.flags&TypeFlagsTypeParameter != 0 || c.isTypeReferenceWithGenericArguments(t) }) } @@ -19610,6 +19610,7 @@ func (c *Checker) resolveObjectTypeMembers(t *Type) { } c.setStructuredTypeMembers(t, members, callSignatures, constructSignatures, indexInfos) lazyState := c.lazyStateArena.New() + lazyState.checker = c lazyState.layout = layout lazyState.mapper = mapper lazyState.baseTypes = instantiatedBaseTypes @@ -21269,7 +21270,7 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) { } } if indexInfos != nil || d.extra != nil { - d.ensureExtra().indexInfos = indexInfos + d.ensureExtra(c).indexInfos = indexInfos } // We resolve the members before computing the signatures because a signature may use // typeof with a qualified name expression that circularly references the type we are @@ -21278,7 +21279,7 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) { if symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 { signatures := c.getSignaturesOfSymbol(symbol) if signatures != nil || d.extra != nil { - extra := d.ensureExtra() + extra := d.ensureExtra(c) extra.signatures = signatures extra.callSignatureCount = len(signatures) } @@ -21291,7 +21292,7 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) { constructSignatures = c.getDefaultConstructSignatures(classType) } if len(constructSignatures) != 0 { - extra := d.ensureExtra() + extra := d.ensureExtra(c) extra.signatures = append(extra.signatures, constructSignatures...) } } @@ -24495,7 +24496,7 @@ func (c *Checker) getInferTypeParameters(node *ast.Node) []*Type { result = append(result, c.getDeclaredTypeOfSymbol(symbol)) } } - slices.SortFunc(result, CompareTypes) + slices.SortFunc(result, c.CompareTypes) return result } @@ -25704,9 +25705,8 @@ func (c *Checker) newType(flags TypeFlags, objectFlags ObjectFlags, t *Type, kin t.objectFlags = objectFlags &^ (ObjectFlagsCouldContainTypeVariablesComputed | ObjectFlagsCouldContainTypeVariables | ObjectFlagsMembersResolved) t.id = TypeId(c.TypeCount) t.kind = kind - t.checker = c if c.tracer != nil { - c.tracer.RecordType(t) + c.tracer.RecordType(c, t) } return t } @@ -25860,7 +25860,7 @@ func (c *Checker) setStructuredTypeSignatures(data *StructuredType, callSignatur if data.extra == nil && callSignatures == nil && constructSignatures == nil && indexInfos == nil { return } - extra := data.ensureExtra() + extra := data.ensureExtra(c) if len(callSignatures) != 0 { if len(constructSignatures) != 0 { extra.signatures = core.Concatenate(callSignatures, constructSignatures) @@ -26434,7 +26434,7 @@ func (c *Checker) getUnionTypeWorker(types []*Type, unionReduction UnionReductio namedUnions := c.addNamedUnions(nil, types) var reducedTypes []*Type for _, t := range typeSet { - if !core.Some(namedUnions, func(u *Type) bool { return containsType(u.Types(), t) }) { + if !core.Some(namedUnions, func(u *Type) bool { return c.containsType(u.Types(), t) }) { reducedTypes = append(reducedTypes, t) } } @@ -26449,7 +26449,7 @@ func (c *Checker) getUnionTypeWorker(types []*Type, unionReduction UnionReductio } if namedTypesCount+len(reducedTypes) == len(typeSet) { for _, t := range namedUnions { - reducedTypes, _ = insertType(reducedTypes, t) + reducedTypes, _ = c.insertType(reducedTypes, t) } origin = c.newUnionType(ObjectFlagsNone, reducedTypes) } @@ -26533,7 +26533,7 @@ func (c *Checker) addTypesToUnion(sourceTypes []*Type, types []*Type) ([]*Type, } if len(types) >= 2 { // Sort and deduplicate types - slices.SortStableFunc(types, CompareTypes) + slices.SortStableFunc(types, c.CompareTypes) unique := 1 for _, t := range types[1:] { if t != types[unique-1] { @@ -26572,7 +26572,7 @@ func (c *Checker) removeRedundantLiteralTypes(types []*Type, includes TypeFlags, flags&TypeFlagsBigIntLiteral != 0 && includes&TypeFlagsBigInt != 0 || flags&TypeFlagsUniqueESSymbol != 0 && includes&TypeFlagsESSymbol != 0 || reduceVoidUndefined && flags&TypeFlagsUndefined != 0 && includes&TypeFlagsVoid != 0 || - isFreshLiteralType(t) && containsType(types, t.AsLiteralType().regularType) + isFreshLiteralType(t) && c.containsType(types, t.AsLiteralType().regularType) if remove { types = slices.Delete(types, i, i+1) } @@ -26629,14 +26629,14 @@ func (c *Checker) removeConstrainedTypeVariables(types []*Type) []*Type { index = 1 } if t.AsIntersectionType().types[index] == typeVariable { - primitives, _ = insertType(primitives, t.AsIntersectionType().types[1-index]) + primitives, _ = c.insertType(primitives, t.AsIntersectionType().types[1-index]) } } } // If every constituent in the type variable's constraint is covered by an intersection of the type // variable and that constituent, remove those intersections and substitute the type variable. constraint := c.getBaseConstraintOfType(typeVariable) - if everyType(constraint, func(t *Type) bool { return containsType(primitives, t) }) { + if everyType(constraint, func(t *Type) bool { return c.containsType(primitives, t) }) { i := len(types) for i > 0 { i-- @@ -26646,12 +26646,12 @@ func (c *Checker) removeConstrainedTypeVariables(types []*Type) []*Type { if t.AsIntersectionType().types[0].flags&TypeFlagsTypeVariable == 0 { index = 1 } - if t.AsIntersectionType().types[index] == typeVariable && containsType(primitives, t.AsIntersectionType().types[1-index]) { + if t.AsIntersectionType().types[index] == typeVariable && c.containsType(primitives, t.AsIntersectionType().types[1-index]) { types = slices.Delete(types, i, i+1) } } } - types, _ = insertType(types, typeVariable) + types, _ = c.insertType(types, typeVariable) } } return types @@ -27097,7 +27097,7 @@ func (c *Checker) intersectUnionsOfPrimitiveTypes(types []*Type) ([]*Type, bool) for _, u := range unionTypes { for _, t := range u.Types() { var inserted bool - if checked, inserted = insertType(checked, t); inserted { + if checked, inserted = c.insertType(checked, t); inserted { if c.eachUnionContains(unionTypes, t) { // undefinedType/missingType are always sorted first so we leverage that here if t == c.undefinedType && len(result) != 0 && result[0] == c.missingType { @@ -27107,7 +27107,7 @@ func (c *Checker) intersectUnionsOfPrimitiveTypes(types []*Type) ([]*Type, bool) result[0] = c.missingType continue } - result, _ = insertType(result, t) + result, _ = c.insertType(result, t) } } } @@ -27131,14 +27131,14 @@ func (c *Checker) eachUnionContains(unionTypes []*Type, t *Type) bool { func (c *Checker) unionContainsType(union *Type, t *Type, matchSymbol bool) bool { types := union.Types() - if containsType(types, t) { + if c.containsType(types, t) { return true } if t == c.missingType { - return containsType(types, c.undefinedType) + return c.containsType(types, c.undefinedType) } if t == c.undefinedType { - return containsType(types, c.missingType) + return c.containsType(types, c.missingType) } var primitive *Type switch { @@ -27151,7 +27151,7 @@ func (c *Checker) unionContainsType(union *Type, t *Type, matchSymbol bool) bool case t.flags&TypeFlagsUniqueESSymbol != 0 && matchSymbol: primitive = c.esSymbolType } - return primitive != nil && containsType(types, primitive) + return primitive != nil && c.containsType(types, primitive) } func (c *Checker) getCrossProductIntersections(types []*Type, flags IntersectionFlags) []*Type { @@ -27325,11 +27325,11 @@ func (c *Checker) removeType(t *Type, targetType *Type) *Type { } return t } - if origin := t.AsUnionType().origin; origin != nil && origin.flags&TypeFlagsUnion != 0 && containsType(origin.Types(), targetType) { + if origin := t.AsUnionType().origin; origin != nil && origin.flags&TypeFlagsUnion != 0 && c.containsType(origin.Types(), targetType) { return c.filterType(t, func(t *Type) bool { return t != targetType }) } types := t.Types() - if i, ok := slices.BinarySearchFunc(types, targetType, CompareTypes); ok { + if i, ok := slices.BinarySearchFunc(types, targetType, c.CompareTypes); ok { if len(types) == 2 { return types[1-i] } @@ -27344,13 +27344,13 @@ func (c *Checker) removeType(t *Type, targetType *Type) *Type { return t } -func containsType(types []*Type, t *Type) bool { - _, ok := slices.BinarySearchFunc(types, t, CompareTypes) +func (c *Checker) containsType(types []*Type, t *Type) bool { + _, ok := slices.BinarySearchFunc(types, t, c.CompareTypes) return ok } -func insertType(types []*Type, t *Type) ([]*Type, bool) { - if i, ok := slices.BinarySearchFunc(types, t, CompareTypes); !ok { +func (c *Checker) insertType(types []*Type, t *Type) ([]*Type, bool) { + if i, ok := slices.BinarySearchFunc(types, t, c.CompareTypes); !ok { return slices.Insert(types, i, t), true } return types, false @@ -27982,7 +27982,7 @@ func (c *Checker) getSuggestionForNonexistentIndexSignature(objectType *Type, ex func (c *Checker) getSuggestedTypeForNonexistentStringLiteralType(source *Type, target *Type) *Type { candidates := core.FilterSeq(target.Types(), func(t *Type) bool { return t.flags&TypeFlagsStringLiteral != 0 }) - return core.GetSpellingSuggestionWithMaxCandidateCount(getStringLiteralValue(source), candidates, getStringLiteralValue, CompareTypes, 1000) + return core.GetSpellingSuggestionWithMaxCandidateCount(getStringLiteralValue(source), candidates, getStringLiteralValue, c.CompareTypes, 1000) } func getIndexNodeForAccessExpression(accessNode *ast.Node) *ast.Node { @@ -28193,7 +28193,7 @@ func (c *Checker) getResolvedBaseConstraint(t *Type, stack []RecursionId) *Type // levels of nesting, we are presumably exploring a repeating pattern with a long cycle that hasn't // yet triggered the deeply nested limiter. We have no test cases that actually get to 50 levels of // nesting, so it is effectively just a safety stop. - identity := getRecursionIdentity(t) + identity := c.getRecursionIdentity(t) if len(stack) < 10 || len(stack) < 50 && !slices.Contains(stack, identity) { constraint = c.computeBaseConstraint(c.getSimplifiedType(t /*writing*/, false), append(stack, identity)) } @@ -31606,7 +31606,7 @@ func (c *Checker) instantiateContextualType(contextualType *Type, node *ast.Node // literals actually end up widening to 'boolean' (see #48363). t := c.instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper) if t.flags&TypeFlagsAnyOrUnknown == 0 { - if t.flags&TypeFlagsUnion != 0 && containsType(t.Types(), c.regularFalseType) && containsType(t.Types(), c.regularTrueType) { + if t.flags&TypeFlagsUnion != 0 && c.containsType(t.Types(), c.regularFalseType) && c.containsType(t.Types(), c.regularTrueType) { return c.filterType(t, func(t *Type) bool { return t != c.regularFalseType && t != c.regularTrueType }) diff --git a/tsc/internal/checker/flow.go b/tsc/internal/checker/flow.go index d2831231772fe..2f48e590eca7e 100644 --- a/tsc/internal/checker/flow.go +++ b/tsc/internal/checker/flow.go @@ -2436,7 +2436,7 @@ func (c *Checker) typeMaybeAssignableTo(source *Type, target *Type) bool { return c.isTypeAssignableTo(source, target) } // Quick exit when source union contains the target type - if containsType(source.Types(), target) { + if c.containsType(source.Types(), target) { return true } // Otherwise, check if any constituent type of the source union is assignable to the target type diff --git a/tsc/internal/checker/inference.go b/tsc/internal/checker/inference.go index 02c7d009b9ec5..560bdf07f4b12 100644 --- a/tsc/internal/checker/inference.go +++ b/tsc/internal/checker/inference.go @@ -399,7 +399,7 @@ func (c *Checker) inferFromMatchingTypes(n *InferenceState, sources []*Type, tar // when inferring from string[] | string[][] to T[] | T[][], the inference of string we make from // relating string[][] to T[][] is of higher quality than the inference of string[] we make relating // string[][] to T[]. - slices.SortFunc(matchedTargets, compareTypesAndDepth) + slices.SortFunc(matchedTargets, c.compareTypesAndDepth) for _, t := range matchedTargets { for _, s := range matchedSources { if matches(c, s, t) { @@ -418,40 +418,40 @@ func (c *Checker) inferFromMatchingTypes(n *InferenceState, sources []*Type, tar } // Compare two types first by depth and then by the regular type ordering. -func compareTypesAndDepth(t1, t2 *Type) int { - d1 := getTypeDepth(t1, 3) - d2 := getTypeDepth(t2, 3) +func (c *Checker) compareTypesAndDepth(t1, t2 *Type) int { + d1 := c.getTypeDepth(t1, 3) + d2 := c.getTypeDepth(t2, 3) if d1 != d2 { return d2 - d1 // Largest depth sorts first } - return CompareTypes(t1, t2) + return c.CompareTypes(t1, t2) } // Return the depth of the given type up to the given maximum depth. For generic aliased types // and type references, the depth is one plus the largest type argument depth. For union and // intersection types, the depth is the largest constituent type depth. For all other types, // the depth is zero. The maximum depth limits infinite recursion of circular types. -func getTypeDepth(t *Type, maxDepth int) int { +func (c *Checker) getTypeDepth(t *Type, maxDepth int) int { if maxDepth != 0 { if t.alias != nil && len(t.alias.typeArguments) != 0 { - return getTypeListDepth(t.alias.typeArguments, maxDepth-1) + 1 + return c.getTypeListDepth(t.alias.typeArguments, maxDepth-1) + 1 } if t.objectFlags&ObjectFlagsReference != 0 { - if typeArguments := t.checker.getTypeArguments(t); len(typeArguments) != 0 { - return getTypeListDepth(typeArguments, maxDepth-1) + 1 + if typeArguments := c.getTypeArguments(t); len(typeArguments) != 0 { + return c.getTypeListDepth(typeArguments, maxDepth-1) + 1 } } if t.flags&TypeFlagsUnionOrIntersection != 0 { - return getTypeListDepth(t.Types(), maxDepth) + return c.getTypeListDepth(t.Types(), maxDepth) } } return 0 } -func getTypeListDepth(types []*Type, maxDepth int) int { +func (c *Checker) getTypeListDepth(types []*Type, maxDepth int) int { depth := 0 for _, t := range types { - depth = max(depth, getTypeDepth(t, maxDepth)) + depth = max(depth, c.getTypeDepth(t, maxDepth)) } return depth } diff --git a/tsc/internal/checker/nodebuilderimpl.go b/tsc/internal/checker/nodebuilderimpl.go index 45f8ddc00dcf2..9da12fff3074e 100644 --- a/tsc/internal/checker/nodebuilderimpl.go +++ b/tsc/internal/checker/nodebuilderimpl.go @@ -578,7 +578,7 @@ func (b *NodeBuilderImpl) getResolvedTypeWithoutAbstractConstructSignatures(t *S } typeCopy := b.ch.newAnonymousType(t.symbol, t.getMembers(), t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.getIndexInfos()) t.extra.objectTypeWithoutAbstractConstructSignatures = typeCopy - typeCopy.AsStructuredType().ensureExtra().objectTypeWithoutAbstractConstructSignatures = typeCopy + typeCopy.AsStructuredType().ensureExtra(b.ch).objectTypeWithoutAbstractConstructSignatures = typeCopy return typeCopy } diff --git a/tsc/internal/checker/relater.go b/tsc/internal/checker/relater.go index 007fba2511a13..2667266069f80 100644 --- a/tsc/internal/checker/relater.go +++ b/tsc/internal/checker/relater.go @@ -190,7 +190,7 @@ func (c *Checker) isTypeRelatedTo(source *Type, target *Type, relation *Relation } } if source.flags&TypeFlagsObject != 0 && target.flags&TypeFlagsObject != 0 { - id, _ := getRelationKey(source, target, IntersectionStateNone, relation == c.identityRelation, false) + id, _ := c.getRelationKey(source, target, IntersectionStateNone, relation == c.identityRelation, false) related := relation.get(id) if related != RelationComparisonResultNone { return related&RelationComparisonResultSucceeded != 0 @@ -370,7 +370,7 @@ func (c *Checker) checkTypeRelatedToEx( result := r.isRelatedToEx(source, target, RecursionFlagsBoth, errorNode != nil /*reportErrors*/, headMessage, IntersectionStateNone) if r.overflow { // Record this relation as having failed such that we don't attempt the overflowing operation again. - id, _ := getRelationKey(source, target, IntersectionStateNone, relation == c.identityRelation, false /*ignoreConstraints*/) + id, _ := c.getRelationKey(source, target, IntersectionStateNone, relation == c.identityRelation, false /*ignoreConstraints*/) relation.set(id, RelationComparisonResultFailed|RelationComparisonResultComplexityOverflow) if tr := c.tracer; tr != nil { tr.Instant(tracing.PhaseCheckTypes, "checkTypeRelatedTo_DepthLimit", map[string]any{"sourceId": source.id, "targetId": target.id, "depth": len(r.sourceStack), "targetDepth": len(r.targetStack)}) @@ -765,7 +765,7 @@ func isExcessPropertyCheckTarget(t *Type) bool { // structurally equal to at least maxDepth levels, but unequal at some level beyond that. func (c *Checker) isDeeplyNestedType(t *Type, stack []*Type, maxDepth int) bool { if len(stack) >= maxDepth { - target := getRecursionIdentityTarget(t) + target := c.getRecursionIdentityTarget(t) if target.flags&TypeFlagsIntersection != 0 { for _, t := range target.Types() { if c.isDeeplyNestedType(t, stack, maxDepth) { @@ -777,7 +777,7 @@ func (c *Checker) isDeeplyNestedType(t *Type, stack []*Type, maxDepth int) bool count := 0 lastTypeId := TypeId(0) for _, t := range stack { - if hasMatchingRecursionIdentity(t, identity) { + if c.hasMatchingRecursionIdentity(t, identity) { // We only count occurrences with a higher type id than the previous occurrence, since higher // type ids are an indicator of newer instantiations caused by recursion. if t.id >= lastTypeId { @@ -794,11 +794,11 @@ func (c *Checker) isDeeplyNestedType(t *Type, stack []*Type, maxDepth int) bool return false } -func hasMatchingRecursionIdentity(t *Type, identity RecursionId) bool { - target := getRecursionIdentityTarget(t) +func (c *Checker) hasMatchingRecursionIdentity(t *Type, identity RecursionId) bool { + target := c.getRecursionIdentityTarget(t) if target.flags&TypeFlagsIntersection != 0 { for _, t := range target.Types() { - if hasMatchingRecursionIdentity(t, identity) { + if c.hasMatchingRecursionIdentity(t, identity) { return true } } @@ -807,8 +807,8 @@ func hasMatchingRecursionIdentity(t *Type, identity RecursionId) bool { return getRecursionIdentityFromTarget(target) == identity } -func getRecursionIdentity(t *Type) RecursionId { - return getRecursionIdentityFromTarget(getRecursionIdentityTarget(t)) +func (c *Checker) getRecursionIdentity(t *Type) RecursionId { + return getRecursionIdentityFromTarget(c.getRecursionIdentityTarget(t)) } // Get the recursion identity target type from a type. Recursively (a) obtain the target object type of an @@ -817,15 +817,15 @@ func getRecursionIdentity(t *Type) RecursionId { // to explicitly written object literals. For example in `Mapped<{ x: Mapped<{ x: Mapped<{ x: string }>}>}>`, // each of the mapped type applications will have a unique recursion identity (that of their target object type // literal) and thus avoid appearing deeply nested. -func getRecursionIdentityTarget(t *Type) *Type { +func (c *Checker) getRecursionIdentityTarget(t *Type) *Type { if t.flags&TypeFlagsIndexedAccess != 0 { - return getRecursionIdentityTarget(t.AsIndexedAccessType().objectType) + return c.getRecursionIdentityTarget(t.AsIndexedAccessType().objectType) } if t.objectFlags&ObjectFlagsInstantiatedMapped == ObjectFlagsInstantiatedMapped { - target := t.checker.getModifiersTypeFromMappedType(t) + target := c.getModifiersTypeFromMappedType(t) if target != nil && (target.symbol != nil || target.flags&TypeFlagsIntersection != 0 && core.Some(target.Types(), func(t *Type) bool { return t.symbol != nil })) { - return getRecursionIdentityTarget(target) + return c.getRecursionIdentityTarget(target) } } return t @@ -2870,7 +2870,7 @@ func (c *Checker) isTypeSubsetOf(source *Type, target *Type) bool { func (c *Checker) isTypeSubsetOfUnion(source *Type, target *Type) bool { if source.flags&TypeFlagsUnion != 0 { for _, t := range source.Types() { - if !containsType(target.Types(), t) { + if !c.containsType(target.Types(), t) { return false } } @@ -2879,7 +2879,7 @@ func (c *Checker) isTypeSubsetOfUnion(source *Type, target *Type) bool { if source.flags&TypeFlagsEnumLike != 0 && c.getBaseTypeOfEnumLikeType(source) == target { return true } - return containsType(target.Types(), source) + return c.containsType(target.Types(), source) } func (r *Relater) unionOrIntersectionRelatedTo(source *Type, target *Type, reportErrors bool, intersectionState IntersectionState) Ternary { @@ -2953,7 +2953,7 @@ func (r *Relater) unionOrIntersectionRelatedTo(source *Type, target *Type, repor func (r *Relater) someTypeRelatedToType(source *Type, target *Type, reportErrors bool, intersectionState IntersectionState) Ternary { sourceTypes := source.Types() - if source.flags&TypeFlagsUnion != 0 && containsType(sourceTypes, target) { + if source.flags&TypeFlagsUnion != 0 && r.c.containsType(sourceTypes, target) { return TernaryTrue } for i, t := range sourceTypes { @@ -3007,7 +3007,7 @@ func (r *Relater) getUndefinedStrippedTargetIfNeeded(source *Type, target *Type) func (r *Relater) typeRelatedToSomeType(source *Type, target *Type, reportErrors bool, intersectionState IntersectionState) Ternary { targetTypes := target.Types() if target.flags&TypeFlagsUnion != 0 { - if containsType(targetTypes, source) { + if r.c.containsType(targetTypes, source) { return TernaryTrue } if r.relation != r.c.comparableRelation && target.objectFlags&ObjectFlagsPrimitiveUnion != 0 && source.flags&TypeFlagsEnumLiteral == 0 && @@ -3034,7 +3034,7 @@ func (r *Relater) typeRelatedToSomeType(source *Type, target *Type, reportErrors case source.flags&TypeFlagsBigIntLiteral != 0: primitive = r.c.bigintType } - if primitive != nil && containsType(targetTypes, primitive) || alternateForm != nil && containsType(targetTypes, alternateForm) { + if primitive != nil && r.c.containsType(targetTypes, primitive) || alternateForm != nil && r.c.containsType(targetTypes, alternateForm) { return TernaryTrue } return TernaryFalse @@ -3100,7 +3100,7 @@ func (r *Relater) recursiveTypeRelatedTo(source *Type, target *Type, reportError // important to have well-defined behavior even in cases that shouldn't normally occur. return TernaryFalse } - id, constrained := getRelationKey(source, target, intersectionState, r.relation == r.c.identityRelation, false /*ignoreConstraints*/) + id, constrained := r.c.getRelationKey(source, target, intersectionState, r.relation == r.c.identityRelation, false /*ignoreConstraints*/) if entry := r.relation.get(id); entry != RelationComparisonResultNone { if reportErrors && entry&RelationComparisonResultFailed != 0 && entry&RelationComparisonResultOverflow == 0 { // We are elaborating errors and the cached result is a failure not due to a comparison overflow, @@ -3128,7 +3128,7 @@ func (r *Relater) recursiveTypeRelatedTo(source *Type, target *Type, reportError // type parameters. For such keys we also check against the key we would have gotten if all type parameters // were unconstrained. if constrained { - broadestEquivalentId, _ := getRelationKey(source, target, intersectionState, r.relation == r.c.identityRelation, true /*ignoreConstraints*/) + broadestEquivalentId, _ := r.c.getRelationKey(source, target, intersectionState, r.relation == r.c.identityRelation, true /*ignoreConstraints*/) if r.maybeKeysSet.Has(broadestEquivalentId) { return TernaryMaybe } diff --git a/tsc/internal/checker/tracer.go b/tsc/internal/checker/tracer.go index 0fea57f8d4d70..81df2060c397c 100644 --- a/tsc/internal/checker/tracer.go +++ b/tsc/internal/checker/tracer.go @@ -22,8 +22,8 @@ func NewTracer(tr *tracing.Tracing, checkerIndex int) *Tracer { return &Tracer{tracing: tr, recorder: tr.NewTypeTracer(checkerIndex), checkerIndex: checkerIndex} } -func (t *Tracer) RecordType(typ *Type) { - t.recorder.RecordType(wrapType(typ)) +func (t *Tracer) RecordType(c *Checker, typ *Type) { + t.recorder.RecordType(wrapType(c, typ)) } func (t *Tracer) Push(phase tracing.Phase, name string, args map[string]any, separateBeginAndEnd bool) func() { @@ -105,7 +105,7 @@ func (a *tracedTypeAdapter) AliasTypeArguments() []tracing.TracedType { if a.t.alias == nil { return nil } - return wrapTypes(a.t.alias.TypeArguments()) + return wrapTypes(a.checker, a.t.alias.TypeArguments()) } func (a *tracedTypeAdapter) IntrinsicName() string { @@ -122,14 +122,14 @@ func (a *tracedTypeAdapter) UnionTypes() []tracing.TracedType { if a.t.flags&TypeFlagsUnion == 0 { return nil } - return wrapTypes(a.t.AsUnionType().types) + return wrapTypes(a.checker, a.t.AsUnionType().types) } func (a *tracedTypeAdapter) IntersectionTypes() []tracing.TracedType { if a.t.flags&TypeFlagsIntersection == 0 { return nil } - return wrapTypes(a.t.AsIntersectionType().types) + return wrapTypes(a.checker, a.t.AsIntersectionType().types) } func (a *tracedTypeAdapter) IndexType() tracing.TracedType { @@ -140,7 +140,7 @@ func (a *tracedTypeAdapter) IndexType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) IndexedAccessObjectType() tracing.TracedType { @@ -151,7 +151,7 @@ func (a *tracedTypeAdapter) IndexedAccessObjectType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) IndexedAccessIndexType() tracing.TracedType { @@ -162,7 +162,7 @@ func (a *tracedTypeAdapter) IndexedAccessIndexType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ConditionalCheckType() tracing.TracedType { @@ -173,7 +173,7 @@ func (a *tracedTypeAdapter) ConditionalCheckType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ConditionalExtendsType() tracing.TracedType { @@ -184,7 +184,7 @@ func (a *tracedTypeAdapter) ConditionalExtendsType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ConditionalTrueType() tracing.TracedType { @@ -195,7 +195,7 @@ func (a *tracedTypeAdapter) ConditionalTrueType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ConditionalFalseType() tracing.TracedType { @@ -206,7 +206,7 @@ func (a *tracedTypeAdapter) ConditionalFalseType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) SubstitutionBaseType() tracing.TracedType { @@ -217,7 +217,7 @@ func (a *tracedTypeAdapter) SubstitutionBaseType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) SubstitutionConstraintType() tracing.TracedType { @@ -228,7 +228,7 @@ func (a *tracedTypeAdapter) SubstitutionConstraintType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ReferenceTarget() tracing.TracedType { @@ -239,14 +239,14 @@ func (a *tracedTypeAdapter) ReferenceTarget() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ReferenceTypeArguments() []tracing.TracedType { if a.t.flags&TypeFlagsObject == 0 || a.t.objectFlags&ObjectFlagsReference == 0 { return nil } - return wrapTypes(a.t.AsTypeReference().resolvedTypeArguments) + return wrapTypes(a.checker, a.t.AsTypeReference().resolvedTypeArguments) } func (a *tracedTypeAdapter) ReferenceNode() *ast.Node { @@ -264,7 +264,7 @@ func (a *tracedTypeAdapter) ReverseMappedSourceType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ReverseMappedMappedType() tracing.TracedType { @@ -275,7 +275,7 @@ func (a *tracedTypeAdapter) ReverseMappedMappedType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) ReverseMappedConstraintType() tracing.TracedType { @@ -286,7 +286,7 @@ func (a *tracedTypeAdapter) ReverseMappedConstraintType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) EvolvingArrayElementType() tracing.TracedType { @@ -297,7 +297,7 @@ func (a *tracedTypeAdapter) EvolvingArrayElementType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) EvolvingArrayFinalType() tracing.TracedType { @@ -308,7 +308,7 @@ func (a *tracedTypeAdapter) EvolvingArrayFinalType() tracing.TracedType { if t == nil { return nil } - return wrapType(t) + return wrapType(a.checker, t) } func (a *tracedTypeAdapter) IsTuple() bool { @@ -323,7 +323,7 @@ func (a *tracedTypeAdapter) Pattern() *ast.Node { } func (a *tracedTypeAdapter) RecursionIdentity() any { - return getRecursionIdentity(a.t).value + return a.checker.getRecursionIdentity(a.t).value } func (a *tracedTypeAdapter) Display() string { @@ -346,20 +346,20 @@ func (a *tracedTypeAdapter) Display() string { return "" } -func wrapType(t *Type) tracing.TracedType { +func wrapType(c *Checker, t *Type) tracing.TracedType { if t == nil { return nil } - return &tracedTypeAdapter{t: t, checker: t.checker} + return &tracedTypeAdapter{t: t, checker: c} } -func wrapTypes(types []*Type) []tracing.TracedType { +func wrapTypes(c *Checker, types []*Type) []tracing.TracedType { if len(types) == 0 { return nil } result := make([]tracing.TracedType, len(types)) for i, t := range types { - result[i] = wrapType(t) + result[i] = wrapType(c, t) } return result } diff --git a/tsc/internal/checker/types.go b/tsc/internal/checker/types.go index f119288a21744..bd75885e6c245 100644 --- a/tsc/internal/checker/types.go +++ b/tsc/internal/checker/types.go @@ -504,7 +504,7 @@ type SignatureLinks struct { type TypeFlags uint32 // Note that for types of different kinds, the numeric values of TypeFlags determine the order -// computed by the CompareTypes function and therefore the order of constituent types in union types. +// computed by the Checker.CompareTypes method and therefore the order of constituent types in union types. // Since union type processing often bails out early when a result is known, it is important to order // TypeFlags in increasing order of potential type complexity. In particular, indexed access and // conditional types should sort last as those types are potentially recursive and possibly infinite. @@ -790,7 +790,6 @@ type Type struct { kind typeKind symbol *ast.Symbol alias *TypeAlias - checker *Checker } // Enforce the layout required by the pointer conversions, on every architecture. @@ -1182,9 +1181,9 @@ func (t *StructuredType) getPropertyAt(index int) *ast.Symbol { if member == nil { memberInfo := lazy.layout.memberInfos[index] if memberInfo.baseIndex < 0 { - member = t.checker.instantiateSymbol(memberInfo.symbol, lazy.mapper) + member = lazy.checker.instantiateSymbol(memberInfo.symbol, lazy.mapper) } else { - member = t.checker.getPropertyOfType(lazy.baseTypes[memberInfo.baseIndex], memberInfo.symbol.Name()) + member = lazy.checker.getPropertyOfType(lazy.baseTypes[memberInfo.baseIndex], memberInfo.symbol.Name()) } t.properties[index] = member } @@ -1233,9 +1232,9 @@ func (t *StructuredType) getIndexInfos() []*IndexInfo { return t.extra.indexInfos } -func (t *StructuredType) ensureExtra() *structuredTypeExtra { +func (t *StructuredType) ensureExtra(c *Checker) *structuredTypeExtra { if t.extra == nil { - t.extra = t.checker.structuredTypeExtraArena.New() + t.extra = c.structuredTypeExtraArena.New() } return t.extra } @@ -1297,6 +1296,7 @@ type TypeReference struct { type LazyState struct { layout *MemberLayout + checker *Checker mapper *TypeMapper baseTypes []*Type propertiesResolved bool diff --git a/tsc/internal/checker/types_test.go b/tsc/internal/checker/types_test.go index 86de2b089e06e..750ce924d77ca 100644 --- a/tsc/internal/checker/types_test.go +++ b/tsc/internal/checker/types_test.go @@ -110,7 +110,7 @@ func didPanic(f func()) (panicked bool) { func TestTypeHeaderSize(t *testing.T) { t.Parallel() - assert.Equal(t, unsafe.Sizeof(Type{}), 16+3*unsafe.Sizeof((*Checker)(nil))) + assert.Equal(t, unsafe.Sizeof(Type{}), 16+2*unsafe.Sizeof((*Checker)(nil))) } func TestKeyBuilder(t *testing.T) { @@ -417,9 +417,9 @@ func TestTypeMapperDispatch(t *testing.T) { assert.Equal(t, test.mapper.Map(source), test.result) assert.Assert(t, !test.mapper.MapsThisOnly()) } - assert.Equal(t, compareTypeMappers(simple, newSimpleTypeMapper(source, target)), 0) - assert.Equal(t, compareTypeMappers(array, newArrayTypeMapper([]*Type{source, other}, []*Type{target, source})), 0) - assert.Equal(t, compareTypeMappers(merged, newMergedTypeMapper(simple, array)), 0) + assert.Equal(t, c.compareTypeMappers(simple, newSimpleTypeMapper(source, target)), 0) + assert.Equal(t, c.compareTypeMappers(array, newArrayTypeMapper([]*Type{source, other}, []*Type{target, source})), 0) + assert.Equal(t, c.compareTypeMappers(merged, newMergedTypeMapper(simple, array)), 0) this := c.newTypeParameter(nil) this.AsTypeParameter().isThisType = true for _, mapper := range []*TypeMapper{ diff --git a/tsc/internal/checker/utilities.go b/tsc/internal/checker/utilities.go index 3a7e9993ba879..5a524b7b1d090 100644 --- a/tsc/internal/checker/utilities.go +++ b/tsc/internal/checker/utilities.go @@ -415,7 +415,7 @@ func (c *Checker) compareNodes(n1, n2 *ast.Node) int { return n1.Pos() - n2.Pos() } -func CompareTypes(t1, t2 *Type) int { +func (c *Checker) CompareTypes(t1, t2 *Type) int { if t1 == t2 { return 0 } @@ -425,16 +425,13 @@ func CompareTypes(t1, t2 *Type) int { if t2 == nil { return 1 } - if t1.checker != t2.checker { - panic("Cannot compare types from different checkers") - } // First sort in order of increasing type flags values. - if c := getSortOrderFlags(t1) - getSortOrderFlags(t2); c != 0 { - return c + if r := getSortOrderFlags(t1) - getSortOrderFlags(t2); r != 0 { + return r } // Order named types by name and, in the case of aliased types, by alias type arguments. - if c := compareTypeNames(t1, t2); c != 0 { - return c + if r := c.compareTypeNames(t1, t2); r != 0 { + return r } // We have unnamed types or types with identical names. Now sort by data specific to the type. switch { @@ -453,14 +450,14 @@ func CompareTypes(t1, t2 *Type) int { } // A single instantiation expression can produce multiple types for union constituents, // so compare their source declarations before comparing the shared expression node. - if c := t1.checker.compareNodes(declaration1, declaration2); c != 0 { - return c + if r := c.compareNodes(declaration1, declaration2); r != 0 { + return r } - if c := t1.checker.compareNodes(t1.AsInstantiationExpressionType().node, t2.AsInstantiationExpressionType().node); c != 0 { - return c + if r := c.compareNodes(t1.AsInstantiationExpressionType().node, t2.AsInstantiationExpressionType().node); r != 0 { + return r } - } else if c := t1.checker.compareSymbols(t1.symbol, t2.symbol); c != 0 { - return c + } else if r := c.compareSymbols(t1.symbol, t2.symbol); r != 0 { + return r } // When object types have the same or no symbol, order by kind. We order type references before other kinds. if t1.objectFlags&ObjectFlagsReference != 0 && t2.objectFlags&ObjectFlagsReference != 0 { @@ -468,25 +465,25 @@ func CompareTypes(t1, t2 *Type) int { r2 := t2.AsTypeReference() if r1.target.objectFlags&ObjectFlagsTuple != 0 && r2.target.objectFlags&ObjectFlagsTuple != 0 { // Tuple types have no associated symbol, instead we order by tuple element information. - if c := compareTupleTypes(r1.target.AsTupleType(), r2.target.AsTupleType()); c != 0 { - return c + if r := compareTupleTypes(r1.target.AsTupleType(), r2.target.AsTupleType()); r != 0 { + return r } } // Here we know we have references to instantiations of the same type because we have matching targets. if r1.node == nil && r2.node == nil { // Non-deferred type references with the same target are sorted by their type argument lists. - if c := compareTypeLists(t1.AsTypeReference().resolvedTypeArguments, t2.AsTypeReference().resolvedTypeArguments); c != 0 { - return c + if r := c.compareTypeLists(t1.AsTypeReference().resolvedTypeArguments, t2.AsTypeReference().resolvedTypeArguments); r != 0 { + return r } } else { // Deferred type references with the same target are ordered by the source location of the reference. - if c := t1.checker.compareNodes(r1.node, r2.node); c != 0 { - return c + if r := c.compareNodes(r1.node, r2.node); r != 0 { + return r } // Instantiations of the same deferred type reference are ordered by their associated type mappers // (which reflect the mapping of in-scope type parameters to type arguments). - if c := compareTypeMappers(t1.AsObjectType().mapper, t2.AsObjectType().mapper); c != 0 { - return c + if r := c.compareTypeMappers(t1.AsObjectType().mapper, t2.AsObjectType().mapper); r != 0 { + return r } } } else if t1.objectFlags&ObjectFlagsReference != 0 { @@ -495,20 +492,20 @@ func CompareTypes(t1, t2 *Type) int { return 1 } else { // Order unnamed non-reference object types by kind and instantiation data. - if c := int(t1.objectFlags&ObjectFlagsObjectTypeKindMask) - int(t2.objectFlags&ObjectFlagsObjectTypeKindMask); c != 0 { - return c + if r := int(t1.objectFlags&ObjectFlagsObjectTypeKindMask) - int(t2.objectFlags&ObjectFlagsObjectTypeKindMask); r != 0 { + return r } if t1.objectFlags&ObjectFlagsReverseMapped != 0 { r1 := t1.AsReverseMappedType() r2 := t2.AsReverseMappedType() - if c := CompareTypes(r1.source, r2.source); c != 0 { - return c + if r := c.CompareTypes(r1.source, r2.source); r != 0 { + return r } - if c := CompareTypes(r1.mappedType, r2.mappedType); c != 0 { - return c + if r := c.CompareTypes(r1.mappedType, r2.mappedType); r != 0 { + return r } - if c := CompareTypes(r1.constraintType, r2.constraintType); c != 0 { - return c + if r := c.CompareTypes(r1.constraintType, r2.constraintType); r != 0 { + return r } } m1 := t1.AsObjectType().mapper @@ -523,8 +520,8 @@ func CompareTypes(t1, t2 *Type) int { m2 = castTypeMapper[CompositeTypeMapper](m2, TypeMapperKindComposite).m2 } } - if c := compareTypeMappers(m1, m2); c != 0 { - return c + if r := c.compareTypeMappers(m1, m2); r != 0 { + return r } } case t1.flags&TypeFlagsUnion != 0: @@ -532,41 +529,41 @@ func CompareTypes(t1, t2 *Type) int { o1 := t1.AsUnionType().origin o2 := t2.AsUnionType().origin if o1 == nil && o2 == nil { - if c := compareTypeLists(t1.Types(), t2.Types()); c != 0 { - return c + if r := c.compareTypeLists(t1.Types(), t2.Types()); r != 0 { + return r } } else if o1 == nil { return 1 } else if o2 == nil { return -1 } else { - if c := CompareTypes(o1, o2); c != 0 { - return c + if r := c.CompareTypes(o1, o2); r != 0 { + return r } } case t1.flags&TypeFlagsIntersection != 0: // Intersections are ordered by their constituent type lists. - if c := compareTypeLists(t1.Types(), t2.Types()); c != 0 { - return c + if r := c.compareTypeLists(t1.Types(), t2.Types()); r != 0 { + return r } case t1.flags&(TypeFlagsEnum|TypeFlagsEnumLiteral|TypeFlagsUniqueESSymbol) != 0: // Enum members are ordered by their symbol (and thus their declaration order). - if c := t1.checker.compareSymbols(t1.symbol, t2.symbol); c != 0 { - return c + if r := c.compareSymbols(t1.symbol, t2.symbol); r != 0 { + return r } case t1.flags&TypeFlagsStringLiteral != 0: // String literal types are ordered by their values. - if c := strings.Compare(t1.AsLiteralType().value.(string), t2.AsLiteralType().value.(string)); c != 0 { - return c + if r := strings.Compare(t1.AsLiteralType().value.(string), t2.AsLiteralType().value.(string)); r != 0 { + return r } case t1.flags&TypeFlagsNumberLiteral != 0: // Numeric literal types are ordered by their values. - if c := cmp.Compare(t1.AsLiteralType().value.(jsnum.Number), t2.AsLiteralType().value.(jsnum.Number)); c != 0 { - return c + if r := cmp.Compare(t1.AsLiteralType().value.(jsnum.Number), t2.AsLiteralType().value.(jsnum.Number)); r != 0 { + return r } case t1.flags&TypeFlagsBigIntLiteral != 0: - if c := getBigIntLiteralValue(t1).Compare(getBigIntLiteralValue(t2)); c != 0 { - return c + if r := getBigIntLiteralValue(t1).Compare(getBigIntLiteralValue(t2)); r != 0 { + return r } case t1.flags&TypeFlagsBooleanLiteral != 0: b1 := t1.AsLiteralType().value.(bool) @@ -578,47 +575,47 @@ func CompareTypes(t1, t2 *Type) int { return -1 } case t1.flags&TypeFlagsTypeParameter != 0: - if c := t1.checker.compareSymbols(t1.symbol, t2.symbol); c != 0 { - return c + if r := c.compareSymbols(t1.symbol, t2.symbol); r != 0 { + return r } case t1.flags&TypeFlagsIndex != 0: - if c := CompareTypes(t1.AsIndexType().target, t2.AsIndexType().target); c != 0 { - return c + if r := c.CompareTypes(t1.AsIndexType().target, t2.AsIndexType().target); r != 0 { + return r } - if c := int(t1.AsIndexType().indexFlags) - int(t2.AsIndexType().indexFlags); c != 0 { - return c + if r := int(t1.AsIndexType().indexFlags) - int(t2.AsIndexType().indexFlags); r != 0 { + return r } case t1.flags&TypeFlagsIndexedAccess != 0: - if c := CompareTypes(t1.AsIndexedAccessType().objectType, t2.AsIndexedAccessType().objectType); c != 0 { - return c + if r := c.CompareTypes(t1.AsIndexedAccessType().objectType, t2.AsIndexedAccessType().objectType); r != 0 { + return r } - if c := CompareTypes(t1.AsIndexedAccessType().indexType, t2.AsIndexedAccessType().indexType); c != 0 { - return c + if r := c.CompareTypes(t1.AsIndexedAccessType().indexType, t2.AsIndexedAccessType().indexType); r != 0 { + return r } case t1.flags&TypeFlagsConditional != 0: - if c := t1.checker.compareNodes(t1.AsConditionalType().root.node.AsNode(), t2.AsConditionalType().root.node.AsNode()); c != 0 { - return c + if r := c.compareNodes(t1.AsConditionalType().root.node.AsNode(), t2.AsConditionalType().root.node.AsNode()); r != 0 { + return r } - if c := compareTypeMappers(t1.AsConditionalType().mapper, t2.AsConditionalType().mapper); c != 0 { - return c + if r := c.compareTypeMappers(t1.AsConditionalType().mapper, t2.AsConditionalType().mapper); r != 0 { + return r } case t1.flags&TypeFlagsSubstitution != 0: - if c := CompareTypes(t1.AsSubstitutionType().baseType, t2.AsSubstitutionType().baseType); c != 0 { - return c + if r := c.CompareTypes(t1.AsSubstitutionType().baseType, t2.AsSubstitutionType().baseType); r != 0 { + return r } - if c := CompareTypes(t1.AsSubstitutionType().constraint, t2.AsSubstitutionType().constraint); c != 0 { - return c + if r := c.CompareTypes(t1.AsSubstitutionType().constraint, t2.AsSubstitutionType().constraint); r != 0 { + return r } case t1.flags&TypeFlagsTemplateLiteral != 0: - if c := slices.Compare(t1.AsTemplateLiteralType().texts, t2.AsTemplateLiteralType().texts); c != 0 { - return c + if r := slices.Compare(t1.AsTemplateLiteralType().texts, t2.AsTemplateLiteralType().texts); r != 0 { + return r } - if c := compareTypeLists(t1.AsTemplateLiteralType().types, t2.AsTemplateLiteralType().types); c != 0 { - return c + if r := c.compareTypeLists(t1.AsTemplateLiteralType().types, t2.AsTemplateLiteralType().types); r != 0 { + return r } case t1.flags&TypeFlagsStringMapping != 0: - if c := CompareTypes(t1.AsStringMappingType().target, t2.AsStringMappingType().target); c != 0 { - return c + if r := c.CompareTypes(t1.AsStringMappingType().target, t2.AsStringMappingType().target); r != 0 { + return r } } // Fall back to type IDs. This results in type creation order for built-in types. @@ -633,11 +630,11 @@ func getSortOrderFlags(t *Type) int { return int(t.flags) } -func compareTypeNames(t1, t2 *Type) int { +func (c *Checker) compareTypeNames(t1, t2 *Type) int { s1 := getTypeNameSymbol(t1) s2 := getTypeNameSymbol(t2) if s1 == s2 { - return compareTypeLists(t1.alias.TypeArguments(), t2.alias.TypeArguments()) + return c.compareTypeLists(t1.alias.TypeArguments(), t2.alias.TypeArguments()) } if s1 == nil { return 1 @@ -645,11 +642,11 @@ func compareTypeNames(t1, t2 *Type) int { if s2 == nil { return -1 } - if c := strings.Compare(s1.Name(), s2.Name()); c != 0 { - return c + if r := strings.Compare(s1.Name(), s2.Name()); r != 0 { + return r } // Keep distinct same-named declarations together before comparing alias arguments or structure. - return t1.checker.compareSymbols(s1, s2) + return c.compareSymbols(s1, s2) } func getTypeNameSymbol(t *Type) *ast.Symbol { @@ -680,13 +677,13 @@ func compareTupleTypes(t1, t2 *TupleType) int { return len(t1.elementInfos) - len(t2.elementInfos) } for i := range t1.elementInfos { - if c := int(t1.elementInfos[i].flags) - int(t2.elementInfos[i].flags); c != 0 { - return c + if r := int(t1.elementInfos[i].flags) - int(t2.elementInfos[i].flags); r != 0 { + return r } } for i := range t1.elementInfos { - if c := compareElementLabels(t1.elementInfos[i].labeledDeclaration, t2.elementInfos[i].labeledDeclaration); c != 0 { - return c + if r := compareElementLabels(t1.elementInfos[i].labeledDeclaration, t2.elementInfos[i].labeledDeclaration); r != 0 { + return r } } return 0 @@ -705,19 +702,19 @@ func compareElementLabels(n1, n2 *ast.Node) int { return strings.Compare(n1.Name().Text(), n2.Name().Text()) } -func compareTypeLists(s1, s2 []*Type) int { +func (c *Checker) compareTypeLists(s1, s2 []*Type) int { if len(s1) != len(s2) { return len(s1) - len(s2) } for i, t1 := range s1 { - if c := CompareTypes(t1, s2[i]); c != 0 { - return c + if r := c.CompareTypes(t1, s2[i]); r != 0 { + return r } } return 0 } -func compareTypeMappers(m1, m2 *TypeMapper) int { +func (c *Checker) compareTypeMappers(m1, m2 *TypeMapper) int { if m1 == m2 { return 0 } @@ -736,24 +733,24 @@ func compareTypeMappers(m1, m2 *TypeMapper) int { case TypeMapperKindSimple: m1 := castTypeMapper[SimpleTypeMapper](m1, TypeMapperKindSimple) m2 := castTypeMapper[SimpleTypeMapper](m2, TypeMapperKindSimple) - if c := CompareTypes(m1.source, m2.source); c != 0 { - return c + if r := c.CompareTypes(m1.source, m2.source); r != 0 { + return r } - return CompareTypes(m1.target, m2.target) + return c.CompareTypes(m1.target, m2.target) case TypeMapperKindArray: m1 := castTypeMapper[ArrayTypeMapper](m1, TypeMapperKindArray) m2 := castTypeMapper[ArrayTypeMapper](m2, TypeMapperKindArray) - if c := compareTypeLists(m1.sources, m2.sources); c != 0 { - return c + if r := c.compareTypeLists(m1.sources, m2.sources); r != 0 { + return r } - return compareTypeLists(m1.targets, m2.targets) + return c.compareTypeLists(m1.targets, m2.targets) case TypeMapperKindMerged: m1 := castTypeMapper[MergedTypeMapper](m1, TypeMapperKindMerged) m2 := castTypeMapper[MergedTypeMapper](m2, TypeMapperKindMerged) - if c := compareTypeMappers(m1.m1, m2.m1); c != 0 { - return c + if r := c.compareTypeMappers(m1.m1, m2.m1); r != 0 { + return r } - return compareTypeMappers(m1.m2, m2.m2) + return c.compareTypeMappers(m1.m2, m2.m2) } return 0 } diff --git a/tsc/internal/testrunner/compiler_runner.go b/tsc/internal/testrunner/compiler_runner.go index 6f2712632b5b8..a36440f3e9d73 100644 --- a/tsc/internal/testrunner/compiler_runner.go +++ b/tsc/internal/testrunner/compiler_runner.go @@ -535,7 +535,7 @@ func (c *compilerTest) verifyUnionOrdering(t *testing.T) { reversed := slices.Clone(types) slices.Reverse(reversed) - slices.SortFunc(reversed, checker.CompareTypes) + slices.SortFunc(reversed, c.CompareTypes) assert.Assert(t, slices.Equal(reversed, types), "compareTypes does not sort union types consistently") shuffled := slices.Clone(types) @@ -543,7 +543,7 @@ func (c *compilerTest) verifyUnionOrdering(t *testing.T) { for range 10 { rng.Shuffle(len(shuffled), func(i, j int) { shuffled[i], shuffled[j] = shuffled[j], shuffled[i] }) - slices.SortFunc(shuffled, checker.CompareTypes) + slices.SortFunc(shuffled, c.CompareTypes) assert.Assert(t, slices.Equal(shuffled, types), "compareTypes does not sort union types consistently") } }