mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Add Missing Definitions of canDerive{En,De}codable
This commit is contained in:
@@ -1071,10 +1071,35 @@ static bool canSynthesize(DerivedConformance &derived, ValueDecl *requirement) {
|
|||||||
LLVM_FALLTHROUGH;
|
LLVM_FALLTHROUGH;
|
||||||
case CodingKeysClassification::Valid:
|
case CodingKeysClassification::Valid:
|
||||||
return true;
|
return true;
|
||||||
|
static bool canDeriveCodable(NominalTypeDecl *NTD,
|
||||||
|
KnownProtocolKind Kind) {
|
||||||
|
assert(Kind == KnownProtocolKind::Encodable ||
|
||||||
|
Kind == KnownProtocolKind::Decodable);
|
||||||
|
|
||||||
|
// Structs and classes can explicitly derive Encodable and Decodable
|
||||||
|
// conformance (explicitly meaning we can synthesize an implementation if
|
||||||
|
// a type conforms manually).
|
||||||
|
// FIXME: Enums too!
|
||||||
|
if (!isa<StructDecl>(NTD) && !isa<ClassDecl>(NTD)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto *PD = NTD->getASTContext().getProtocol(Kind);
|
||||||
|
if (!PD) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DerivedConformance::canDeriveDecodable(NominalTypeDecl *NTD) {
|
||||||
|
return canDeriveCodable(NTD, KnownProtocolKind::Decodable);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DerivedConformance::canDeriveEncodable(NominalTypeDecl *NTD) {
|
||||||
|
return canDeriveCodable(NTD, KnownProtocolKind::Encodable);
|
||||||
|
}
|
||||||
|
|
||||||
ValueDecl *DerivedConformance::deriveEncodable(ValueDecl *requirement) {
|
ValueDecl *DerivedConformance::deriveEncodable(ValueDecl *requirement) {
|
||||||
// We can only synthesize Encodable for structs and classes.
|
// We can only synthesize Encodable for structs and classes.
|
||||||
if (!isa<StructDecl>(Nominal) && !isa<ClassDecl>(Nominal))
|
if (!isa<StructDecl>(Nominal) && !isa<ClassDecl>(Nominal))
|
||||||
|
|||||||
@@ -88,6 +88,14 @@ bool DerivedConformance::derivesProtocolConformance(DeclContext *DC,
|
|||||||
if (*derivableKind == KnownDerivableProtocolKind::Differentiable)
|
if (*derivableKind == KnownDerivableProtocolKind::Differentiable)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (*derivableKind == KnownDerivableProtocolKind::Encodable) {
|
||||||
|
return canDeriveEncodable(Nominal);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*derivableKind == KnownDerivableProtocolKind::Decodable) {
|
||||||
|
return canDeriveDecodable(Nominal);
|
||||||
|
}
|
||||||
|
|
||||||
if (auto *enumDecl = dyn_cast<EnumDecl>(Nominal)) {
|
if (auto *enumDecl = dyn_cast<EnumDecl>(Nominal)) {
|
||||||
switch (*derivableKind) {
|
switch (*derivableKind) {
|
||||||
// The presence of a raw type is an explicit declaration that
|
// The presence of a raw type is an explicit declaration that
|
||||||
@@ -137,31 +145,13 @@ bool DerivedConformance::derivesProtocolConformance(DeclContext *DC,
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (isa<StructDecl>(Nominal) || isa<ClassDecl>(Nominal)) {
|
} else if (isa<StructDecl>(Nominal)) {
|
||||||
// Structs and classes can explicitly derive Encodable and Decodable
|
switch (*derivableKind) {
|
||||||
// conformance (explicitly meaning we can synthesize an implementation if
|
case KnownDerivableProtocolKind::Equatable:
|
||||||
// a type conforms manually).
|
// Structs can explicitly derive Equatable conformance.
|
||||||
if (*derivableKind == KnownDerivableProtocolKind::Encodable ||
|
return canDeriveEquatable(DC, Nominal);
|
||||||
*derivableKind == KnownDerivableProtocolKind::Decodable) {
|
default:
|
||||||
// FIXME: This is not actually correct. We cannot promise to always
|
return false;
|
||||||
// provide a witness here for all structs and classes. Unfortunately,
|
|
||||||
// figuring out whether this is actually possible requires much more
|
|
||||||
// context -- a TypeChecker and the parent decl context at least -- and is
|
|
||||||
// tightly coupled to the logic within DerivedConformance.
|
|
||||||
// This unfortunately means that we expect a witness even if one will not
|
|
||||||
// be produced, which requires DerivedConformance::deriveCodable to output
|
|
||||||
// its own diagnostics.
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Structs can explicitly derive Equatable conformance.
|
|
||||||
if (isa<StructDecl>(Nominal)) {
|
|
||||||
switch (*derivableKind) {
|
|
||||||
case KnownDerivableProtocolKind::Equatable:
|
|
||||||
return canDeriveEquatable(DC, Nominal);
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -278,6 +278,11 @@ public:
|
|||||||
/// \returns the derived member, which will also be added to the type.
|
/// \returns the derived member, which will also be added to the type.
|
||||||
ValueDecl *deriveBridgedNSError(ValueDecl *requirement);
|
ValueDecl *deriveBridgedNSError(ValueDecl *requirement);
|
||||||
|
|
||||||
|
/// Determine if \c Encodable can be derived for the given type.
|
||||||
|
static bool canDeriveEncodable(NominalTypeDecl *NTD);
|
||||||
|
/// Determine if \c Decodable can be derived for the given type.
|
||||||
|
static bool canDeriveDecodable(NominalTypeDecl *NTD);
|
||||||
|
|
||||||
/// Derive a CodingKey requirement for an enum type.
|
/// Derive a CodingKey requirement for an enum type.
|
||||||
///
|
///
|
||||||
/// \returns the derived member, which will also be added to the type.
|
/// \returns the derived member, which will also be added to the type.
|
||||||
|
|||||||
Reference in New Issue
Block a user