mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[Distributed] Move dist funcdecl getters to ASTContext
This commit is contained in:
@@ -670,29 +670,30 @@ public:
|
||||
NominalTypeDecl *actorOrSystem,
|
||||
bool isVoidReturn) const;
|
||||
|
||||
/// Retrieve the declaration of DistributedActorSystem.make().
|
||||
///
|
||||
/// \param actorOrSystem distributed actor or actor system to get the
|
||||
/// remoteCall function for. Since the method we're looking for is an ad-hoc
|
||||
/// requirement, a specific type MUST be passed here as it is not possible
|
||||
/// to obtain the decl from just the `DistributedActorSystem` protocol type.
|
||||
FuncDecl *getMakeInvocationEncoderOnDistributedActorSystem(
|
||||
NominalTypeDecl *actorOrSystem) const;
|
||||
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.recordArgument(_:).
|
||||
//
|
||||
// \param nominal optionally provide a 'NominalTypeDecl' from which the
|
||||
// function decl shall be extracted. This is useful to avoid witness calls
|
||||
// through the protocol which is looked up when nominal is null.
|
||||
FuncDecl *getRecordArgumentOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal = nullptr) const;
|
||||
NominalTypeDecl *nominal) const;
|
||||
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.recordErrorType().
|
||||
//
|
||||
// \param nominal optionally provide a 'NominalTypeDecl' from which the
|
||||
// function decl shall be extracted. This is useful to avoid witness calls
|
||||
// through the protocol which is looked up when nominal is null.
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.recordErrorType(_:).
|
||||
FuncDecl *getRecordErrorTypeOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal = nullptr) const;
|
||||
NominalTypeDecl *nominal) const;
|
||||
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.recordReturnType().
|
||||
//
|
||||
// \param nominal optionally provide a 'NominalTypeDecl' from which the
|
||||
// function decl shall be extracted. This is useful to avoid witness calls
|
||||
// through the protocol which is looked up when nominal is null.
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.recordReturnType(_:).
|
||||
FuncDecl *getRecordReturnTypeOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal = nullptr) const;
|
||||
NominalTypeDecl *nominal) const;
|
||||
|
||||
// Retrieve the declaration of DistributedInvocationEncoder.doneRecording().
|
||||
//
|
||||
@@ -700,8 +701,7 @@ public:
|
||||
// function decl shall be extracted. This is useful to avoid witness calls
|
||||
// through the protocol which is looked up when nominal is null.
|
||||
FuncDecl *getDoneRecordingOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal = nullptr) const;
|
||||
|
||||
NominalTypeDecl *nominal) const;
|
||||
|
||||
/// Look for the declaration with the given name within the
|
||||
/// passed in module.
|
||||
|
||||
@@ -3370,9 +3370,6 @@ public:
|
||||
/// Find, or potentially synthesize, the implicit 'id' property of this actor.
|
||||
VarDecl *getDistributedActorIDProperty() const;
|
||||
|
||||
/// Find the 'makeInvocation' function.
|
||||
AbstractFunctionDecl* getDistributedActorSystemMakeInvocationEncoderFunction() const;
|
||||
|
||||
/// Find the 'RemoteCallTarget.init(_mangledName:)' initializer function
|
||||
ConstructorDecl* getDistributedRemoteCallTargetInitFunction() const;
|
||||
|
||||
|
||||
@@ -267,18 +267,6 @@ struct ASTContext::Implementation {
|
||||
/// -> Builtin.Int1
|
||||
FuncDecl *IsOSVersionAtLeastDecl = nullptr;
|
||||
|
||||
/// func recordArgument(_:) throws
|
||||
FuncDecl *RecordArgumentDistributedInvocationEncoderDecl = nullptr;
|
||||
|
||||
/// func recordErrorType(_:) throws
|
||||
FuncDecl *RecordErrorTypeDistributedInvocationEncoderDecl = nullptr;
|
||||
|
||||
/// func recordReturnType(_:) throws
|
||||
FuncDecl *RecordReturnTypeDistributedInvocationEncoderDecl = nullptr;
|
||||
|
||||
/// func doneRecording() throws
|
||||
FuncDecl *DoneRecordingDistributedInvocationEncoderDecl = nullptr;
|
||||
|
||||
/// The set of known protocols, lazily populated as needed.
|
||||
ProtocolDecl *KnownProtocols[NumKnownProtocols] = { };
|
||||
|
||||
@@ -1295,7 +1283,7 @@ AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
|
||||
NominalTypeDecl *actorOrSystem, bool isVoidReturn) const {
|
||||
assert(actorOrSystem && "distributed actor (or system) decl must be provided");
|
||||
const NominalTypeDecl *system = actorOrSystem;
|
||||
if (actorOrSystem && actorOrSystem->isDistributedActor()) {
|
||||
if (actorOrSystem->isDistributedActor()) {
|
||||
auto var = actorOrSystem->getDistributedActorSystemProperty();
|
||||
system = var->getInterfaceType()->getAnyNominal();
|
||||
}
|
||||
@@ -1310,32 +1298,49 @@ AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem(
|
||||
nullptr);
|
||||
}
|
||||
|
||||
FuncDecl *ASTContext::getRecordArgumentOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal) const {
|
||||
if (getImpl().RecordArgumentDistributedInvocationEncoderDecl) {
|
||||
return getImpl().RecordArgumentDistributedInvocationEncoderDecl;
|
||||
FuncDecl *ASTContext::getMakeInvocationEncoderOnDistributedActorSystem(
|
||||
NominalTypeDecl *actorOrSystem) const {
|
||||
NominalTypeDecl *system = actorOrSystem;
|
||||
assert(actorOrSystem && "distributed actor (or system) decl must be provided");
|
||||
if (actorOrSystem->isDistributedActor()) {
|
||||
auto var = actorOrSystem->getDistributedActorSystemProperty();
|
||||
system = var->getInterfaceType()->getAnyNominal();
|
||||
}
|
||||
|
||||
NominalTypeDecl *encoderProto = nominal ?
|
||||
nominal :
|
||||
getProtocol(KnownProtocolKind::DistributedTargetInvocationEncoder);
|
||||
assert(encoderProto && "Missing DistributedTargetInvocationEncoder protocol");
|
||||
for (auto result : encoderProto->lookupDirect(Id_recordArgument)) {
|
||||
for (auto result : system->lookupDirect(Id_makeInvocationEncoder)) {
|
||||
auto *fd = dyn_cast<FuncDecl>(result);
|
||||
if (!fd)
|
||||
continue;
|
||||
if (fd->getParameters()->size() != 0)
|
||||
continue;
|
||||
if (fd->hasAsync())
|
||||
continue;
|
||||
if (fd->hasThrows())
|
||||
continue;
|
||||
// TODO(distributed): more checks, return type etc
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FuncDecl *ASTContext::getRecordArgumentOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal) const {
|
||||
for (auto result : nominal->lookupDirect(Id_recordArgument)) {
|
||||
auto *fd = dyn_cast<FuncDecl>(result);
|
||||
if (!fd)
|
||||
continue;
|
||||
if (fd->getParameters()->size() != 1)
|
||||
continue;
|
||||
|
||||
if (fd->hasAsync())
|
||||
continue;
|
||||
if (!fd->hasThrows())
|
||||
continue;
|
||||
// TODO(distributed): more checks
|
||||
|
||||
if (fd->getResultInterfaceType()->isVoid() &&
|
||||
fd->hasThrows() &&
|
||||
!fd->hasAsync()) {
|
||||
getImpl().RecordArgumentDistributedInvocationEncoderDecl = fd;
|
||||
if (fd->getResultInterfaceType()->isVoid())
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -1343,31 +1348,20 @@ FuncDecl *ASTContext::getRecordArgumentOnDistributedInvocationEncoder(
|
||||
|
||||
FuncDecl *ASTContext::getRecordErrorTypeOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal) const {
|
||||
if (getImpl().RecordErrorTypeDistributedInvocationEncoderDecl) {
|
||||
return getImpl().RecordErrorTypeDistributedInvocationEncoderDecl;
|
||||
}
|
||||
|
||||
NominalTypeDecl *encoderProto =
|
||||
nominal
|
||||
? nominal
|
||||
: getProtocol(KnownProtocolKind::DistributedTargetInvocationEncoder);
|
||||
assert(encoderProto && "Missing DistributedTargetInvocationEncoder protocol");
|
||||
for (auto result : encoderProto->lookupDirect(Id_recordErrorType)) {
|
||||
for (auto result : nominal->lookupDirect(Id_recordErrorType)) {
|
||||
auto *fd = dyn_cast<FuncDecl>(result);
|
||||
if (!fd)
|
||||
continue;
|
||||
|
||||
if (fd->getParameters()->size() != 1)
|
||||
continue;
|
||||
if (fd->hasAsync())
|
||||
continue;
|
||||
if (!fd->hasThrows())
|
||||
continue;
|
||||
// TODO(distributed): more checks
|
||||
|
||||
// TODO(distributed): more checks that the arg type matches (!!!)
|
||||
|
||||
if (fd->getResultInterfaceType()->isVoid() &&
|
||||
fd->hasThrows() &&
|
||||
!fd->hasAsync()) {
|
||||
getImpl().RecordErrorTypeDistributedInvocationEncoderDecl = fd;
|
||||
if (fd->getResultInterfaceType()->isVoid())
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -1375,31 +1369,20 @@ FuncDecl *ASTContext::getRecordErrorTypeOnDistributedInvocationEncoder(
|
||||
|
||||
FuncDecl *ASTContext::getRecordReturnTypeOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal) const {
|
||||
if (getImpl().RecordReturnTypeDistributedInvocationEncoderDecl) {
|
||||
return getImpl().RecordReturnTypeDistributedInvocationEncoderDecl;
|
||||
}
|
||||
|
||||
NominalTypeDecl *encoderProto =
|
||||
nominal
|
||||
? nominal
|
||||
: getProtocol(KnownProtocolKind::DistributedTargetInvocationEncoder);
|
||||
assert(encoderProto && "Missing DistributedTargetInvocationEncoder protocol");
|
||||
for (auto result : encoderProto->lookupDirect(Id_recordReturnType)) {
|
||||
for (auto result : nominal->lookupDirect(Id_recordReturnType)) {
|
||||
auto *fd = dyn_cast<FuncDecl>(result);
|
||||
if (!fd)
|
||||
continue;
|
||||
|
||||
if (fd->getParameters()->size() != 1)
|
||||
continue;
|
||||
if (fd->hasAsync())
|
||||
continue;
|
||||
if (!fd->hasThrows())
|
||||
continue;
|
||||
// TODO(distributed): more checks
|
||||
|
||||
// TODO(distributed): more checks that the arg type matches (!!!)
|
||||
|
||||
if (fd->getResultInterfaceType()->isVoid() &&
|
||||
fd->hasThrows() &&
|
||||
!fd->hasAsync()) {
|
||||
getImpl().RecordReturnTypeDistributedInvocationEncoderDecl = fd;
|
||||
if (fd->getResultInterfaceType()->isVoid())
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
@@ -1407,16 +1390,7 @@ FuncDecl *ASTContext::getRecordReturnTypeOnDistributedInvocationEncoder(
|
||||
|
||||
FuncDecl *ASTContext::getDoneRecordingOnDistributedInvocationEncoder(
|
||||
NominalTypeDecl *nominal) const {
|
||||
if (getImpl().DoneRecordingDistributedInvocationEncoderDecl) {
|
||||
return getImpl().DoneRecordingDistributedInvocationEncoderDecl;
|
||||
}
|
||||
|
||||
NominalTypeDecl *encoderProto =
|
||||
nominal
|
||||
? nominal
|
||||
: getProtocol(KnownProtocolKind::DistributedTargetInvocationEncoder);
|
||||
assert(encoderProto && "Missing DistributedTargetInvocationEncoder protocol");
|
||||
for (auto result : encoderProto->lookupDirect(Id_doneRecording)) {
|
||||
for (auto result : nominal->lookupDirect(Id_doneRecording)) {
|
||||
auto *fd = dyn_cast<FuncDecl>(result);
|
||||
if (!fd)
|
||||
continue;
|
||||
@@ -1426,10 +1400,8 @@ FuncDecl *ASTContext::getDoneRecordingOnDistributedInvocationEncoder(
|
||||
|
||||
if (fd->getResultInterfaceType()->isVoid() &&
|
||||
fd->hasThrows() &&
|
||||
!fd->hasAsync()) {
|
||||
getImpl().DoneRecordingDistributedInvocationEncoderDecl = fd;
|
||||
!fd->hasAsync())
|
||||
return fd;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
@@ -7402,17 +7402,14 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
|
||||
auto callId = isVoidReturn ? C.Id_remoteCallVoid : C.Id_remoteCall;
|
||||
|
||||
// Check the name
|
||||
if (this->getBaseName() != callId)
|
||||
if (getBaseName() != callId)
|
||||
return false;
|
||||
|
||||
auto params = this->getParameters();
|
||||
auto params = getParameters();
|
||||
unsigned int expectedParamNum = isVoidReturn ? 4 : 5;
|
||||
|
||||
// Check the expected argument count
|
||||
// - for value returning remoteCall:
|
||||
if (!params || (!isVoidReturn && params->size() != 5))
|
||||
return false;
|
||||
// - for void returning remoteCallVoid:
|
||||
if (!params || (isVoidReturn && params->size() != 4))
|
||||
// Check the expected argument count:
|
||||
if (!params || params->size() != expectedParamNum)
|
||||
return false;
|
||||
|
||||
// Check API names of the arguments
|
||||
@@ -7422,7 +7419,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
|
||||
auto thrownTypeParam = params->get(3);
|
||||
if (actorParam->getArgumentName() != C.Id_on ||
|
||||
targetParam->getArgumentName() != C.Id_target ||
|
||||
invocationParam->getArgumentName() != C.Id_invocationDecoder ||
|
||||
invocationParam->getArgumentName() != C.Id_invocation ||
|
||||
thrownTypeParam->getArgumentName() != C.Id_throwing)
|
||||
return false;
|
||||
|
||||
@@ -7432,6 +7429,26 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isGeneric())
|
||||
return false;
|
||||
|
||||
auto genericParams = getGenericParams();
|
||||
unsigned int expectedGenericParamNum = isVoidReturn ? 2 : 3;
|
||||
|
||||
// We expect: Act, Err, Res?
|
||||
if (genericParams->size() != expectedGenericParamNum) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME(distributed): check the exact generic requirements
|
||||
|
||||
// === check the return type
|
||||
if (isVoidReturn) {
|
||||
if (auto func = dyn_cast<FuncDecl>(this))
|
||||
if (!func->getResultInterfaceType()->isVoid())
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME(distributed): check the right types of the args and generics...
|
||||
// FIXME(distributed): check access level actually is ok, i.e. not private etc
|
||||
|
||||
@@ -7439,34 +7456,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
|
||||
}
|
||||
|
||||
bool AbstractFunctionDecl::isDistributed() const {
|
||||
return this->getAttrs().hasAttribute<DistributedActorAttr>();
|
||||
}
|
||||
|
||||
AbstractFunctionDecl*
|
||||
NominalTypeDecl::getDistributedActorSystemMakeInvocationEncoderFunction() const {
|
||||
auto &C = this->getASTContext();
|
||||
NominalTypeDecl *system = const_cast<NominalTypeDecl *>(this);
|
||||
if (this->isDistributedActor()) {
|
||||
auto var = this->getDistributedActorSystemProperty();
|
||||
system = var->getInterfaceType()->getAnyNominal();
|
||||
}
|
||||
|
||||
// FIXME(distributed): implement more properly...
|
||||
for (auto value : system->lookupDirect(C.Id_makeInvocationEncoder)) {
|
||||
auto func = dyn_cast<AbstractFunctionDecl>(value);
|
||||
if (!func)
|
||||
continue;
|
||||
|
||||
if (func->getParameters()->size() != 0)
|
||||
continue;
|
||||
|
||||
// TODO(distriuted): return type must conform to our expected protocol
|
||||
|
||||
return func;
|
||||
}
|
||||
|
||||
// TODO(distributed): make a Request for it?
|
||||
return nullptr;
|
||||
return getAttrs().hasAttribute<DistributedActorAttr>();
|
||||
}
|
||||
|
||||
ConstructorDecl*
|
||||
|
||||
@@ -724,8 +724,8 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
|
||||
|
||||
// === `InvocationEncoder` types
|
||||
AbstractFunctionDecl *makeInvocationEncoderFnDecl =
|
||||
selfTyDecl->getDistributedActorSystemMakeInvocationEncoderFunction();
|
||||
assert(makeInvocationEncoderFnDecl && "no remoteCall func found!");
|
||||
ctx.getMakeInvocationEncoderOnDistributedActorSystem(selfTyDecl);
|
||||
assert(makeInvocationEncoderFnDecl && "no 'makeInvocationEncoder' func found!");
|
||||
auto makeInvocationEncoderFnRef = SILDeclRef(makeInvocationEncoderFnDecl);
|
||||
|
||||
ProtocolDecl *invocationEncoderProto =
|
||||
@@ -882,7 +882,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
|
||||
|
||||
// function_ref FakeActorSystem.makeInvocationEncoder()
|
||||
// %19 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV21makeInvocationEncoderAA0aG0VyF : $@convention(method) (@guaranteed FakeActorSystem) -> FakeInvocation // user: %20
|
||||
auto makeInvocationEncoderFnSIL =
|
||||
SILFunction *makeInvocationEncoderFnSIL =
|
||||
builder.getOrCreateFunction(loc, makeInvocationEncoderFnRef, NotForDefinition);
|
||||
SILValue makeInvocationEncoderFn =
|
||||
B.createFunctionRefFor(loc, makeInvocationEncoderFnSIL);
|
||||
@@ -1395,7 +1395,7 @@ void SILGenFunction::emitDistributedThunk(SILDeclRef thunk) {
|
||||
}
|
||||
assert(returnMetatypeValue);
|
||||
|
||||
// function_ref FakeActorSystem.remoteCall<A, B, C>(on:target:invocationDecoder:throwing:returning:)
|
||||
// function_ref FakeActorSystem.remoteCall<A, B, C>(on:target:invocation:throwing:returning:)
|
||||
// %49 = function_ref @$s27FakeDistributedActorSystems0aC6SystemV10remoteCall2on6target17invocationDecoder8throwing9returningq0_x_01_B006RemoteG6TargetVAA0A10InvocationVzq_mq0_mSgtYaKAJ0bC0RzSeR0_SER0_AA0C7AddressV2IDRtzr1_lF : $@convention(method) @async <τ_0_0, τ_0_1, τ_0_2 where τ_0_0 : DistributedActor, τ_0_2 : Decodable, τ_0_2 : Encodable, τ_0_0.ID == ActorAddress> (@guaranteed τ_0_0, @in_guaranteed RemoteCallTarget, @inout FakeInvocation, @thick τ_0_1.Type, Optional<@thick τ_0_2.Type>, @guaranteed FakeActorSystem) -> (@out τ_0_2, @error Error) // user: %50
|
||||
auto remoteCallFnDecl =
|
||||
ctx.getRemoteCallOnDistributedActorSystem(selfTyDecl, /*isVoid=*/resultType.isVoid());
|
||||
|
||||
Reference in New Issue
Block a user