Skip to content

Commit

Permalink
Merge pull request #9004 from itaiferber/swift-archival-serialization
Browse files Browse the repository at this point in the history
Swift Archival & Serialization API
  • Loading branch information
DougGregor authored Apr 29, 2017
2 parents 9296437 + 433c192 commit 447dce6
Show file tree
Hide file tree
Showing 47 changed files with 5,795 additions and 8 deletions.
11 changes: 8 additions & 3 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2912,6 +2912,9 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
private:
/// Predicate used to filter StoredPropertyRange.
struct ToStoredProperty {
ToStoredProperty(bool skipInaccessible = false) :
skipUserInaccessible(skipInaccessible) {}
bool skipUserInaccessible;
Optional<VarDecl *> operator()(Decl *decl) const;
};

Expand All @@ -2921,8 +2924,9 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
ToStoredProperty>;

/// Return a collection of the stored member variables of this type.
StoredPropertyRange getStoredProperties() const {
return StoredPropertyRange(getMembers(), ToStoredProperty());
StoredPropertyRange getStoredProperties(bool skipInaccessible = false) const {
return StoredPropertyRange(getMembers(),
ToStoredProperty(skipInaccessible));
}

// Implement isa/cast/dyncast/etc.
Expand Down Expand Up @@ -6119,7 +6123,8 @@ inline bool ValueDecl::isSettable(const DeclContext *UseDC,
inline Optional<VarDecl *>
NominalTypeDecl::ToStoredProperty::operator()(Decl *decl) const {
if (auto var = dyn_cast<VarDecl>(decl)) {
if (!var->isStatic() && var->hasStorage())
if (!var->isStatic() && var->hasStorage() &&
(!skipUserInaccessible || var->isUserAccessible()))
return var;
}

Expand Down
6 changes: 6 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1966,6 +1966,12 @@ ERROR(broken_int_integer_literal_convertible_conformance,none,
"Int type is broken: does not conform to ExpressibleByIntegerLiteral", ())
ERROR(no_equal_overload_for_int,none,
"no overload of '==' for Int", ())
ERROR(broken_coding_key_requirement,none,
"CodingKey protocol is broken: unexpected requirement", ())
ERROR(broken_encodable_requirement,none,
"Encodable protocol is broken: unexpected requirement", ())
ERROR(broken_decodable_requirement,none,
"Decodable protocol is broken: unexpected requirement", ())

// Dynamic Self
ERROR(dynamic_self_non_method,none,
Expand Down
22 changes: 22 additions & 0 deletions include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,40 @@ IDENTIFIER(Any)
IDENTIFIER(atIndexedSubscript)
IDENTIFIER_(bridgeToObjectiveC)
IDENTIFIER_WITH_NAME(code_, "_code")
IDENTIFIER(CodingKeys)
IDENTIFIER(container)
IDENTIFIER(CoreGraphics)
IDENTIFIER(CoreMedia)
IDENTIFIER(CGFloat)
IDENTIFIER(CVarArg)
IDENTIFIER(Darwin)
IDENTIFIER(dealloc)
IDENTIFIER(Decodable)
IDENTIFIER(decode)
IDENTIFIER(Decoder)
IDENTIFIER(decoder)
IDENTIFIER(deinit)
IDENTIFIER(Element)
IDENTIFIER(Encodable)
IDENTIFIER(encode)
IDENTIFIER(Encoder)
IDENTIFIER(encoder)
IDENTIFIER(error)
IDENTIFIER(forKeyedSubscript)
IDENTIFIER(Foundation)
IDENTIFIER(forKey)
IDENTIFIER(from)
IDENTIFIER(fromRaw)
IDENTIFIER(hashValue)
IDENTIFIER(init)
IDENTIFIER(initialize)
IDENTIFIER(initStorage)
IDENTIFIER(initialValue)
IDENTIFIER(intValue)
IDENTIFIER(Key)
IDENTIFIER(KeyedDecodingContainer)
IDENTIFIER(KeyedEncodingContainer)
IDENTIFIER(keyedBy)
IDENTIFIER(keyPath)
IDENTIFIER(makeIterator)
IDENTIFIER(Iterator)
Expand All @@ -70,10 +86,16 @@ IDENTIFIER(setObject)
IDENTIFIER(simd)
IDENTIFIER(some)
IDENTIFIER(storage)
IDENTIFIER(stringValue)
IDENTIFIER(subscript)
IDENTIFIER(super)
IDENTIFIER(superDecoder)
IDENTIFIER(superEncoder)
IDENTIFIER(SwiftObject)
IDENTIFIER(to)
IDENTIFIER(toRaw)
IDENTIFIER(Type)
IDENTIFIER(type)
IDENTIFIER(Value)
IDENTIFIER(value)
IDENTIFIER_WITH_NAME(value_, "_value")
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/KnownProtocols.def
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ PROTOCOL_(ErrorCodeProtocol)
PROTOCOL(OptionSet)
PROTOCOL_(BridgedNSError)
PROTOCOL_(BridgedStoredNSError)
PROTOCOL(CodingKey)
PROTOCOL(Encodable)
PROTOCOL(Decodable)

PROTOCOL_(ObjectiveCBridgeable)
PROTOCOL_(DestructorSafeContainer)
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/KnownStdlibTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,9 @@ KNOWN_STDLIB_TYPE_DECL(Unmanaged, NominalTypeDecl, 1)

KNOWN_STDLIB_TYPE_DECL(Never, NominalTypeDecl, 0)

KNOWN_STDLIB_TYPE_DECL(Encoder, ProtocolDecl, 1)
KNOWN_STDLIB_TYPE_DECL(Decoder, ProtocolDecl, 1)
KNOWN_STDLIB_TYPE_DECL(KeyedEncodingContainer, NominalTypeDecl, 1)
KNOWN_STDLIB_TYPE_DECL(KeyedDecodingContainer, NominalTypeDecl, 1)

#undef KNOWN_STDLIB_TYPE_DECL
3 changes: 2 additions & 1 deletion lib/AST/ASTPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@ struct SynthesizedExtensionAnalyzer::Implementation {
unsigned countInherits(ExtensionDecl *ED) {
unsigned Count = 0;
for (auto TL : ED->getInherited()) {
if (shouldPrint(TL.getType()->getAnyNominal(), Options))
auto *nominal = TL.getType()->getAnyNominal();
if (nominal && shouldPrint(nominal, Options))
Count ++;
}
return Count;
Expand Down
33 changes: 33 additions & 0 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2106,9 +2106,42 @@ bool NominalTypeDecl::derivesProtocolConformance(ProtocolDecl *protocol) const {
return isObjC() && enumDecl->hasCases()
&& enumDecl->hasOnlyCasesWithoutAssociatedValues();

// Enums without associated values and enums with a raw type of String
// or Int can explicitly derive CodingKey conformance.
case KnownProtocolKind::CodingKey: {
Type rawType = enumDecl->getRawType();
if (rawType) {
auto parentDC = enumDecl->getDeclContext();
ASTContext &C = parentDC->getASTContext();

auto nominal = rawType->getAnyNominal();
return nominal == C.getStringDecl() || nominal == C.getIntDecl();
}

// hasOnlyCasesWithoutAssociatedValues will return true for empty enums;
// empty enumas are allowed to conform as well.
return enumDecl->hasOnlyCasesWithoutAssociatedValues();
}

default:
return false;
}
} else if (isa<StructDecl>(this) || isa<ClassDecl>(this)) {
// Structs and classes can explicitly derive Encodable and Decodable
// conformance (explicitly meaning we can synthesize an implementation if
// a type conforms manually).
if (*knownProtocol == KnownProtocolKind::Encodable ||
*knownProtocol == KnownProtocolKind::Decodable) {
// FIXME: This is not actually correct. We cannot promise to always
// 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;
}
}
return false;
}
Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/GenMeta.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5538,6 +5538,9 @@ SpecialProtocol irgen::getSpecialProtocolID(ProtocolDecl *P) {
case KnownProtocolKind::ErrorCodeProtocol:
case KnownProtocolKind::ExpressibleByBuiltinConstStringLiteral:
case KnownProtocolKind::ExpressibleByBuiltinConstUTF16StringLiteral:
case KnownProtocolKind::CodingKey:
case KnownProtocolKind::Encodable:
case KnownProtocolKind::Decodable:
return SpecialProtocol::None;
}

Expand Down
2 changes: 2 additions & 0 deletions lib/Sema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ add_swift_library(swiftSema STATIC
ConstraintGraph.cpp
ConstraintLocator.cpp
ConstraintSystem.cpp
DerivedConformanceCodable.cpp
DerivedConformanceCodingKey.cpp
DerivedConformanceEquatableHashable.cpp
DerivedConformanceError.cpp
DerivedConformanceRawRepresentable.cpp
Expand Down
Loading

0 comments on commit 447dce6

Please sign in to comment.