[MemberLoading] Split storage and non-storage member loading#87065
[MemberLoading] Split storage and non-storage member loading#87065j-hui merged 3 commits intoswiftlang:mainfrom
Conversation
Restructure this function into a state-holding class with a recursive method, to make it easier to thread state around.
|
@swift-ci please test |
|
Please ignore the changes in
where I had to reorder a couple of members. (These ASTPrinter-related changes should disappear from the diff when #87026 / 9dc1174 lands) |
Doing so allows further granularity when lazily loading members.
7a4c932 to
155b794
Compare
|
@swift-ci please test |
155b794 to
f765ff4
Compare
|
@swift-ci please test |
| visitMember(actorSystemVar); | ||
| for (auto *member : implDecl->getMembers()) | ||
| implDecl->loadStorageMembers(); | ||
| for (auto *member : implDecl->getCurrentMembersWithoutLoading()) |
There was a problem hiding this comment.
Should enumerateStoredPropertiesAndMissing() be unified with computeLoweredProperties() in some way?
There was a problem hiding this comment.
Oh sure! I could do that if you think it'll benefit the code organization.
There was a problem hiding this comment.
Ok so I took a crack at this. I think it's certainly possible to unify enumerateStoredPropertiesAndMissing() and InitializablePropertiesRequest::evaluate(), and perhaps computeLoweredProperties().
However, I'm a bit hesitant to land such a change in this patch. For one thing, I wanted to keep this diff small and focused on the functional change, which is the removal of getMembers().
The other thing is that there are slight discrepancies between these functions. For instance, InitializablePropertiesRequest::evaluate() directly iterates through the members of decl, whereas the others iterate through decl's implementation context. There's also that knownStoredProperties set that prevents enumerateStoredPropertiesAndMissing() from visiting members more than once. I think these differences should be inconsequential, but I'm not confident and I don't know how best to validate this without spending some more time reading code.
Would it be alright if I punt this unification to a follow-up PR?
| }; | ||
|
|
||
| for (auto *member : decl->getMembers()) | ||
| decl->loadStorageMembers(); |
There was a problem hiding this comment.
This looks like another spot where we duplicate visiting stored properties and dealing with property wrappers and so on.
lib/AST/DeclContext.cpp
Outdated
|
|
||
| for (auto *existingMember : getMembers()) { | ||
| addParsedMembers(); | ||
| for (auto *existingMember : getCurrentMembersWithoutLoading()) { |
There was a problem hiding this comment.
It looks like addMemberPreservingSourceOrder() is only called in one place in the parser, can we assert here that getParentSourceFile() != nullptr? Or is it necessary to change this function at all? getMembers() should be the same as getParsedMembers() in this case.
There was a problem hiding this comment.
I didn't realize this was only called by the parser, specifically for IDE-related tasks. Using the tests from #87016, I confirmed that this doesn't seem to affect the importedd Clang decls case I'm ultimately interested in.
I'm happy to back out of this change.
There was a problem hiding this comment.
(And am happy to make this change in a follow-up if it makes sense.)
getStoredProperties() shouldn't call getMembers(), because can have the side effect of un-lazily loading everything. Instead, only ensure that storage-relevant members are loaded and iterate through those.
f765ff4 to
3b4a298
Compare
|
@swift-ci please test |
Hmm, I don't think this is related to this. |
|
@swift-ci please test windows platform |
1 similar comment
|
@swift-ci please test windows platform |
Xazax-hun
left a comment
There was a problem hiding this comment.
Overall looks great, thanks!
| /*lazyLoader=*/nullptr); | ||
| contextInfo->loader->loadAllMembers(const_cast<Decl *>(container), | ||
| contextInfo->memberData); | ||
| if (FirstDeclAndLazyMembers.getInt() == LazyMemberStatus::AllLoaded) |
There was a problem hiding this comment.
Would it make sense to move this check to the very front?
There was a problem hiding this comment.
Behaviorally speaking, doing so shouldn't make a difference to whether we call loadStorageMembers(), so the only impact would be whether this would have the side effect of adding parsed members when AddedParsedMembers is false. Originally, calling getMembers() would always have that side effect, and what I am doing here is preserving that behavior.
Unfortunately at this time I don't know enough about the scenarios where AddedParsedMembers is false to determine when it is safe to not call it, so I'd prefer to defer that to a follow-up PR.
getStoredProperties() shouldn't call getMembers(), because can have the side effect of un-lazily loading everything. Instead, only ensure that storage-relevant members are loaded and iterate through those.
This patch set builds on #87026 (which merged separately) to avoid the import order from catastrophically messing up every single module interface test (which happened anyway; see the mongo diff there).
This patch set is necessary for the lazy importing work in #87016.
rdar://156949141