Skip to content

Commit

Permalink
cache members of composite types and interface types
Browse files Browse the repository at this point in the history
  • Loading branch information
turbolent committed Feb 18, 2021
1 parent 6b56ff1 commit fc98b38
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 48 deletions.
2 changes: 1 addition & 1 deletion runtime/sema/check_composite_declaration.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,7 +584,7 @@ func (checker *Checker) declareCompositeMembersAndValue(
continue
}

nestedCompositeType.AddImplicitTypeRequirementConformance(typeRequirement)
nestedCompositeType.addImplicitTypeRequirementConformance(typeRequirement)
}
})

Expand Down
112 changes: 65 additions & 47 deletions runtime/sema/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -4760,6 +4760,8 @@ type CompositeType struct {
ExplicitInterfaceConformances []*InterfaceType
ImplicitTypeRequirementConformances []*CompositeType
Members *StringMemberOrderedMap
memberResolversOnce sync.Once
memberResolvers map[string]MemberResolver
Fields []string
// TODO: add support for overloaded initializers
ConstructorParameters []*Parameter
Expand All @@ -4785,7 +4787,7 @@ func (t *CompositeType) initializeExplicitInterfaceConformanceSet() {
})
}

func (t *CompositeType) AddImplicitTypeRequirementConformance(typeRequirement *CompositeType) {
func (t *CompositeType) addImplicitTypeRequirementConformance(typeRequirement *CompositeType) {
t.ImplicitTypeRequirementConformances =
append(t.ImplicitTypeRequirementConformances, typeRequirement)
}
Expand Down Expand Up @@ -4831,35 +4833,8 @@ func (t *CompositeType) Equal(other Type) bool {
}

func (t *CompositeType) GetMembers() map[string]MemberResolver {
// TODO: optimize
members := make(map[string]MemberResolver, t.Members.Len())
t.Members.Foreach(func(name string, loopMember *Member) {
// NOTE: don't capture loop variable
member := loopMember
members[name] = MemberResolver{
Kind: member.DeclarationKind,
Resolve: func(_ string, _ ast.Range, _ func(error)) *Member {
return member
},
}
})

// Check conformances.
// If this composite type results from a normal composite declaration,
// it must have members declared for all interfaces it conforms to.
// However, if this composite type is a type requirement,
// it acts like an interface and does not have to declare members.

t.ExplicitInterfaceConformanceSet().
ForEach(func(conformance *InterfaceType) {
for name, resolver := range conformance.GetMembers() {
if _, ok := members[name]; !ok {
members[name] = resolver
}
}
})

return withBuiltinMembers(t, members)
t.initializeMemberResolvers()
return t.memberResolvers
}

func (t *CompositeType) IsResourceType() bool {
Expand Down Expand Up @@ -4982,6 +4957,40 @@ func (t *CompositeType) NestedTypes() *StringTypeOrderedMap {
return t.nestedTypes
}

func (t *CompositeType) initializeMemberResolvers() {
t.memberResolversOnce.Do(func() {
members := make(map[string]MemberResolver, t.Members.Len())

t.Members.Foreach(func(name string, loopMember *Member) {
// NOTE: don't capture loop variable
member := loopMember
members[name] = MemberResolver{
Kind: member.DeclarationKind,
Resolve: func(_ string, _ ast.Range, _ func(error)) *Member {
return member
},
}
})

// Check conformances.
// If this composite type results from a normal composite declaration,
// it must have members declared for all interfaces it conforms to.
// However, if this composite type is a type requirement,
// it acts like an interface and does not have to declare members.

t.ExplicitInterfaceConformanceSet().
ForEach(func(conformance *InterfaceType) {
for name, resolver := range conformance.GetMembers() {
if _, ok := members[name]; !ok {
members[name] = resolver
}
}
})

t.memberResolvers = withBuiltinMembers(t, members)
})
}

// AuthAccountType represents the authorized access to an account.
// Access to an AuthAccount means having full access to its storage, public keys, and code.
// Only signed transactions can get the AuthAccount for an account.
Expand Down Expand Up @@ -5820,11 +5829,13 @@ func (m *Member) testType(test func(Type) bool, results map[*Member]bool) (resul
// InterfaceType

type InterfaceType struct {
Location common.Location
Identifier string
CompositeKind common.CompositeKind
Members *StringMemberOrderedMap
Fields []string
Location common.Location
Identifier string
CompositeKind common.CompositeKind
Members *StringMemberOrderedMap
memberResolversOnce sync.Once
memberResolvers map[string]MemberResolver
Fields []string
// TODO: add support for overloaded initializers
InitializerParameters []*Parameter
ContainerType Type
Expand Down Expand Up @@ -5872,19 +5883,26 @@ func (t *InterfaceType) Equal(other Type) bool {
}

func (t *InterfaceType) GetMembers() map[string]MemberResolver {
// TODO: optimize
members := make(map[string]MemberResolver, t.Members.Len())
t.Members.Foreach(func(name string, loopMember *Member) {
// NOTE: don't capture loop variable
member := loopMember
members[name] = MemberResolver{
Kind: member.DeclarationKind,
Resolve: func(_ string, _ ast.Range, _ func(error)) *Member {
return member
},
}
t.initializeMemberResolvers()
return t.memberResolvers
}

func (t *InterfaceType) initializeMemberResolvers() {
t.memberResolversOnce.Do(func() {
members := make(map[string]MemberResolver, t.Members.Len())
t.Members.Foreach(func(name string, loopMember *Member) {
// NOTE: don't capture loop variable
member := loopMember
members[name] = MemberResolver{
Kind: member.DeclarationKind,
Resolve: func(_ string, _ ast.Range, _ func(error)) *Member {
return member
},
}
})

t.memberResolvers = withBuiltinMembers(t, members)
})
return withBuiltinMembers(t, members)
}

func (t *InterfaceType) IsResourceType() bool {
Expand Down

0 comments on commit fc98b38

Please sign in to comment.