Skip to content

Commit e2d42e7

Browse files
committed
Move optional structured type shape into cold storage
Every object, union, and intersection paid for signature and index-info slice headers, a call-signature count, and a node-builder cache, even when none were needed. Those fields made StructuredType 144 bytes on amd64. Keep them in an optional checker-arena sidecar and reduce the hot record to 88 bytes. Preserve signature publication during recursive anonymous resolution, clipped public signature slices, index-info nil/empty distinctions, and independent node-builder cache identity. Empty unresolved shape does not allocate a sidecar. Compared with the parent commit, including all previous checker, AST, and symbol reductions. Six fresh-process interleaved samples parse, bind, and check the actual VS Code project using one checker and normal GC settings. Live heap falls another 1.81%, GC scan bytes fall 2.01%, and allocated bytes fall 1.28%. Allocation counts do not differ significantly. Neither hardware instructions nor elapsed time establishes a change; this does not claim a CPU improvement. Exact CLI diagnostic text and compiler counts match the baseline. Exact benchstat output: goos: linux goarch: amd64 pkg: github.com/microsoft/TypeScript/tsc/internal/checker cpu: Intel(R) Core(TM) i9-10900K CPU @ 3.70GHz │ vscode-shape-before.txt │ vscode-shape.txt │ │ sec/op │ sec/op vs base │ ExternalProgram-20 41.55 ± 6% 41.84 ± 13% ~ (p=0.937 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ diagnostics │ diagnostics vs base │ ExternalProgram-20 321.0 ± 0% 321.0 ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ files │ files vs base │ ExternalProgram-20 10.28k ± 0% 10.28k ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ retained-B │ retained-B vs base │ ExternalProgram-20 3.959Gi ± 0% 3.887Gi ± 0% -1.81% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ scan-B │ scan-B vs base │ ExternalProgram-20 3.553Gi ± 0% 3.482Gi ± 0% -2.01% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ symbols │ symbols vs base │ ExternalProgram-20 4.154M ± 0% 4.154M ± 0% ~ (p=1.000 n=6) ¹ ¹ all samples are equal │ vscode-shape-before.txt │ vscode-shape.txt │ │ B/op │ B/op vs base │ ExternalProgram-20 5.577Gi ± 0% 5.506Gi ± 0% -1.28% (p=0.002 n=6) │ vscode-shape-before.txt │ vscode-shape.txt │ │ allocs/op │ allocs/op vs base │ ExternalProgram-20 27.36M ± 0% 27.35M ± 0% ~ (p=0.818 n=6) │ shape-before-instructions.txt │ shape-instructions.txt │ │ instructions/op │ instructions/op vs base │ ExternalInstructions-20 292.5G ± 4% 301.6G ± 4% ~ (p=0.093 n=6)
1 parent 5651487 commit e2d42e7

5 files changed

Lines changed: 138 additions & 36 deletions

File tree

‎tsc/internal/checker/checker.go‎

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ type Checker struct {
685685
conditionalTypeArena core.Arena[ConditionalType]
686686
typeListArena core.Arena[*Type]
687687
valueSymbolExtraArena core.Arena[valueSymbolExtra]
688+
structuredTypeExtraArena core.Arena[structuredTypeExtra]
688689
memberIndexArena core.Arena[memberIndex]
689690
memberIndexSlotsArena core.Arena[uint32]
690691
freeTypeSets *temporaryTypeSet
@@ -4606,7 +4607,7 @@ func (c *Checker) getTypeWithoutSignatures(t *Type) *Type {
46064607
switch {
46074608
case t.flags&TypeFlagsObject != 0:
46084609
resolved := c.resolveStructuredTypeMembers(t)
4609-
if len(resolved.signatures) != 0 {
4610+
if len(resolved.getSignatures()) != 0 {
46104611
result := c.newObjectType(ObjectFlagsAnonymous, t.symbol)
46114612
result.objectFlags |= ObjectFlagsMembersResolved
46124613
result.AsObjectType().members = resolved.members
@@ -10946,7 +10947,7 @@ func (c *Checker) getInstantiationExpressionType(exprType *Type, node *ast.Node)
1094610947
debug.Assert(t.symbol != nil, "Instantiation expression source type must have a symbol")
1094710948
symbol.SetDeclarations(t.symbol.Declarations())
1094810949
result := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsInstantiationExpressionType, symbol)
10949-
c.setStructuredTypeMembers(result, resolved.getMembers(), callSignatures, constructSignatures, resolved.indexInfos)
10950+
c.setStructuredTypeMembers(result, resolved.getMembers(), callSignatures, constructSignatures, resolved.getIndexInfos())
1095010951
result.AsInstantiationExpressionType().node = node
1095110952
return result
1095210953
}
@@ -16141,7 +16142,7 @@ func (c *Checker) cloneTypeAsModuleType(symbol *ast.Symbol, moduleType *Type, re
1614116142
links.target = symbol
1614216143
links.originatingImport = referenceParent
1614316144
resolvedModuleType := c.resolveStructuredTypeMembers(moduleType)
16144-
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.getMembers(), nil, nil, resolvedModuleType.indexInfos)
16145+
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.getMembers(), nil, nil, resolvedModuleType.getIndexInfos())
1614516146
return result
1614616147
}
1614716148

@@ -19405,10 +19406,13 @@ func (c *Checker) getSignaturesOfStructuredType(t *Type, kind SignatureKind) []*
1940519406
return nil
1940619407
}
1940719408
resolved := c.resolveStructuredTypeMembers(t)
19409+
if resolved.extra == nil {
19410+
return nil
19411+
}
1940819412
if kind == SignatureKindCall {
19409-
return resolved.signatures[:resolved.callSignatureCount]
19413+
return resolved.extra.signatures[:resolved.extra.callSignatureCount]
1941019414
}
19411-
return resolved.signatures[resolved.callSignatureCount:]
19415+
return resolved.extra.signatures[resolved.extra.callSignatureCount:]
1941219416
}
1941319417

1941419418
func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo {
@@ -19417,7 +19421,7 @@ func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo {
1941719421

1941819422
func (c *Checker) getIndexInfosOfStructuredType(t *Type) []*IndexInfo {
1941919423
if t.flags&TypeFlagsStructuredType != 0 {
19420-
return c.resolveStructuredTypeMembers(t).indexInfos
19424+
return c.resolveStructuredTypeMembers(t).getIndexInfos()
1942119425
}
1942219426
return nil
1942319427
}
@@ -19813,7 +19817,7 @@ func (c *Checker) getSingleCallOrConstructSignature(t *Type) *Signature {
1981319817
func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers bool) *Signature {
1981419818
if t.flags&TypeFlagsObject != 0 {
1981519819
resolved := c.resolveStructuredTypeMembers(t)
19816-
if allowMembers || len(resolved.properties) == 0 && len(resolved.indexInfos) == 0 {
19820+
if allowMembers || len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 {
1981719821
if kind == SignatureKindCall && len(resolved.CallSignatures()) == 1 && len(resolved.ConstructSignatures()) == 0 {
1981819822
return resolved.CallSignatures()[0]
1981919823
}
@@ -21166,14 +21170,20 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) {
2116621170
indexInfos = append(indexInfos, c.enumNumberIndexInfo)
2116721171
}
2116821172
}
21169-
d.indexInfos = indexInfos
21173+
if indexInfos != nil || d.extra != nil {
21174+
d.ensureExtra(c).indexInfos = indexInfos
21175+
}
2117021176
// We resolve the members before computing the signatures because a signature may use
2117121177
// typeof with a qualified name expression that circularly references the type we are
2117221178
// in the process of resolving (see issue #6072). The temporarily empty signature list
2117321179
// will never be observed because a qualified name can't reference signatures.
2117421180
if symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 {
21175-
d.signatures = c.getSignaturesOfSymbol(symbol)
21176-
d.callSignatureCount = len(d.signatures)
21181+
signatures := c.getSignaturesOfSymbol(symbol)
21182+
if signatures != nil || d.extra != nil {
21183+
extra := d.ensureExtra(c)
21184+
extra.signatures = signatures
21185+
extra.callSignatureCount = len(signatures)
21186+
}
2117721187
}
2117821188
// And likewise for construct signatures for classes
2117921189
if symbol.Flags()&ast.SymbolFlagsClass != 0 {
@@ -21182,7 +21192,10 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) {
2118221192
if len(constructSignatures) == 0 {
2118321193
constructSignatures = c.getDefaultConstructSignatures(classType)
2118421194
}
21185-
d.signatures = append(d.signatures, constructSignatures...)
21195+
if len(constructSignatures) != 0 {
21196+
extra := d.ensureExtra(c)
21197+
extra.signatures = append(extra.signatures, constructSignatures...)
21198+
}
2118621199
}
2118721200
}
2118821201

@@ -25751,22 +25764,30 @@ func (c *Checker) setStructuredTypeMembers(t *Type, members ast.SymbolTable, cal
2575125764
} else {
2575225765
data.members = c.newMemberIndex(members, data.properties, data.members)
2575325766
}
25767+
c.setStructuredTypeSignatures(data, callSignatures, constructSignatures, indexInfos)
25768+
}
25769+
25770+
func (c *Checker) setStructuredTypeSignatures(data *StructuredType, callSignatures []*Signature, constructSignatures []*Signature, indexInfos []*IndexInfo) {
25771+
if data.extra == nil && callSignatures == nil && constructSignatures == nil && indexInfos == nil {
25772+
return
25773+
}
25774+
extra := data.ensureExtra(c)
2575425775
if len(callSignatures) != 0 {
2575525776
if len(constructSignatures) != 0 {
25756-
data.signatures = core.Concatenate(callSignatures, constructSignatures)
25777+
extra.signatures = core.Concatenate(callSignatures, constructSignatures)
2575725778
} else {
25758-
data.signatures = slices.Clip(callSignatures)
25779+
extra.signatures = slices.Clip(callSignatures)
2575925780
}
25760-
data.callSignatureCount = len(callSignatures)
25781+
extra.callSignatureCount = len(callSignatures)
2576125782
} else {
2576225783
if len(constructSignatures) != 0 {
25763-
data.signatures = slices.Clip(constructSignatures)
25784+
extra.signatures = slices.Clip(constructSignatures)
2576425785
} else {
25765-
data.signatures = nil
25786+
extra.signatures = nil
2576625787
}
25767-
data.callSignatureCount = 0
25788+
extra.callSignatureCount = 0
2576825789
}
25769-
data.indexInfos = slices.Clip(indexInfos)
25790+
extra.indexInfos = slices.Clip(indexInfos)
2577025791
}
2577125792

2577225793
func (c *Checker) newTypeParameter(symbol *ast.Symbol) *Type {
@@ -27096,7 +27117,7 @@ func (c *Checker) IsEmptyAnonymousObjectType(t *Type) bool {
2709627117
}
2709727118

2709827119
func (c *Checker) isEmptyResolvedType(t *StructuredType) bool {
27099-
return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.signatures) == 0 && len(t.indexInfos) == 0
27120+
return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.getSignatures()) == 0 && len(t.getIndexInfos()) == 0
2710027121
}
2710127122

2710227123
func (c *Checker) isEmptyObjectType(t *Type) bool {
@@ -28480,7 +28501,7 @@ func (c *Checker) containsUndefinedType(t *Type) bool {
2848028501
}
2848128502

2848228503
func (c *Checker) typeHasCallOrConstructSignatures(t *Type) bool {
28483-
return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).signatures) != 0
28504+
return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).getSignatures()) != 0
2848428505
}
2848528506

2848628507
func (c *Checker) getNormalizedType(t *Type, writing bool) *Type {
@@ -28787,7 +28808,7 @@ func (c *Checker) getRegularTypeOfObjectLiteral(t *Type) *Type {
2878728808
}
2878828809
resolved := c.resolveStructuredTypeMembers(t)
2878928810
members := c.transformTypeOfMembers(t, c.getRegularTypeOfObjectLiteral)
28790-
regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.indexInfos)
28811+
regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.getIndexInfos())
2879128812
regular.flags = resolved.flags
2879228813
regular.objectFlags |= resolved.objectFlags & ^ObjectFlagsFreshLiteral
2879328814
c.cachedTypes[key] = regular
@@ -31780,7 +31801,7 @@ func (c *Checker) isFunctionObjectType(t *Type) bool {
3178031801
// We do a quick check for a "bind" property before performing the more expensive subtype
3178131802
// check. This gives us a quicker out in the common case where an object type is not a function.
3178231803
resolved := c.resolveStructuredTypeMembers(t)
31783-
return len(resolved.signatures) != 0 || resolved.getMember("bind") != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
31804+
return len(resolved.getSignatures()) != 0 || resolved.getMember("bind") != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
3178431805
}
3178531806

3178631807
func (c *Checker) getTypeWithFacts(t *Type, include TypeFacts) *Type {

‎tsc/internal/checker/nodebuilderimpl.go‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -566,19 +566,19 @@ func (b *NodeBuilderImpl) getResolvedTypeWithoutAbstractConstructSignatures(t *S
566566
if len(t.ConstructSignatures()) == 0 {
567567
return t.AsType()
568568
}
569-
if t.objectTypeWithoutAbstractConstructSignatures != nil {
570-
return t.objectTypeWithoutAbstractConstructSignatures
569+
if t.extra.objectTypeWithoutAbstractConstructSignatures != nil {
570+
return t.extra.objectTypeWithoutAbstractConstructSignatures
571571
}
572572
constructSignatures := core.Filter(t.ConstructSignatures(), func(signature *Signature) bool {
573573
return signature.flags&SignatureFlagsAbstract == 0
574574
})
575575
if len(constructSignatures) == len(t.ConstructSignatures()) {
576-
t.objectTypeWithoutAbstractConstructSignatures = t.AsType()
576+
t.extra.objectTypeWithoutAbstractConstructSignatures = t.AsType()
577577
return t.AsType()
578578
}
579-
typeCopy := b.ch.newAnonymousType(t.symbol, t.getMembers(), t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.indexInfos)
580-
t.objectTypeWithoutAbstractConstructSignatures = typeCopy
581-
typeCopy.AsStructuredType().objectTypeWithoutAbstractConstructSignatures = typeCopy
579+
typeCopy := b.ch.newAnonymousType(t.symbol, t.getMembers(), t.CallSignatures(), core.IfElse(len(constructSignatures) > 0, constructSignatures, []*Signature{}), t.getIndexInfos())
580+
t.extra.objectTypeWithoutAbstractConstructSignatures = typeCopy
581+
typeCopy.AsStructuredType().ensureExtra(b.ch).objectTypeWithoutAbstractConstructSignatures = typeCopy
582582
return typeCopy
583583
}
584584

@@ -2737,7 +2737,7 @@ func (b *NodeBuilderImpl) createTypeNodesFromResolvedType(resolvedType *Structur
27372737
}
27382738
typeElements = append(typeElements, b.signatureToSignatureDeclarationHelper(signature, ast.KindConstructSignature, nil))
27392739
}
2740-
for _, info := range resolvedType.indexInfos {
2740+
for _, info := range resolvedType.getIndexInfos() {
27412741
var typeNode *ast.TypeNode
27422742
if resolvedType.objectFlags&ObjectFlagsReverseMapped != 0 && b.ctx.flags&nodebuilder.FlagsAllowAnonymousIdentifier != 0 {
27432743
typeNode = b.createElidedInformationPlaceholder()
@@ -2794,7 +2794,7 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
27942794
resolved := b.ch.resolveStructuredTypeMembers(t)
27952795
callSigs := resolved.CallSignatures()
27962796
ctorSigs := resolved.ConstructSignatures()
2797-
if len(resolved.properties) == 0 && len(resolved.indexInfos) == 0 {
2797+
if len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 {
27982798
if len(callSigs) == 0 && len(ctorSigs) == 0 {
27992799
b.ctx.approximateLength += 2
28002800
result := b.f.NewTypeLiteralNode(b.f.NewNodeList([]*ast.Node{}))
@@ -2823,7 +2823,7 @@ func (b *NodeBuilderImpl) createTypeNodeFromObjectType(t *Type) *ast.TypeNode {
28232823
return b.ch.getOrCreateTypeFromSignature(s)
28242824
})
28252825
// count the number of type elements excluding abstract constructors
2826-
typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.indexInfos) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool {
2826+
typeElementCount := len(callSigs) + (len(ctorSigs) - len(abstractSignatures)) + len(resolved.getIndexInfos()) + core.IfElse(b.ctx.flags&nodebuilder.FlagsWriteClassExpressionAsTypeLiteral != 0, core.CountWhere(resolved.properties, func(p *ast.Symbol) bool {
28272827
return p.Flags()&ast.SymbolFlagsPrototype == 0
28282828
}), len(resolved.properties))
28292829
// don't include an empty object literal if there were no other static-side

‎tsc/internal/checker/relater.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -679,7 +679,7 @@ func (c *Checker) elaborateArrowFunction(node *ast.Node, source *Type, target *T
679679
func (c *Checker) isWeakType(t *Type) bool {
680680
if t.flags&TypeFlagsObject != 0 {
681681
resolved := c.resolveStructuredTypeMembers(t)
682-
return len(resolved.signatures) == 0 && len(resolved.indexInfos) == 0 && len(resolved.properties) > 0 && core.Every(resolved.properties, func(p *ast.Symbol) bool {
682+
return len(resolved.getSignatures()) == 0 && len(resolved.getIndexInfos()) == 0 && len(resolved.properties) > 0 && core.Every(resolved.properties, func(p *ast.Symbol) bool {
683683
return p.Flags()&ast.SymbolFlagsOptional != 0
684684
})
685685
}

‎tsc/internal/checker/types.go‎

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,8 +1097,12 @@ func (t *ConstrainedType) AsConstrainedType() *ConstrainedType { return t }
10971097

10981098
type StructuredType struct {
10991099
ConstrainedType
1100-
members *memberIndex
1101-
properties []*ast.Symbol
1100+
members *memberIndex
1101+
properties []*ast.Symbol
1102+
extra *structuredTypeExtra
1103+
}
1104+
1105+
type structuredTypeExtra struct {
11021106
signatures []*Signature // Signatures (call + construct)
11031107
callSignatureCount int // Count of call signatures
11041108
indexInfos []*IndexInfo
@@ -1109,11 +1113,38 @@ type StructuredType struct {
11091113
func (t *StructuredType) AsStructuredType() *StructuredType { return t }
11101114

11111115
func (t *StructuredType) CallSignatures() []*Signature {
1112-
return slices.Clip(t.signatures[:t.callSignatureCount])
1116+
if t.extra == nil {
1117+
return nil
1118+
}
1119+
return slices.Clip(t.extra.signatures[:t.extra.callSignatureCount])
11131120
}
11141121

11151122
func (t *StructuredType) ConstructSignatures() []*Signature {
1116-
return slices.Clip(t.signatures[t.callSignatureCount:])
1123+
if t.extra == nil {
1124+
return nil
1125+
}
1126+
return slices.Clip(t.extra.signatures[t.extra.callSignatureCount:])
1127+
}
1128+
1129+
func (t *StructuredType) getSignatures() []*Signature {
1130+
if t.extra == nil {
1131+
return nil
1132+
}
1133+
return t.extra.signatures
1134+
}
1135+
1136+
func (t *StructuredType) getIndexInfos() []*IndexInfo {
1137+
if t.extra == nil {
1138+
return nil
1139+
}
1140+
return t.extra.indexInfos
1141+
}
1142+
1143+
func (t *StructuredType) ensureExtra(c *Checker) *structuredTypeExtra {
1144+
if t.extra == nil {
1145+
t.extra = c.structuredTypeExtraArena.New()
1146+
}
1147+
return t.extra
11171148
}
11181149

11191150
func (t *StructuredType) Properties() []*ast.Symbol {

‎tsc/internal/checker/types_test.go‎

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,3 +431,53 @@ func TestStructuredMembersLookup(t *testing.T) {
431431
assert.Equal(t, member.getMember("different"), renamed)
432432
assert.Assert(t, member.getMember("original") == nil)
433433
}
434+
435+
func TestCompactStructuredTypeLayout(t *testing.T) {
436+
t.Parallel()
437+
assert.Equal(t, unsafe.Sizeof(StructuredType{}), unsafe.Sizeof(ConstrainedType{})+5*unsafe.Sizeof(uintptr(0)))
438+
}
439+
440+
func TestStructuredTypeExtra(t *testing.T) {
441+
t.Parallel()
442+
c, types := newCompositeTestChecker()
443+
data := c.newAnonymousType(nil, nil, nil, nil, nil).AsStructuredType()
444+
assert.Assert(t, data.extra == nil)
445+
assert.Assert(t, data.CallSignatures() == nil)
446+
assert.Assert(t, data.ConstructSignatures() == nil)
447+
assert.Assert(t, data.getIndexInfos() == nil)
448+
c.setStructuredTypeSignatures(data, nil, nil, nil)
449+
assert.Assert(t, data.extra == nil)
450+
451+
call := &Signature{}
452+
construct := &Signature{}
453+
info := &IndexInfo{keyType: types[0]}
454+
c.setStructuredTypeSignatures(data, []*Signature{call}, []*Signature{construct}, []*IndexInfo{info})
455+
assert.Equal(t, data.CallSignatures()[0], call)
456+
assert.Equal(t, data.ConstructSignatures()[0], construct)
457+
assert.Equal(t, cap(data.CallSignatures()), 1)
458+
assert.Equal(t, cap(data.ConstructSignatures()), 1)
459+
assert.Equal(t, data.getIndexInfos()[0], info)
460+
extra := data.extra
461+
extra.objectTypeWithoutAbstractConstructSignatures = types[2]
462+
for range 1024 {
463+
other := c.newAnonymousType(nil, nil, []*Signature{call}, nil, nil)
464+
assert.Assert(t, other.AsStructuredType().extra != extra)
465+
}
466+
runtime.GC()
467+
assert.Equal(t, data.CallSignatures()[0], call)
468+
assert.Equal(t, data.ConstructSignatures()[0], construct)
469+
assert.Equal(t, data.getIndexInfos()[0], info)
470+
assert.Equal(t, data.extra.objectTypeWithoutAbstractConstructSignatures, types[2])
471+
c.setStructuredTypeSignatures(data, nil, []*Signature{construct}, nil)
472+
assert.Equal(t, len(data.CallSignatures()), 0)
473+
assert.Equal(t, data.ConstructSignatures()[0], construct)
474+
assert.Assert(t, data.getIndexInfos() == nil)
475+
c.setStructuredTypeSignatures(data, nil, nil, nil)
476+
assert.Assert(t, data.CallSignatures() == nil)
477+
assert.Assert(t, data.ConstructSignatures() == nil)
478+
assert.Equal(t, data.extra, extra)
479+
assert.Equal(t, extra.objectTypeWithoutAbstractConstructSignatures, types[2])
480+
c.setStructuredTypeSignatures(data, nil, nil, []*IndexInfo{})
481+
assert.Assert(t, data.getIndexInfos() != nil)
482+
runtime.KeepAlive(c)
483+
}

0 commit comments

Comments
 (0)