Files
swift-mirror/lib/Sema/CodeSynthesisDistributedActor.cpp
Konrad `ktoso` Malawski 97227edcca remove @_dynamic methods!
fix tests
2022-01-26 23:15:43 +09:00

156 lines
5.3 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/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(
// DeclContext *parentDC,
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;
if (auto system = actor->lookupDirect(C.Id_actorSystem).begin()) {
// TODO(distributed): may need to check conformance here?
return dyn_cast<VarDecl>(*system);
}
return nullptr;
}