Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 39 additions & 39 deletions tsc/internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -17885,15 +17885,15 @@ 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)
writeTypeReference = func(ref *Type, depth int) {
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)
Expand All @@ -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('>')
Expand Down Expand Up @@ -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)
Expand All @@ -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)
})
}

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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)
}
Expand All @@ -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...)
}
}
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
}
Expand All @@ -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)
}
Expand Down Expand Up @@ -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] {
Expand Down Expand Up @@ -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)
}
Expand Down Expand Up @@ -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--
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}
}
}
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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]
}
Expand All @@ -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
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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))
}
Expand Down Expand Up @@ -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
})
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/checker/flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
24 changes: 12 additions & 12 deletions tsc/internal/checker/inference.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
}
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
Loading
Loading