mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
165 lines
5.6 KiB
C++
165 lines
5.6 KiB
C++
//===--- CodeSynthesisDistributedActor.cpp --------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "TypeCheckDistributed.h"
|
|
|
|
#include "TypeChecker.h"
|
|
#include "TypeCheckType.h"
|
|
#include "swift/AST/ASTPrinter.h"
|
|
#include "swift/AST/Availability.h"
|
|
#include "swift/AST/Expr.h"
|
|
#include "swift/AST/GenericEnvironment.h"
|
|
#include "swift/AST/Initializer.h"
|
|
#include "swift/AST/ParameterList.h"
|
|
#include "swift/AST/TypeCheckRequests.h"
|
|
#include "swift/AST/DistributedDecl.h"
|
|
#include "swift/Basic/Defer.h"
|
|
#include "swift/ClangImporter/ClangModule.h"
|
|
#include "swift/Sema/ConstraintSystem.h"
|
|
#include "llvm/ADT/SmallString.h"
|
|
#include "llvm/ADT/StringExtras.h"
|
|
#include "DerivedConformances.h"
|
|
using namespace swift;
|
|
|
|
// Note: This would be nice to implement in DerivedConformanceDistributedActor,
|
|
// but we can't since those are lazily triggered and an implementation exists
|
|
// for the 'id' property because 'Identifiable.id' has an extension that impls
|
|
// it for ObjectIdentifier, and we have to instead emit this stored property.
|
|
//
|
|
// The "derived" mechanisms are not really geared towards emitting for
|
|
// what already has a witness.
|
|
static VarDecl *addImplicitDistributedActorIDProperty(
|
|
NominalTypeDecl *nominal) {
|
|
if (!nominal || !nominal->isDistributedActor())
|
|
return nullptr;
|
|
|
|
// ==== if the 'id' already exists, return it
|
|
auto &C = nominal->getASTContext();
|
|
// if (auto existing = nominal->lookupDirect(C.Id_id))
|
|
// return existing;
|
|
|
|
// ==== Synthesize and add 'id' property to the actor decl
|
|
Type propertyType = getDistributedActorIDType(nominal);
|
|
|
|
VarDecl *propDecl = new (C)
|
|
VarDecl(/*IsStatic*/false, VarDecl::Introducer::Let,
|
|
SourceLoc(), C.Id_id, nominal);
|
|
propDecl->setImplicit();
|
|
propDecl->setSynthesized();
|
|
propDecl->copyFormalAccessFrom(nominal, /*sourceIsParentContext*/ true);
|
|
propDecl->setInterfaceType(propertyType);
|
|
|
|
Pattern *propPat = NamedPattern::createImplicit(C, propDecl);
|
|
propPat->setType(propertyType);
|
|
|
|
propPat = TypedPattern::createImplicit(C, propPat, propertyType);
|
|
propPat->setType(propertyType);
|
|
|
|
PatternBindingDecl *pbDecl = PatternBindingDecl::createImplicit(
|
|
C, StaticSpellingKind::None, propPat, /*InitExpr*/ nullptr,
|
|
nominal);
|
|
|
|
propDecl->setIntroducer(VarDecl::Introducer::Let);
|
|
|
|
// mark as nonisolated, allowing access to it from everywhere
|
|
propDecl->getAttrs().add(
|
|
new (C) NonisolatedAttr(/*IsImplicit=*/true));
|
|
|
|
nominal->addMember(propDecl);
|
|
nominal->addMember(pbDecl);
|
|
|
|
return propDecl;
|
|
}
|
|
|
|
/******************************************************************************/
|
|
/************ LOCATING AD-HOC PROTOCOL REQUIREMENT IMPLS **********************/
|
|
/******************************************************************************/
|
|
|
|
AbstractFunctionDecl*
|
|
GetDistributedActorSystemRemoteCallFunctionRequest::evaluate(
|
|
Evaluator &evaluator, NominalTypeDecl *decl, bool isVoidReturn) const {
|
|
auto &C = decl->getASTContext();
|
|
|
|
// It would be nice to check if this is a DistributedActorSystem
|
|
// "conforming" type, but we can't do this as we invoke this function WHILE
|
|
// deciding if the type conforms or not;
|
|
|
|
// Not via `ensureDistributedModuleLoaded` to avoid generating a warning,
|
|
// we won't be emitting the offending decl after all.
|
|
if (!C.getLoadedModule(C.Id_Distributed)) {
|
|
return nullptr;
|
|
}
|
|
|
|
auto callId = isVoidReturn ? C.Id_remoteCallVoid : C.Id_remoteCall;
|
|
|
|
AbstractFunctionDecl *remoteCallFunc = nullptr;
|
|
for (auto value : decl->lookupDirect(callId)) {
|
|
auto func = dyn_cast<AbstractFunctionDecl>(value);
|
|
if (func && func->isDistributedActorSystemRemoteCall(isVoidReturn)) {
|
|
remoteCallFunc = func;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return remoteCallFunc;
|
|
}
|
|
|
|
|
|
/******************************************************************************/
|
|
/************************ SYNTHESIS ENTRY POINT *******************************/
|
|
/******************************************************************************/
|
|
|
|
VarDecl *GetDistributedActorIDPropertyRequest::evaluate(
|
|
Evaluator &evaluator, NominalTypeDecl *actor) const {
|
|
if (!actor->isDistributedActor())
|
|
return nullptr;
|
|
|
|
auto &C = actor->getASTContext();
|
|
|
|
// not via `ensureDistributedModuleLoaded` to avoid generating a warning,
|
|
// we won't be emitting the offending decl after all.
|
|
if (!C.getLoadedModule(C.Id_Distributed))
|
|
return nullptr;
|
|
|
|
return addImplicitDistributedActorIDProperty(actor);
|
|
}
|
|
|
|
VarDecl *GetDistributedActorSystemPropertyRequest::evaluate(
|
|
Evaluator &evaluator, NominalTypeDecl *actor) const {
|
|
if (!actor->isDistributedActor())
|
|
return nullptr;
|
|
|
|
auto &C = actor->getASTContext();
|
|
|
|
// not via `ensureDistributedModuleLoaded` to avoid generating a warning,
|
|
// we won't be emitting the offending decl after all.
|
|
if (!C.getLoadedModule(C.Id_Distributed))
|
|
return nullptr;
|
|
|
|
auto module = C.getStdlibModule();
|
|
auto DistSystemProtocol =
|
|
C.getProtocol(KnownProtocolKind::DistributedActorSystem);
|
|
|
|
for (auto system : actor->lookupDirect(C.Id_actorSystem)) {
|
|
if (auto var = dyn_cast<VarDecl>(system)) {
|
|
auto conformance = module->conformsToProtocol(var->getInterfaceType(),
|
|
DistSystemProtocol);
|
|
if (conformance.isInvalid())
|
|
continue;
|
|
|
|
return var;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|