@@ -28,36 +28,78 @@ bool DerivedConformance::canDeriveDistributedActor(
2828 auto classDecl = dyn_cast<ClassDecl>(nominal);
2929 return classDecl && classDecl->isDistributedActor () && dc == nominal;
3030}
31+
3132// ==== ------------------------------------------------------------------------
3233
33- // TODO: deduplicate with 'declareDerivedProperty' from DerivedConformance...
34- std::pair<VarDecl *, PatternBindingDecl *>
35- createStoredProperty (ClassDecl *classDecl, ASTContext &ctx,
36- VarDecl::Introducer introducer, Identifier name,
37- Type propertyInterfaceType, Type propertyContextType,
38- bool isStatic, bool isFinal) {
39- auto parentDC = classDecl;
40-
41- VarDecl *propDecl = new (ctx)
42- VarDecl (/* IsStatic*/ isStatic, introducer,
43- SourceLoc (), name, parentDC);
44- propDecl->setImplicit ();
45- propDecl->setSynthesized ();
46- propDecl->copyFormalAccessFrom (classDecl, /* sourceIsParentContext*/ true );
47- propDecl->setInterfaceType (propertyInterfaceType);
48-
49- Pattern *propPat = NamedPattern::createImplicit (ctx, propDecl);
50- propPat->setType (propertyContextType);
51-
52- propPat = TypedPattern::createImplicit (ctx, propPat, propertyContextType);
53- propPat->setType (propertyContextType);
54-
55- auto *pbDecl = PatternBindingDecl::createImplicit (
56- ctx, StaticSpellingKind::None, propPat, /* InitExpr*/ nullptr ,
57- parentDC);
58- return {propDecl, pbDecl};
34+ /* *****************************************************************************/
35+ /* ****************************** RESOLVE FUNCTION *****************************/
36+ /* *****************************************************************************/
37+
38+ // / Synthesizes the
39+ // /
40+ // / \verbatim
41+ // / static resolve(_ address: ActorAddress,
42+ // / using transport: ActorTransport) throws -> Self {
43+ // / <filled in by SILGenDistributed>
44+ // / }
45+ // / \endverbatim
46+ // /
47+ // / factory function in the AST, with an empty body. Its body is
48+ // / expected to be filled-in during SILGen.
49+ // TODO(distributed): move this synthesis to DerivedConformance style
50+ static FuncDecl *deriveDistributedActor_resolve (DerivedConformance &derived) {
51+ auto decl = dyn_cast<ClassDecl>(derived.Nominal );
52+ assert (decl->isDistributedActor ());
53+ auto &C = decl->getASTContext ();
54+
55+ auto mkParam = [&](Identifier argName, Identifier paramName, Type ty) -> ParamDecl* {
56+ auto *param = new (C) ParamDecl (SourceLoc (),
57+ SourceLoc (), argName,
58+ SourceLoc (), paramName, decl);
59+ param->setImplicit ();
60+ param->setSpecifier (ParamSpecifier::Default);
61+ param->setInterfaceType (ty);
62+ return param;
63+ };
64+
65+ auto addressType = C.getAnyActorIdentityDecl ()->getDeclaredInterfaceType ();
66+ auto transportType = C.getActorTransportDecl ()->getDeclaredInterfaceType ();
67+
68+ // (_ identity: AnyActorIdentity, using transport: ActorTransport)
69+ auto *params = ParameterList::create (
70+ C,
71+ /* LParenLoc=*/ SourceLoc (),
72+ /* params=*/ { mkParam (Identifier (), C.Id_identity , addressType),
73+ mkParam (C.Id_using , C.Id_transport , transportType)
74+ },
75+ /* RParenLoc=*/ SourceLoc ()
76+ );
77+
78+ // Func name: resolve(_:using:)
79+ DeclName name (C, C.Id_resolve , params);
80+
81+ // Expected type: (Self) -> (AnyActorIdentity, ActorTransport) throws -> (Self)
82+ auto *factoryDecl =
83+ FuncDecl::createImplicit (C, StaticSpellingKind::KeywordStatic,
84+ name, SourceLoc (),
85+ /* async=*/ false ,
86+ /* throws=*/ true ,
87+ /* genericParams=*/ nullptr ,
88+ params,
89+ /* returnType*/ decl->getDeclaredInterfaceType (),
90+ decl);
91+
92+ factoryDecl->setDistributedActorFactory (); // TODO(distributed): should we mark this specifically as the resolve factory?
93+ factoryDecl->copyFormalAccessFrom (decl, /* sourceIsParentContext=*/ true );
94+
95+ derived.addMembersToConformanceContext ({factoryDecl});
96+ return factoryDecl;
5997}
6098
99+ /* *****************************************************************************/
100+ /* ****************************** PROPERTIES ***********************************/
101+ /* *****************************************************************************/
102+
61103static ValueDecl *deriveDistributedActor_id (DerivedConformance &derived) {
62104 assert (derived.Nominal ->isDistributedActor ());
63105 auto &C = derived.Context ;
@@ -114,7 +156,6 @@ static ValueDecl *deriveDistributedActor_actorTransport(
114156 return propDecl;
115157}
116158
117-
118159// ==== ------------------------------------------------------------------------
119160
120161ValueDecl *DerivedConformance::deriveDistributedActor (ValueDecl *requirement) {
@@ -126,5 +167,12 @@ ValueDecl *DerivedConformance::deriveDistributedActor(ValueDecl *requirement) {
126167 return deriveDistributedActor_actorTransport (*this );
127168 }
128169
170+ if (auto func = dyn_cast<FuncDecl>(requirement)) {
171+ // just a simple name check is enough here,
172+ // if we are invoked here we know for sure it is for the "right" function
173+ if (func->getName ().getBaseName () == Context.Id_resolve )
174+ return deriveDistributedActor_resolve (*this );
175+ }
176+
129177 return nullptr ;
130178}
0 commit comments