Skip to content

Commit 17af03d

Browse files
committed
[Sema] Factor out InitializablePropertiesRequest
This serves as the backing request for both InitAccessorPropertiesRequest and MemberwiseInitPropertiesRequest, ensuring the former does not care about the init accessor is included in the memberwise initializer.
1 parent 302e803 commit 17af03d

File tree

3 files changed

+71
-23
lines changed

3 files changed

+71
-23
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1949,6 +1949,25 @@ class StoredPropertiesAndMissingMembersRequest :
19491949
bool isCached() const { return true; }
19501950
};
19511951

1952+
/// Request to obtain a list of properties that can be initalized.
1953+
class InitializablePropertiesRequest
1954+
: public SimpleRequest<InitializablePropertiesRequest,
1955+
ArrayRef<VarDecl *>(NominalTypeDecl *),
1956+
RequestFlags::Cached> {
1957+
public:
1958+
using SimpleRequest::SimpleRequest;
1959+
1960+
private:
1961+
friend SimpleRequest;
1962+
1963+
// Evaluation.
1964+
ArrayRef<VarDecl *> evaluate(Evaluator &evaluator,
1965+
NominalTypeDecl *decl) const;
1966+
1967+
public:
1968+
bool isCached() const { return true; }
1969+
};
1970+
19521971
/// Request to obtain a list of computed properties with init accesors
19531972
/// in the given nominal type.
19541973
class InitAccessorPropertiesRequest :

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,8 @@ SWIFT_REQUEST(TypeChecker, StoredPropertiesAndMissingMembersRequest,
336336
ArrayRef<Decl *>(NominalTypeDecl *), Cached, NoLocationInfo)
337337
SWIFT_REQUEST(TypeChecker, StoredPropertiesRequest,
338338
ArrayRef<VarDecl *>(NominalTypeDecl *), Cached, NoLocationInfo)
339+
SWIFT_REQUEST(TypeChecker, InitializablePropertiesRequest,
340+
ArrayRef<VarDecl *>(NominalTypeDecl *), Cached, NoLocationInfo)
339341
SWIFT_REQUEST(TypeChecker, InitAccessorPropertiesRequest,
340342
ArrayRef<VarDecl *>(NominalTypeDecl *),
341343
Cached, NoLocationInfo)

lib/Sema/TypeCheckStorage.cpp

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,51 @@ bool HasInitAccessorRequest::evaluate(Evaluator &evaluator,
322322
return var->getAccessor(AccessorKind::Init);
323323
}
324324

325+
ArrayRef<VarDecl *>
326+
InitializablePropertiesRequest::evaluate(Evaluator &evaluator,
327+
NominalTypeDecl *decl) const {
328+
IterableDeclContext *implDecl = decl->getImplementationContext();
329+
330+
if (!hasStoredProperties(decl, implDecl))
331+
return ArrayRef<VarDecl *>();
332+
333+
SmallVector<VarDecl *, 4> results;
334+
computeLoweredProperties(decl, implDecl, LoweredPropertiesReason::Memberwise);
335+
336+
auto maybeAddProperty = [&](VarDecl *var) {
337+
if (!var->getDeclContext()->isTypeContext() || var->isStatic())
338+
return;
339+
340+
if (var->getAttrs().hasAttribute<LazyAttr>() ||
341+
var->hasAttachedPropertyWrapper() || var->hasStorage() ||
342+
var->hasInitAccessor()) {
343+
results.push_back(var);
344+
}
345+
};
346+
347+
for (auto *member : decl->getMembers()) {
348+
if (auto *var = dyn_cast<VarDecl>(member))
349+
maybeAddProperty(var);
350+
351+
member->visitAuxiliaryDecls([&](Decl *auxDecl) {
352+
if (auto auxVar = dyn_cast<VarDecl>(auxDecl))
353+
maybeAddProperty(auxVar);
354+
});
355+
}
356+
357+
return decl->getASTContext().AllocateCopy(results);
358+
}
359+
325360
ArrayRef<VarDecl *>
326361
InitAccessorPropertiesRequest::evaluate(Evaluator &evaluator,
327362
NominalTypeDecl *decl) const {
363+
auto initableVars =
364+
evaluateOrDefault(evaluator, InitializablePropertiesRequest{decl}, {});
365+
if (initableVars.empty())
366+
return {};
367+
328368
SmallVector<VarDecl *, 4> results;
329-
for (auto var : decl->getMemberwiseInitProperties()) {
369+
for (auto *var : initableVars) {
330370
if (var->hasInitAccessor())
331371
results.push_back(var);
332372
}
@@ -336,25 +376,19 @@ InitAccessorPropertiesRequest::evaluate(Evaluator &evaluator,
336376

337377
ArrayRef<VarDecl *>
338378
MemberwiseInitPropertiesRequest::evaluate(Evaluator &evaluator,
339-
NominalTypeDecl *decl) const {
340-
IterableDeclContext *implDecl = decl->getImplementationContext();
341-
342-
if (!hasStoredProperties(decl, implDecl))
343-
return ArrayRef<VarDecl *>();
344-
345-
// Make sure we expand what we need to to get all of the properties.
346-
computeLoweredProperties(decl, implDecl, LoweredPropertiesReason::Memberwise);
379+
NominalTypeDecl *decl) const {
380+
auto initableVars =
381+
evaluateOrDefault(evaluator, InitializablePropertiesRequest{decl}, {});
382+
if (initableVars.empty())
383+
return {};
347384

348385
SmallVector<VarDecl *, 4> results;
349386
SmallPtrSet<VarDecl *, 4> subsumedViaInitAccessor;
350387

351-
auto maybeAddProperty = [&](VarDecl *var) {
388+
for (auto *var : initableVars) {
352389
// We only care about properties that are memberwise initialized.
353390
if (!var->isMemberwiseInitialized(/*preferDeclaredProperties=*/true))
354-
return;
355-
356-
// Add this property.
357-
results.push_back(var);
391+
continue;
358392

359393
// If this property has an init accessor, it subsumes all of the stored properties
360394
// that the accessor initializes. Mark those stored properties as being subsumed; we'll
@@ -364,16 +398,9 @@ MemberwiseInitPropertiesRequest::evaluate(Evaluator &evaluator,
364398
subsumedViaInitAccessor.insert(subsumed);
365399
}
366400
}
367-
};
368-
369-
for (auto *member : decl->getCurrentMembers()) {
370-
if (auto *var = dyn_cast<VarDecl>(member))
371-
maybeAddProperty(var);
372401

373-
member->visitAuxiliaryDecls([&](Decl *auxDecl) {
374-
if (auto auxVar = dyn_cast<VarDecl>(auxDecl))
375-
maybeAddProperty(auxVar);
376-
});
402+
// Add this property.
403+
results.push_back(var);
377404
}
378405

379406
// If any properties were subsumed via init accessors, drop them from the list.

0 commit comments

Comments
 (0)