[Distributed] Move property synthesis to DerivedConformanceDistributedActor

This commit is contained in:
Konrad `ktoso` Malawski
2021-08-25 21:22:29 +09:00
parent 0a0926ba7a
commit 90d8816dee
8 changed files with 147 additions and 95 deletions

View File

@@ -30,6 +30,101 @@ bool DerivedConformance::canDeriveDistributedActor(
}
// ==== ------------------------------------------------------------------------
// TODO: deduplicate with 'declareDerivedProperty' from DerivedConformance...
std::pair<VarDecl *, PatternBindingDecl *>
createStoredProperty(ClassDecl *classDecl, ASTContext &ctx,
VarDecl::Introducer introducer, Identifier name,
Type propertyInterfaceType, Type propertyContextType,
bool isStatic, bool isFinal) {
auto parentDC = classDecl;
VarDecl *propDecl = new (ctx)
VarDecl(/*IsStatic*/ isStatic, introducer,
SourceLoc(), name, parentDC);
propDecl->setImplicit();
propDecl->setSynthesized();
propDecl->copyFormalAccessFrom(classDecl, /*sourceIsParentContext*/ true);
propDecl->setInterfaceType(propertyInterfaceType);
Pattern *propPat = NamedPattern::createImplicit(ctx, propDecl);
propPat->setType(propertyContextType);
propPat = TypedPattern::createImplicit(ctx, propPat, propertyContextType);
propPat->setType(propertyContextType);
auto *pbDecl = PatternBindingDecl::createImplicit(
ctx, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
parentDC);
return {propDecl, pbDecl};
}
static ValueDecl *deriveDistributedActor_id(DerivedConformance &derived) {
assert(derived.Nominal->isDistributedActor());
auto decl = dyn_cast<ClassDecl>(derived.Nominal);
auto &C = derived.Context;
// ```
// @_distributedActorIndependent
// let id: AnyActorIdentity
// ```
auto propertyType = C.getAnyActorIdentityDecl()->getDeclaredInterfaceType();
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = createStoredProperty(
decl, C,
VarDecl::Introducer::Let, C.Id_id,
propertyType, propertyType,
/*isStatic=*/false, /*isFinal=*/true);
// mark as @_distributedActorIndependent, allowing access to it from everywhere
propDecl->getAttrs().add(
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
derived.addMembersToConformanceContext({ propDecl, pbDecl });
return propDecl;
}
static ValueDecl *deriveDistributedActor_actorTransport(
DerivedConformance &derived) {
assert(derived.Nominal->isDistributedActor());
auto decl = dyn_cast<ClassDecl>(derived.Nominal);
auto &C = derived.Context;
// ```
// @_distributedActorIndependent
// let actorTransport: ActorTransport
// ```
// (no need for @actorIndependent because it is an immutable let)
auto propertyType = C.getActorTransportDecl()->getDeclaredInterfaceType();
VarDecl *propDecl;
PatternBindingDecl *pbDecl;
std::tie(propDecl, pbDecl) = createStoredProperty(
decl, C,
VarDecl::Introducer::Let, C.Id_actorTransport,
propertyType, propertyType,
/*isStatic=*/false, /*isFinal=*/true);
// mark as @_distributedActorIndependent, allowing access to it from everywhere
propDecl->getAttrs().add(
new (C) DistributedActorIndependentAttr(/*IsImplicit=*/true));
derived.addMembersToConformanceContext({ propDecl, pbDecl });
return propDecl;
}
// ==== ------------------------------------------------------------------------
ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
if (auto var = dyn_cast<VarDecl>(requirement)) {
if (var->getName() == Context.Id_id)
return deriveDistributedActor_id(*this);
if (var->getName() == Context.Id_actorTransport)
return deriveDistributedActor_actorTransport(*this);
}
return nullptr;
}