mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[Sema] Requestify memberwise init synthesis
This commit adds two requests, one to compute whether or not a decl should have a memberwise initializer, and another to synthesize it.
This commit is contained in:
@@ -871,36 +871,14 @@ static void addImplicitConstructorsToStruct(StructDecl *decl) {
|
||||
"User-defined structs cannot have unreferenceable storage");
|
||||
|
||||
decl->setAddedImplicitInitializers();
|
||||
|
||||
// Check whether there is a user-declared constructor or an instance
|
||||
// variable.
|
||||
bool FoundMemberwiseInitializedProperty = false;
|
||||
(void)decl->getMemberwiseInitializer();
|
||||
|
||||
// If the user has already defined a designated initializer, then don't
|
||||
// synthesize an initializer.
|
||||
// synthesize a default initializer.
|
||||
auto &ctx = decl->getASTContext();
|
||||
if (hasUserDefinedDesignatedInit(ctx.evaluator, decl))
|
||||
return;
|
||||
|
||||
for (auto member : decl->getMembers()) {
|
||||
if (auto var = dyn_cast<VarDecl>(member)) {
|
||||
// If this is a backing storage property for a property wrapper,
|
||||
// skip it.
|
||||
if (var->getOriginalWrappedProperty())
|
||||
continue;
|
||||
|
||||
if (var->isMemberwiseInitialized(/*preferDeclaredProperties=*/true))
|
||||
FoundMemberwiseInitializedProperty = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (FoundMemberwiseInitializedProperty) {
|
||||
// Create the implicit memberwise constructor.
|
||||
auto ctor = createImplicitConstructor(
|
||||
decl, ImplicitConstructorKind::Memberwise, ctx);
|
||||
decl->addMember(ctor);
|
||||
}
|
||||
|
||||
if (areAllStoredPropertiesDefaultInitializable(ctx.evaluator, decl))
|
||||
TypeChecker::defineDefaultConstructor(decl);
|
||||
}
|
||||
@@ -1203,6 +1181,43 @@ void TypeChecker::synthesizeMemberForLookup(NominalTypeDecl *target,
|
||||
}
|
||||
}
|
||||
|
||||
llvm::Expected<bool>
|
||||
HasMemberwiseInitRequest::evaluate(Evaluator &evaluator,
|
||||
StructDecl *decl) const {
|
||||
// Don't synthesize a memberwise init for imported decls.
|
||||
if (decl->hasClangNode())
|
||||
return false;
|
||||
|
||||
// If the user has already defined a designated initializer, then don't
|
||||
// synthesize a memberwise init.
|
||||
if (hasUserDefinedDesignatedInit(evaluator, decl))
|
||||
return false;
|
||||
|
||||
for (auto *member : decl->getMembers()) {
|
||||
if (auto *var = dyn_cast<VarDecl>(member)) {
|
||||
// If this is a backing storage property for a property wrapper,
|
||||
// skip it.
|
||||
if (var->getOriginalWrappedProperty())
|
||||
continue;
|
||||
|
||||
if (var->isMemberwiseInitialized(/*preferDeclaredProperties=*/true))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
llvm::Expected<ConstructorDecl *>
|
||||
SynthesizeMemberwiseInitRequest::evaluate(Evaluator &evaluator,
|
||||
NominalTypeDecl *decl) const {
|
||||
// Create the implicit memberwise constructor.
|
||||
auto &ctx = decl->getASTContext();
|
||||
auto ctor =
|
||||
createImplicitConstructor(decl, ImplicitConstructorKind::Memberwise, ctx);
|
||||
decl->addMember(ctor);
|
||||
return ctor;
|
||||
}
|
||||
|
||||
/// Synthesizer callback for a function body consisting of "return".
|
||||
static std::pair<BraceStmt *, bool>
|
||||
synthesizeSingleReturnFunctionBody(AbstractFunctionDecl *afd, void *) {
|
||||
|
||||
Reference in New Issue
Block a user