mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Property delegates] Implicit initialization for properties with delegates.
When a property delegate type has a default initializer, use that to implicitly initialize properties that use that delegate and do not have their own initializers. For example, this would allow (e.g.), delegate types like the DelayedImmutable and DelayedMutable examples to drop the explicit initialization, e.g., ``` @DelayedMutable var foo: Int ``` would be implicitly initialized via ``` $foo = DelayedMutable() ``` This is a simplistic implementation that does not yet propertly handle definite initialization. Fixes rdar://problem/50266039.
This commit is contained in:
@@ -1520,6 +1520,23 @@ static VarDecl *synthesizePropertyDelegateStorageDelegateProperty(
|
||||
return property;
|
||||
}
|
||||
|
||||
static void typeCheckSynthesizedDelegateInitializer(
|
||||
PatternBindingDecl *pbd, VarDecl *backingVar, PatternBindingDecl *parentPBD,
|
||||
Expr *&initializer) {
|
||||
DeclContext *dc = pbd->getDeclContext();
|
||||
ASTContext &ctx = dc->getASTContext();
|
||||
|
||||
// Type-check the initialization.
|
||||
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
|
||||
tc.typeCheckExpression(initializer, dc);
|
||||
if (auto initializerContext =
|
||||
dyn_cast_or_null<Initializer>(
|
||||
pbd->getPatternEntryForVarDecl(backingVar).getInitContext())) {
|
||||
tc.contextualizeInitializer(initializerContext, initializer);
|
||||
}
|
||||
tc.checkPropertyDelegateErrorHandling(pbd, initializer);
|
||||
}
|
||||
|
||||
llvm::Expected<PropertyDelegateBackingPropertyInfo>
|
||||
PropertyDelegateBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
|
||||
VarDecl *var) const {
|
||||
@@ -1589,14 +1606,6 @@ PropertyDelegateBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
|
||||
|
||||
tc.typeCheckPatternBinding(parentPBD, patternNumber);
|
||||
}
|
||||
|
||||
Expr *originalInitialValue = nullptr;
|
||||
if (Expr *init = parentPBD->getInit(patternNumber)) {
|
||||
pbd->setInit(0, init);
|
||||
pbd->setInitializerChecked(0);
|
||||
originalInitialValue = findOriginalPropertyDelegateInitialValue(var, init);
|
||||
}
|
||||
|
||||
// Mark the backing property as 'final'. There's no sensible way to override.
|
||||
if (dc->getSelfClassDecl())
|
||||
makeFinal(ctx, backingVar);
|
||||
@@ -1616,6 +1625,23 @@ PropertyDelegateBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
|
||||
std::min(defaultAccess, var->getSetterFormalAccess());
|
||||
backingVar->overwriteSetterAccess(setterAccess);
|
||||
|
||||
Expr *originalInitialValue = nullptr;
|
||||
if (Expr *init = parentPBD->getInit(patternNumber)) {
|
||||
pbd->setInit(0, init);
|
||||
pbd->setInitializerChecked(0);
|
||||
originalInitialValue = findOriginalPropertyDelegateInitialValue(var, init);
|
||||
} else if (!parentPBD->isInitialized(patternNumber) &&
|
||||
delegateInfo.defaultInit) {
|
||||
// FIXME: Record this expression somewhere so that DI can perform the
|
||||
// initialization itself.
|
||||
auto typeExpr = TypeExpr::createImplicit(storageType, ctx);
|
||||
Expr *initializer = CallExpr::createImplicit(ctx, typeExpr, {}, { });
|
||||
typeCheckSynthesizedDelegateInitializer(pbd, backingVar, parentPBD,
|
||||
initializer);
|
||||
pbd->setInit(0, initializer);
|
||||
pbd->setInitializerChecked(0);
|
||||
}
|
||||
|
||||
// If there is a storage delegate property (delegateVar) in the delegate,
|
||||
// synthesize a computed property for '$foo'.
|
||||
VarDecl *storageVar = nullptr;
|
||||
@@ -1640,16 +1666,9 @@ PropertyDelegateBackingPropertyInfoRequest::evaluate(Evaluator &evaluator,
|
||||
Expr *initializer =
|
||||
CallExpr::createImplicit(ctx, typeExpr, {origValue},
|
||||
{ctx.Id_initialValue});
|
||||
typeCheckSynthesizedDelegateInitializer(pbd, backingVar, parentPBD,
|
||||
initializer);
|
||||
|
||||
// Type-check the initialization.
|
||||
auto &tc = *static_cast<TypeChecker *>(ctx.getLazyResolver());
|
||||
tc.typeCheckExpression(initializer, dc);
|
||||
if (auto initializerContext =
|
||||
dyn_cast_or_null<Initializer>(
|
||||
pbd->getPatternEntryForVarDecl(backingVar).getInitContext())) {
|
||||
tc.contextualizeInitializer(initializerContext, initializer);
|
||||
}
|
||||
tc.checkPropertyDelegateErrorHandling(parentPBD, initializer);
|
||||
return PropertyDelegateBackingPropertyInfo(
|
||||
backingVar, storageVar, originalInitialValue, initializer, origValue);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user