Skip to content

Commit 659894f

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 63f2f6e commit 659894f

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
freeTypeSets *temporaryTypeSet
689690
mergedSymbols map[*ast.Symbol]*ast.Symbol
690691
mergedExportsChecked collections.Set[*ast.Symbol]
@@ -4604,7 +4605,7 @@ func (c *Checker) getTypeWithoutSignatures(t *Type) *Type {
46044605
switch {
46054606
case t.flags&TypeFlagsObject != 0:
46064607
resolved := c.resolveStructuredTypeMembers(t)
4607-
if len(resolved.signatures) != 0 {
4608+
if len(resolved.getSignatures()) != 0 {
46084609
result := c.newObjectType(ObjectFlagsAnonymous, t.symbol)
46094610
result.objectFlags |= ObjectFlagsMembersResolved
46104611
result.AsObjectType().members = resolved.members
@@ -10944,7 +10945,7 @@ func (c *Checker) getInstantiationExpressionType(exprType *Type, node *ast.Node)
1094410945
debug.Assert(t.symbol != nil, "Instantiation expression source type must have a symbol")
1094510946
symbol.SetDeclarations(t.symbol.Declarations())
1094610947
result := c.newObjectType(ObjectFlagsAnonymous|ObjectFlagsInstantiationExpressionType, symbol)
10947-
c.setStructuredTypeMembers(result, resolved.members, callSignatures, constructSignatures, resolved.indexInfos)
10948+
c.setStructuredTypeMembers(result, resolved.members, callSignatures, constructSignatures, resolved.getIndexInfos())
1094810949
result.AsInstantiationExpressionType().node = node
1094910950
return result
1095010951
}
@@ -16139,7 +16140,7 @@ func (c *Checker) cloneTypeAsModuleType(symbol *ast.Symbol, moduleType *Type, re
1613916140
links.target = symbol
1614016141
links.originatingImport = referenceParent
1614116142
resolvedModuleType := c.resolveStructuredTypeMembers(moduleType)
16142-
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.members, nil, nil, resolvedModuleType.indexInfos)
16143+
c.valueSymbolLinks.Get(result).resolvedType = c.newAnonymousType(result, resolvedModuleType.members, nil, nil, resolvedModuleType.getIndexInfos())
1614316144
return result
1614416145
}
1614516146

@@ -19403,10 +19404,13 @@ func (c *Checker) getSignaturesOfStructuredType(t *Type, kind SignatureKind) []*
1940319404
return nil
1940419405
}
1940519406
resolved := c.resolveStructuredTypeMembers(t)
19407+
if resolved.extra == nil {
19408+
return nil
19409+
}
1940619410
if kind == SignatureKindCall {
19407-
return resolved.signatures[:resolved.callSignatureCount]
19411+
return resolved.extra.signatures[:resolved.extra.callSignatureCount]
1940819412
}
19409-
return resolved.signatures[resolved.callSignatureCount:]
19413+
return resolved.extra.signatures[resolved.extra.callSignatureCount:]
1941019414
}
1941119415

1941219416
func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo {
@@ -19415,7 +19419,7 @@ func (c *Checker) getIndexInfosOfType(t *Type) []*IndexInfo {
1941519419

1941619420
func (c *Checker) getIndexInfosOfStructuredType(t *Type) []*IndexInfo {
1941719421
if t.flags&TypeFlagsStructuredType != 0 {
19418-
return c.resolveStructuredTypeMembers(t).indexInfos
19422+
return c.resolveStructuredTypeMembers(t).getIndexInfos()
1941919423
}
1942019424
return nil
1942119425
}
@@ -19788,7 +19792,7 @@ func (c *Checker) getSingleCallOrConstructSignature(t *Type) *Signature {
1978819792
func (c *Checker) getSingleSignature(t *Type, kind SignatureKind, allowMembers bool) *Signature {
1978919793
if t.flags&TypeFlagsObject != 0 {
1979019794
resolved := c.resolveStructuredTypeMembers(t)
19791-
if allowMembers || len(resolved.properties) == 0 && len(resolved.indexInfos) == 0 {
19795+
if allowMembers || len(resolved.properties) == 0 && len(resolved.getIndexInfos()) == 0 {
1979219796
if kind == SignatureKindCall && len(resolved.CallSignatures()) == 1 && len(resolved.ConstructSignatures()) == 0 {
1979319797
return resolved.CallSignatures()[0]
1979419798
}
@@ -21141,14 +21145,20 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) {
2114121145
indexInfos = append(indexInfos, c.enumNumberIndexInfo)
2114221146
}
2114321147
}
21144-
d.indexInfos = indexInfos
21148+
if indexInfos != nil || d.extra != nil {
21149+
d.ensureExtra(c).indexInfos = indexInfos
21150+
}
2114521151
// We resolve the members before computing the signatures because a signature may use
2114621152
// typeof with a qualified name expression that circularly references the type we are
2114721153
// in the process of resolving (see issue #6072). The temporarily empty signature list
2114821154
// will never be observed because a qualified name can't reference signatures.
2114921155
if symbol.Flags()&(ast.SymbolFlagsFunction|ast.SymbolFlagsMethod) != 0 {
21150-
d.signatures = c.getSignaturesOfSymbol(symbol)
21151-
d.callSignatureCount = len(d.signatures)
21156+
signatures := c.getSignaturesOfSymbol(symbol)
21157+
if signatures != nil || d.extra != nil {
21158+
extra := d.ensureExtra(c)
21159+
extra.signatures = signatures
21160+
extra.callSignatureCount = len(signatures)
21161+
}
2115221162
}
2115321163
// And likewise for construct signatures for classes
2115421164
if symbol.Flags()&ast.SymbolFlagsClass != 0 {
@@ -21157,7 +21167,10 @@ func (c *Checker) resolveAnonymousTypeMembers(t *Type) {
2115721167
if len(constructSignatures) == 0 {
2115821168
constructSignatures = c.getDefaultConstructSignatures(classType)
2115921169
}
21160-
d.signatures = append(d.signatures, constructSignatures...)
21170+
if len(constructSignatures) != 0 {
21171+
extra := d.ensureExtra(c)
21172+
extra.signatures = append(extra.signatures, constructSignatures...)
21173+
}
2116121174
}
2116221175
}
2116321176

@@ -25716,22 +25729,30 @@ func (c *Checker) setStructuredTypeMembers(t *Type, members ast.SymbolTable, cal
2571625729
data := t.AsStructuredType()
2571725730
data.members = members
2571825731
data.properties = c.getNamedMembers(members, t.symbol)
25732+
c.setStructuredTypeSignatures(data, callSignatures, constructSignatures, indexInfos)
25733+
}
25734+
25735+
func (c *Checker) setStructuredTypeSignatures(data *StructuredType, callSignatures []*Signature, constructSignatures []*Signature, indexInfos []*IndexInfo) {
25736+
if data.extra == nil && callSignatures == nil && constructSignatures == nil && indexInfos == nil {
25737+
return
25738+
}
25739+
extra := data.ensureExtra(c)
2571925740
if len(callSignatures) != 0 {
2572025741
if len(constructSignatures) != 0 {
25721-
data.signatures = core.Concatenate(callSignatures, constructSignatures)
25742+
extra.signatures = core.Concatenate(callSignatures, constructSignatures)
2572225743
} else {
25723-
data.signatures = slices.Clip(callSignatures)
25744+
extra.signatures = slices.Clip(callSignatures)
2572425745
}
25725-
data.callSignatureCount = len(callSignatures)
25746+
extra.callSignatureCount = len(callSignatures)
2572625747
} else {
2572725748
if len(constructSignatures) != 0 {
25728-
data.signatures = slices.Clip(constructSignatures)
25749+
extra.signatures = slices.Clip(constructSignatures)
2572925750
} else {
25730-
data.signatures = nil
25751+
extra.signatures = nil
2573125752
}
25732-
data.callSignatureCount = 0
25753+
extra.callSignatureCount = 0
2573325754
}
25734-
data.indexInfos = slices.Clip(indexInfos)
25755+
extra.indexInfos = slices.Clip(indexInfos)
2573525756
}
2573625757

2573725758
func (c *Checker) newTypeParameter(symbol *ast.Symbol) *Type {
@@ -27061,7 +27082,7 @@ func (c *Checker) IsEmptyAnonymousObjectType(t *Type) bool {
2706127082
}
2706227083

2706327084
func (c *Checker) isEmptyResolvedType(t *StructuredType) bool {
27064-
return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.signatures) == 0 && len(t.indexInfos) == 0
27085+
return t.AsType() != c.anyFunctionType && len(t.properties) == 0 && len(t.getSignatures()) == 0 && len(t.getIndexInfos()) == 0
2706527086
}
2706627087

2706727088
func (c *Checker) isEmptyObjectType(t *Type) bool {
@@ -28445,7 +28466,7 @@ func (c *Checker) containsUndefinedType(t *Type) bool {
2844528466
}
2844628467

2844728468
func (c *Checker) typeHasCallOrConstructSignatures(t *Type) bool {
28448-
return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).signatures) != 0
28469+
return t.flags&TypeFlagsStructuredType != 0 && len(c.resolveStructuredTypeMembers(t).getSignatures()) != 0
2844928470
}
2845028471

2845128472
func (c *Checker) getNormalizedType(t *Type, writing bool) *Type {
@@ -28752,7 +28773,7 @@ func (c *Checker) getRegularTypeOfObjectLiteral(t *Type) *Type {
2875228773
}
2875328774
resolved := c.resolveStructuredTypeMembers(t)
2875428775
members := c.transformTypeOfMembers(t, c.getRegularTypeOfObjectLiteral)
28755-
regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.indexInfos)
28776+
regular := c.newAnonymousType(t.symbol, members, resolved.CallSignatures(), resolved.ConstructSignatures(), resolved.getIndexInfos())
2875628777
regular.flags = resolved.flags
2875728778
regular.objectFlags |= resolved.objectFlags & ^ObjectFlagsFreshLiteral
2875828779
c.cachedTypes[key] = regular
@@ -31745,7 +31766,7 @@ func (c *Checker) isFunctionObjectType(t *Type) bool {
3174531766
// We do a quick check for a "bind" property before performing the more expensive subtype
3174631767
// check. This gives us a quicker out in the common case where an object type is not a function.
3174731768
resolved := c.resolveStructuredTypeMembers(t)
31748-
return len(resolved.signatures) != 0 || resolved.members["bind"] != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
31769+
return len(resolved.getSignatures()) != 0 || resolved.members["bind"] != nil && c.isTypeSubtypeOf(t, c.globalFunctionType)
3174931770
}
3175031771

3175131772
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.members, 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.members, 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
@@ -1096,8 +1096,12 @@ func (t *ConstrainedType) AsConstrainedType() *ConstrainedType { return t }
10961096

10971097
type StructuredType struct {
10981098
ConstrainedType
1099-
members ast.SymbolTable
1100-
properties []*ast.Symbol
1099+
members ast.SymbolTable
1100+
properties []*ast.Symbol
1101+
extra *structuredTypeExtra
1102+
}
1103+
1104+
type structuredTypeExtra struct {
11011105
signatures []*Signature // Signatures (call + construct)
11021106
callSignatureCount int // Count of call signatures
11031107
indexInfos []*IndexInfo
@@ -1108,11 +1112,38 @@ type StructuredType struct {
11081112
func (t *StructuredType) AsStructuredType() *StructuredType { return t }
11091113

11101114
func (t *StructuredType) CallSignatures() []*Signature {
1111-
return slices.Clip(t.signatures[:t.callSignatureCount])
1115+
if t.extra == nil {
1116+
return nil
1117+
}
1118+
return slices.Clip(t.extra.signatures[:t.extra.callSignatureCount])
11121119
}
11131120

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

11181149
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
@@ -391,3 +391,53 @@ func TestCompactValueSymbolLinksLayout(t *testing.T) {
391391
assert.Equal(t, links.getWriteType(), types[0])
392392
assert.Equal(t, links.getContainingType(), types[2])
393393
}
394+
395+
func TestCompactStructuredTypeLayout(t *testing.T) {
396+
t.Parallel()
397+
assert.Equal(t, unsafe.Sizeof(StructuredType{}), unsafe.Sizeof(ConstrainedType{})+5*unsafe.Sizeof(uintptr(0)))
398+
}
399+
400+
func TestStructuredTypeExtra(t *testing.T) {
401+
t.Parallel()
402+
c, types := newCompositeTestChecker()
403+
data := c.newAnonymousType(nil, nil, nil, nil, nil).AsStructuredType()
404+
assert.Assert(t, data.extra == nil)
405+
assert.Assert(t, data.CallSignatures() == nil)
406+
assert.Assert(t, data.ConstructSignatures() == nil)
407+
assert.Assert(t, data.getIndexInfos() == nil)
408+
c.setStructuredTypeSignatures(data, nil, nil, nil)
409+
assert.Assert(t, data.extra == nil)
410+
411+
call := &Signature{}
412+
construct := &Signature{}
413+
info := &IndexInfo{keyType: types[0]}
414+
c.setStructuredTypeSignatures(data, []*Signature{call}, []*Signature{construct}, []*IndexInfo{info})
415+
assert.Equal(t, data.CallSignatures()[0], call)
416+
assert.Equal(t, data.ConstructSignatures()[0], construct)
417+
assert.Equal(t, cap(data.CallSignatures()), 1)
418+
assert.Equal(t, cap(data.ConstructSignatures()), 1)
419+
assert.Equal(t, data.getIndexInfos()[0], info)
420+
extra := data.extra
421+
extra.objectTypeWithoutAbstractConstructSignatures = types[2]
422+
for range 1024 {
423+
other := c.newAnonymousType(nil, nil, []*Signature{call}, nil, nil)
424+
assert.Assert(t, other.AsStructuredType().extra != extra)
425+
}
426+
runtime.GC()
427+
assert.Equal(t, data.CallSignatures()[0], call)
428+
assert.Equal(t, data.ConstructSignatures()[0], construct)
429+
assert.Equal(t, data.getIndexInfos()[0], info)
430+
assert.Equal(t, data.extra.objectTypeWithoutAbstractConstructSignatures, types[2])
431+
c.setStructuredTypeSignatures(data, nil, []*Signature{construct}, nil)
432+
assert.Equal(t, len(data.CallSignatures()), 0)
433+
assert.Equal(t, data.ConstructSignatures()[0], construct)
434+
assert.Assert(t, data.getIndexInfos() == nil)
435+
c.setStructuredTypeSignatures(data, nil, nil, nil)
436+
assert.Assert(t, data.CallSignatures() == nil)
437+
assert.Assert(t, data.ConstructSignatures() == nil)
438+
assert.Equal(t, data.extra, extra)
439+
assert.Equal(t, extra.objectTypeWithoutAbstractConstructSignatures, types[2])
440+
c.setStructuredTypeSignatures(data, nil, nil, []*IndexInfo{})
441+
assert.Assert(t, data.getIndexInfos() != nil)
442+
runtime.KeepAlive(c)
443+
}

0 commit comments

Comments
 (0)