Skip to content

Commit 39ce30c

Browse files
maschwenkclaude
andcommitted
Drop the partial member handling now that #64372 is in
resolveObjectTypeMembers no longer exposes a type's declared members while its base types resolve, so the lazy table doesn't need to either. A table is now either being prepared, during which the type resolves its members as usual, or ready; the materialized state, the count of inherited base types and the partial lookup paths go away. Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent 0a06ad9 commit 39ce30c

1 file changed

Lines changed: 63 additions & 156 deletions

File tree

‎tsc/internal/checker/checker.go‎

Lines changed: 63 additions & 156 deletions
Original file line numberDiff line numberDiff line change
@@ -19443,7 +19443,7 @@ func (c *Checker) resolveClassOrInterfaceMembers(t *Type) {
1944319443
}
1944419444

1944519445
func (c *Checker) resolveTypeReferenceMembers(t *Type) {
19446-
if lm := c.lazyMemberTables[t]; lm != nil && lm.state != lazyMembersResolvingDeclared {
19446+
if lm := c.lazyMemberTables[t]; lm != nil && lm.ready {
1944719447
c.resolveLazyMembers(t, lm)
1944819448
return
1944919449
}
@@ -19530,35 +19530,20 @@ func (c *Checker) appendInheritedSignaturesAndIndexInfos(callSignatures []*Signa
1953019530
// getIndexInfosOfStructuredType answer from the table. Member lookups
1953119531
// instantiate only the requested member, the way resolveObjectTypeMembers
1953219532
// would have when the table was prepared, and resolving the members in full
19533-
// later reuses the symbols already handed out.
19534-
//
19535-
// While resolveObjectTypeMembers resolves base types, the type exposes its
19536-
// declared members (see ObjectFlagsUnresolvedMembers). If preparing the table
19537-
// leads back to the type, the type is resolved in full at that point so it
19538-
// exposes the same members.
19539-
19540-
type lazyMembersState int
19541-
19542-
const (
19543-
lazyMembersResolvingDeclared lazyMembersState = iota // instantiating declared signatures and index infos, resolving base types
19544-
lazyMembersResolvingBases // instantiating base types and resolving their members
19545-
lazyMembersReady
19546-
lazyMembersMaterialized // resolved in full while base types were being resolved
19547-
)
19533+
// later reuses the symbols already handed out. While a table is being
19534+
// prepared, the type resolves its members as usual.
1954819535

1954919536
type lazyMemberTable struct {
19550-
state lazyMembersState
19537+
ready bool
1955119538
mapper *TypeMapper
1955219539
typeArguments []*Type
1955319540
unaffected []string // sorted names of declared members that instantiate to themselves
19554-
callSignatures []*Signature // declared, and once the table is ready, inherited
19541+
callSignatures []*Signature // declared and inherited
1955519542
constructSignatures []*Signature
1955619543
indexInfos []*IndexInfo
1955719544
baseTypes []*Type // instantiated base types
19558-
inheritedCount int // number of base types inherited from so far
1955919545
declared map[string]*ast.Symbol
1956019546
found map[string]*ast.Symbol // memoized lookups; nil means no such member
19561-
members ast.SymbolTable // once materialized
1956219547
}
1956319548

1956419549
// isUnresolvedInstantiatedReference reports whether t is a reference to a
@@ -19590,38 +19575,9 @@ func (c *Checker) getReferenceMemberTypeArguments(t *Type, source *Type) (typePa
1959019575
return typeParameters, typeArguments
1959119576
}
1959219577

19593-
// getLazyMemberTable returns the lazy member table of t, preparing it first if
19594-
// needed, or nil if t's members aren't resolved lazily. A table returned while
19595-
// it is still being prepared isn't ready.
19596-
func (c *Checker) getLazyMemberTable(t *Type) *lazyMemberTable {
19597-
if !isUnresolvedInstantiatedReference(t) {
19598-
return nil
19599-
}
19600-
if lm := c.lazyMemberTables[t]; lm != nil {
19601-
return lm
19602-
}
19603-
typeParameters, typeArguments := c.getReferenceMemberTypeArguments(t, t.Target())
19604-
if slices.Equal(typeParameters, typeArguments) {
19605-
return nil
19606-
}
19607-
// Resolving deferred type arguments may have led to t being resolved or
19608-
// prepared already. Like resolveObjectTypeMembers, which would then replace
19609-
// those members, prepare t (again) regardless.
19610-
lm := &lazyMemberTable{
19611-
mapper: newTypeMapper(typeParameters, typeArguments),
19612-
typeArguments: typeArguments,
19613-
declared: map[string]*ast.Symbol{},
19614-
found: map[string]*ast.Symbol{},
19615-
}
19616-
c.lazyMemberTables[t] = lm
19617-
c.prepareLazyMembers(t, lm)
19618-
if lm.state != lazyMembersReady {
19619-
return nil
19620-
}
19621-
return lm
19622-
}
19623-
19624-
// getReadyLazyMemberTable returns the lazy member table of t if it is ready.
19578+
// getReadyLazyMemberTable returns the lazy member table of t, preparing it
19579+
// first if needed, or nil if t's members aren't resolved lazily or the table
19580+
// is still being prepared.
1962519581
func (c *Checker) getReadyLazyMemberTable(t *Type) *lazyMemberTable {
1962619582
if !mayHaveLazyMembers(t) {
1962719583
return nil
@@ -19630,15 +19586,34 @@ func (c *Checker) getReadyLazyMemberTable(t *Type) *lazyMemberTable {
1963019586
}
1963119587

1963219588
func (c *Checker) getReadyLazyMemberTableWorker(t *Type) *lazyMemberTable {
19633-
if lm := c.getLazyMemberTable(t); lm != nil && lm.state == lazyMembersReady {
19634-
return lm
19589+
if !isUnresolvedInstantiatedReference(t) {
19590+
return nil
1963519591
}
19636-
return nil
19592+
lm := c.lazyMemberTables[t]
19593+
if lm == nil {
19594+
typeParameters, typeArguments := c.getReferenceMemberTypeArguments(t, t.Target())
19595+
if slices.Equal(typeParameters, typeArguments) {
19596+
return nil
19597+
}
19598+
lm = &lazyMemberTable{
19599+
mapper: newTypeMapper(typeParameters, typeArguments),
19600+
typeArguments: typeArguments,
19601+
declared: map[string]*ast.Symbol{},
19602+
found: map[string]*ast.Symbol{},
19603+
}
19604+
c.lazyMemberTables[t] = lm
19605+
c.prepareLazyMembers(t, lm)
19606+
}
19607+
if !lm.ready || t.objectFlags&ObjectFlagsMembersResolved != 0 {
19608+
return nil
19609+
}
19610+
return lm
1963719611
}
1963819612

19639-
// prepareLazyMembers mirrors resolveObjectTypeMembers, except that it only
19640-
// records which declared members would instantiate to themselves instead of
19641-
// instantiating them, and doesn't inherit members.
19613+
// prepareLazyMembers mirrors resolveObjectTypeMembers, except that it records
19614+
// which declared members would instantiate to themselves instead of
19615+
// instantiating them, and doesn't inherit members from base types with lazy
19616+
// member tables.
1964219617
func (c *Checker) prepareLazyMembers(t *Type, lm *lazyMemberTable) {
1964319618
source := t.Target()
1964419619
resolved := c.resolveDeclaredMembers(source)
@@ -19648,76 +19623,34 @@ func (c *Checker) prepareLazyMembers(t *Type, lm *lazyMemberTable) {
1964819623
}
1964919624
}
1965019625
slices.Sort(lm.unaffected)
19651-
lm.callSignatures = c.instantiateSignatures(resolved.declaredCallSignatures, lm.mapper)
19652-
lm.constructSignatures = c.instantiateSignatures(resolved.declaredConstructSignatures, lm.mapper)
19653-
lm.indexInfos = c.instantiateIndexInfos(resolved.declaredIndexInfos, lm.mapper)
19654-
baseTypes := c.getBaseTypes(source)
19655-
lm.state = lazyMembersResolvingBases
19656-
if t.objectFlags&ObjectFlagsMembersResolved != 0 {
19657-
// A lookup led to t being resolved in full; resolveObjectTypeMembers
19658-
// would now go on to replace those members with its own.
19659-
c.resolveLazyMembers(t, lm)
19660-
}
19661-
callSignatures, constructSignatures, indexInfos := lm.callSignatures, lm.constructSignatures, lm.indexInfos
19626+
callSignatures := c.instantiateSignatures(resolved.declaredCallSignatures, lm.mapper)
19627+
constructSignatures := c.instantiateSignatures(resolved.declaredConstructSignatures, lm.mapper)
19628+
indexInfos := c.instantiateIndexInfos(resolved.declaredIndexInfos, lm.mapper)
1966219629
thisArgument := core.LastOrNil(lm.typeArguments)
19663-
for _, baseType := range baseTypes {
19630+
for _, baseType := range c.getBaseTypes(source) {
1966419631
instantiatedBaseType := baseType
1966519632
if thisArgument != nil {
1966619633
instantiatedBaseType = c.getTypeWithThisArgument(c.instantiateType(baseType, lm.mapper), thisArgument, false /*needsApparentType*/)
1966719634
}
1966819635
lm.baseTypes = append(lm.baseTypes, instantiatedBaseType)
19669-
if lm.state == lazyMembersResolvingBases && !c.prepareBaseTypeMembers(instantiatedBaseType) {
19670-
// The base type's members are only partially resolved, and t must
19671-
// inherit them as they are now.
19672-
c.resolveLazyMembers(t, lm)
19673-
}
19674-
if lm.state == lazyMembersMaterialized {
19675-
lm.members = c.addInheritedMembers(lm.members, c.getPropertiesOfType(instantiatedBaseType))
19636+
if c.getReadyLazyMemberTable(c.getReducedApparentType(instantiatedBaseType)) == nil {
19637+
c.getPropertiesOfType(instantiatedBaseType)
1967619638
}
1967719639
callSignatures, constructSignatures, indexInfos = c.appendInheritedSignaturesAndIndexInfos(callSignatures, constructSignatures, indexInfos, instantiatedBaseType)
19678-
lm.inheritedCount++
1967919640
}
1968019641
lm.callSignatures, lm.constructSignatures, lm.indexInfos = callSignatures, constructSignatures, indexInfos
19681-
if lm.state == lazyMembersMaterialized {
19682-
t.objectFlags &^= ObjectFlagsUnresolvedMembers
19683-
c.setStructuredTypeMembers(t, lm.members, callSignatures, constructSignatures, indexInfos)
19684-
delete(c.lazyMemberTables, t)
19685-
return
19686-
}
19687-
lm.state = lazyMembersReady
19688-
}
19689-
19690-
// prepareBaseTypeMembers resolves the members of an instantiated base type as
19691-
// inheriting from it in resolveObjectTypeMembers would. It returns false, and
19692-
// leaves that to the caller, when those members are only partially resolved.
19693-
func (c *Checker) prepareBaseTypeMembers(baseType *Type) bool {
19694-
if baseType == c.anyType {
19695-
return true
19696-
}
19697-
reduced := c.getReducedApparentType(baseType)
19698-
if reduced.flags&TypeFlagsObject != 0 {
19699-
if reduced.objectFlags&ObjectFlagsUnresolvedMembers != 0 {
19700-
return false
19701-
}
19702-
if lm := c.getLazyMemberTable(reduced); lm != nil {
19703-
return lm.state == lazyMembersReady
19704-
}
19642+
lm.ready = true
19643+
if t.objectFlags&ObjectFlagsMembersResolved != 0 {
19644+
// Preparing the table led to t being resolved in full, and
19645+
// resolveObjectTypeMembers would now replace those members.
19646+
c.resolveLazyMembers(t, lm)
1970519647
}
19706-
c.getPropertiesOfType(baseType)
19707-
c.getSignaturesOfType(baseType, SignatureKindCall)
19708-
c.getSignaturesOfType(baseType, SignatureKindConstruct)
19709-
c.getIndexInfosOfType(baseType)
19710-
return true
1971119648
}
1971219649

19713-
// resolveLazyMembers resolves the members of t, whose lazy member table was
19714-
// prepared, as resolveObjectTypeMembers does. While the table's base types are
19715-
// still being prepared, it only exposes the members inherited so far, like
19716-
// resolveObjectTypeMembers would at that point, and prepareLazyMembers
19717-
// finishes the job.
19650+
// resolveLazyMembers resolves the members of t from its lazy member table, as
19651+
// resolveObjectTypeMembers does.
1971819652
func (c *Checker) resolveLazyMembers(t *Type, lm *lazyMemberTable) {
19719-
source := t.Target()
19720-
resolved := c.resolveDeclaredMembers(source)
19653+
resolved := c.resolveDeclaredMembers(t.Target())
1972119654
var members ast.SymbolTable
1972219655
if len(resolved.declaredMembers) != 0 {
1972319656
members = make(ast.SymbolTable, len(resolved.declaredMembers))
@@ -19727,19 +19660,9 @@ func (c *Checker) resolveLazyMembers(t *Type, lm *lazyMemberTable) {
1972719660
}
1972819661
}
1972919662
}
19730-
if len(c.getBaseTypes(source)) != 0 {
19731-
c.setStructuredTypeMembers(t, members, lm.callSignatures, lm.constructSignatures, lm.indexInfos)
19732-
t.objectFlags |= ObjectFlagsUnresolvedMembers
19733-
for _, baseType := range lm.baseTypes[:lm.inheritedCount] {
19734-
members = c.addInheritedMembers(members, c.getPropertiesOfType(baseType))
19735-
}
19736-
}
19737-
if lm.state != lazyMembersReady {
19738-
lm.state = lazyMembersMaterialized
19739-
lm.members = members
19740-
return
19663+
for _, baseType := range lm.baseTypes {
19664+
members = c.addInheritedMembers(members, c.getPropertiesOfType(baseType))
1974119665
}
19742-
t.objectFlags &^= ObjectFlagsUnresolvedMembers
1974319666
c.setStructuredTypeMembers(t, members, lm.callSignatures, lm.constructSignatures, lm.indexInfos)
1974419667
delete(c.lazyMemberTables, t)
1974519668
}
@@ -19778,52 +19701,36 @@ func (c *Checker) getMemberOfStructuredType(t *Type, name string) *ast.Symbol {
1977819701
}
1977919702

1978019703
func (c *Checker) getMemberOfUnresolvedStructuredType(t *Type, name string) *ast.Symbol {
19781-
if symbol, ok := c.lookupMemberLazily(t, name); ok {
19782-
return symbol
19704+
if !isReservedMemberName(name) {
19705+
if lm := c.getReadyLazyMemberTable(t); lm != nil {
19706+
return c.lookupLazyMember(t, lm, name)
19707+
}
1978319708
}
1978419709
return c.resolveStructuredTypeMembers(t).members[name]
1978519710
}
1978619711

19787-
// lookupMemberLazily returns what resolveStructuredTypeMembers(t).members[name]
19788-
// would hold, without building t's member table. ok is false when the lazy
19789-
// path can't answer and the caller must resolve members normally.
19790-
func (c *Checker) lookupMemberLazily(t *Type, name string) (symbol *ast.Symbol, ok bool) {
19791-
if isReservedMemberName(name) {
19792-
return nil, false
19793-
}
19794-
lm := c.getLazyMemberTable(t)
19795-
if lm == nil || lm.state == lazyMembersResolvingDeclared {
19796-
return nil, false
19797-
}
19712+
// lookupLazyMember returns what resolveStructuredTypeMembers(t).members[name]
19713+
// would hold: the declared member, or else the property inherited from the
19714+
// first base type that has one, where a base may only fill a missing or
19715+
// non-value entry (addInheritedMembers).
19716+
func (c *Checker) lookupLazyMember(t *Type, lm *lazyMemberTable, name string) *ast.Symbol {
1979819717
if symbol, ok := lm.found[name]; ok {
19799-
return symbol, true
19718+
return symbol
1980019719
}
19801-
// Mirrors resolveObjectTypeMembers: declared named members first, then
19802-
// inherited properties, where a base may only fill a missing or non-value
19803-
// entry (addInheritedMembers).
19804-
resolved := c.resolveDeclaredMembers(t.Target())
1980519720
var result *ast.Symbol
19806-
if decl := resolved.declaredMembers[name]; decl != nil && c.isNamedMember(decl, name) {
19721+
if decl := c.resolveDeclaredMembers(t.Target()).declaredMembers[name]; decl != nil && c.isNamedMember(decl, name) {
1980719722
result = c.getLazyDeclaredMember(lm, decl, name)
1980819723
}
19809-
baseTypes := lm.baseTypes[:lm.inheritedCount]
19810-
if lm.state != lazyMembersReady && len(resolved.declaredMembers) == 0 {
19811-
// While base types are being resolved, resolveObjectTypeMembers only
19812-
// exposes inherited members through the table of declared members.
19813-
baseTypes = nil
19814-
}
19815-
for _, baseType := range baseTypes {
19724+
for _, baseType := range lm.baseTypes {
1981619725
if result != nil && result.Flags&ast.SymbolFlagsValue != 0 {
1981719726
break
1981819727
}
1981919728
if prop := c.getNamedPropertyOfType(baseType, name); prop != nil && isInheritableProperty(prop) {
1982019729
result = prop
1982119730
}
1982219731
}
19823-
if lm.state == lazyMembersReady {
19824-
lm.found[name] = result
19825-
}
19826-
return result, true
19732+
lm.found[name] = result
19733+
return result
1982719734
}
1982819735

1982919736
// getNamedPropertyOfType finds name among getPropertiesOfType(t).

0 commit comments

Comments
 (0)