> On Oct 31, 2016, at 12:00 PM, Kenny Leung via swift-dev <[email protected]> > wrote: > > Just curious - what is the swift-api-digester? > swift-api-digester is a test utility to detect source-breaking API changes during the evolution of a Swift-compatible module. The tool works on two phases: (1) dumping module content as a JSON file, and (2) comparing two JSON files textually to report source-breaking changes.
> -Kenny > > >> On Oct 27, 2016, at 11:55 AM, Xi Ge via swift-commits >> <[email protected]> wrote: >> >> Repository : github.com/apple/swift >> On branch : master >> Link : >> github.com/apple/swift/commit/4475b0761337b3a379d0a88561a659c9c6d946db >> >>> --------------------------------------------------------------- >> >> commit 4475b0761337b3a379d0a88561a659c9c6d946db >> Author: Xi Ge <[email protected]> >> Date: Thu Oct 27 11:55:17 2016 -0700 >> >> swift-api-digester: teach the tool to keep track of ownership attributes. >> >> >>> --------------------------------------------------------------- >> >> 4475b0761337b3a379d0a88561a659c9c6d946db >> test/api-digester/Inputs/cake.swift | 2 + >> test/api-digester/Outputs/cake.json | 142 >> +++++++++++++++++++++++ >> tools/swift-api-digester/DigesterEnums.def | 1 + >> tools/swift-api-digester/swift-api-digester.cpp | 39 +++++-- >> 4 files changed, 176 insertions(+), 8 deletions(-) >> >> diff --git a/test/api-digester/Inputs/cake.swift >> b/test/api-digester/Inputs/cake.swift >> index 80f6d23..a61ac20 100644 >> --- a/test/api-digester/Inputs/cake.swift >> +++ b/test/api-digester/Inputs/cake.swift >> @@ -8,4 +8,6 @@ public struct S1 { >> >> public class C1 { >> open class func foo1() {} >> + public weak var Ins : C1? >> + public unowned var Ins2 : C1 = C1() >> } >> \ No newline at end of file >> diff --git a/test/api-digester/Outputs/cake.json >> b/test/api-digester/Outputs/cake.json >> index c29c338..e783b94 100644 >> --- a/test/api-digester/Outputs/cake.json >> +++ b/test/api-digester/Outputs/cake.json >> @@ -91,6 +91,148 @@ >> ] >> }, >> { >> + "kind": "Var", >> + "name": "Ins", >> + "printedName": "Ins", >> + "declKind": "Var", >> + "usr": "s:vC4cake2C13InsXwGSqS0__", >> + "location": "", >> + "moduleName": "cake", >> + "ownership": 1, >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "WeakStorage", >> + "printedName": "C1?" >> + }, >> + { >> + "kind": "Getter", >> + "name": "_", >> + "printedName": "_()", >> + "declKind": "Func", >> + "usr": "s:FC4cake2C1g3InsXwGSqS0__", >> + "location": "", >> + "moduleName": "cake", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "Optional", >> + "printedName": "C1?", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + } >> + ] >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + } >> + ] >> + }, >> + { >> + "kind": "Setter", >> + "name": "_", >> + "printedName": "_()", >> + "declKind": "Func", >> + "usr": "s:FC4cake2C1s3InsXwGSqS0__", >> + "location": "", >> + "moduleName": "cake", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "Void", >> + "printedName": "()" >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "Optional", >> + "printedName": "C1?", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + } >> + ] >> + } >> + ] >> + } >> + ] >> + }, >> + { >> + "kind": "Var", >> + "name": "Ins2", >> + "printedName": "Ins2", >> + "declKind": "Var", >> + "usr": "s:vC4cake2C14Ins2XoS0_", >> + "location": "", >> + "moduleName": "cake", >> + "ownership": 2, >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "UnownedStorage", >> + "printedName": "C1" >> + }, >> + { >> + "kind": "Getter", >> + "name": "_", >> + "printedName": "_()", >> + "declKind": "Func", >> + "usr": "s:FC4cake2C1g4Ins2XoS0_", >> + "location": "", >> + "moduleName": "cake", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + } >> + ] >> + }, >> + { >> + "kind": "Setter", >> + "name": "_", >> + "printedName": "_()", >> + "declKind": "Func", >> + "usr": "s:FC4cake2C1s4Ins2XoS0_", >> + "location": "", >> + "moduleName": "cake", >> + "children": [ >> + { >> + "kind": "TypeNominal", >> + "name": "Void", >> + "printedName": "()" >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + }, >> + { >> + "kind": "TypeNominal", >> + "name": "C1", >> + "printedName": "C1" >> + } >> + ] >> + } >> + ] >> + }, >> + { >> "kind": "Constructor", >> "name": "init", >> "printedName": "init()", >> diff --git a/tools/swift-api-digester/DigesterEnums.def >> b/tools/swift-api-digester/DigesterEnums.def >> index b123d2f..2e8ef29 100644 >> --- a/tools/swift-api-digester/DigesterEnums.def >> +++ b/tools/swift-api-digester/DigesterEnums.def >> @@ -73,6 +73,7 @@ KEY(static) >> KEY(typeAttributes) >> KEY(declAttributes) >> KEY(declKind) >> +KEY(ownership) >> >> KNOWN_TYPE(Optional) >> KNOWN_TYPE(ImplicitlyUnwrappedOptional) >> diff --git a/tools/swift-api-digester/swift-api-digester.cpp >> b/tools/swift-api-digester/swift-api-digester.cpp >> index c067945..eefef8f 100644 >> --- a/tools/swift-api-digester/swift-api-digester.cpp >> +++ b/tools/swift-api-digester/swift-api-digester.cpp >> @@ -228,23 +228,23 @@ static StringRef getKeyContent(KeyKind Kind) { >> } >> >> // The node kind appearing in the tree that describes the content of the SDK >> -enum class SDKNodeKind { >> +enum class SDKNodeKind: uint8_t { >> #define NODE_KIND(NAME) NAME, >> #include "DigesterEnums.def" >> }; >> >> -enum class NodeAnnotation { >> +enum class NodeAnnotation: uint8_t{ >> #define NODE_ANNOTATION(NAME) NAME, >> #include "DigesterEnums.def" >> }; >> >> -enum class KnownTypeKind { >> +enum class KnownTypeKind: uint8_t { >> #define KNOWN_TYPE(NAME) NAME, >> #include "DigesterEnums.def" >> Unknown, >> }; >> >> -enum class SDKDeclAttrKind { >> +enum class SDKDeclAttrKind: uint8_t { >> #define DECL_ATTR(Name) DAK_##Name, >> #include "DigesterEnums.def" >> }; >> @@ -283,6 +283,7 @@ struct SDKNodeInitInfo { >> bool IsMutating = false; >> bool IsStatic = false; >> Optional<uint8_t> SelfIndex; >> + Ownership Ownership = Ownership::Strong; >> std::vector<SDKDeclAttrKind> DeclAttrs; >> std::vector<TypeAttrKind> TypeAttrs; >> SDKNodeInitInfo() = default; >> @@ -344,13 +345,14 @@ class SDKNodeDecl : public SDKNode { >> StringRef ModuleName; >> std::vector<SDKDeclAttrKind> DeclAttributes; >> bool IsStatic; >> + uint8_t Ownership; >> bool hasDeclAttribute(SDKDeclAttrKind DAKind) const; >> >> protected: >> SDKNodeDecl(SDKNodeInitInfo Info, SDKNodeKind Kind) : SDKNode(Info, Kind), >> DKind(Info.DKind), Usr(Info.USR), Location(Info.Location), >> ModuleName(Info.ModuleName), DeclAttributes(Info.DeclAttrs), >> - IsStatic(Info.IsStatic) {} >> + IsStatic(Info.IsStatic), Ownership(uint8_t(Info.Ownership)) {} >> >> public: >> StringRef getUsr() const { return Usr; } >> @@ -358,6 +360,7 @@ public: >> StringRef getModuleName() const {return ModuleName;} >> void addDeclAttribute(SDKDeclAttrKind DAKind); >> ArrayRef<SDKDeclAttrKind> getDeclAttributes() const; >> + swift::Ownership getOwnership() const { return >> swift::Ownership(Ownership); } >> bool isObjc() const { return Usr.startswith("c:"); } >> static bool classof(const SDKNode *N); >> DeclKind getDeclKind() const { return DKind; } >> @@ -762,6 +765,10 @@ NodeUniquePtr >> SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) { >> auto WithQuote = cast<llvm::yaml::ScalarNode>(N)->getRawValue(); >> return WithQuote.substr(1, WithQuote.size() - 2); >> }; >> + >> + static auto getAsInt = [&](llvm::yaml::Node *N) -> int { >> + return std::stoi(cast<llvm::yaml::ScalarNode>(N)->getRawValue()); >> + }; >> SDKNodeKind Kind; >> SDKNodeInitInfo Info; >> NodeOwnedVector Children; >> @@ -778,8 +785,7 @@ NodeUniquePtr >> SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) { >> Info.Name = GetScalarString(Pair.getValue()); >> break; >> case KeyKind::KK_selfIndex: >> - Info.SelfIndex = >> std::stoi(cast<llvm::yaml::ScalarNode>(Pair.getValue())-> >> - getRawValue()); >> + Info.SelfIndex = getAsInt(Pair.getValue()); >> break; >> case KeyKind::KK_usr: >> Info.USR = GetScalarString(Pair.getValue()); >> @@ -808,6 +814,10 @@ NodeUniquePtr >> SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) { >> case KeyKind::KK_static: >> Info.IsStatic = true; >> break; >> + case KeyKind::KK_ownership: >> + Info.Ownership = swift::Ownership(getAsInt(Pair.getValue())); >> + assert(Info.Ownership != swift::Ownership::Strong && "Stong is >> implied."); >> + break; >> >> case KeyKind::KK_typeAttributes: { >> auto *Seq = cast<llvm::yaml::SequenceNode>(Pair.getValue()); >> @@ -1013,6 +1023,13 @@ static Optional<uint8_t> getSelfIndex(ValueDecl *VD) { >> return None; >> } >> >> +static Ownership getOwnership(ValueDecl *VD) { >> + if (auto OA = VD->getAttrs().getAttribute<OwnershipAttr>()) { >> + return OA->get(); >> + } >> + return Ownership::Strong; >> +} >> + >> SDKNodeInitInfo::SDKNodeInitInfo(Type Ty) : Name(getTypeName(Ty)), >> PrintedName(getPrintedName(Ty)) { >> if (isFunctionTypeNoEscape(Ty)) >> @@ -1025,7 +1042,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(ValueDecl *VD) : >> USR(calculateUsr(VD)), Location(calculateLocation(VD)), >> ModuleName(VD->getModuleContext()->getName().str()), >> IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)), >> - IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)) { >> + IsStatic(VD->isStatic()), SelfIndex(getSelfIndex(VD)), >> + Ownership(getOwnership(VD)) { >> if (VD->getAttrs().getDeprecated(VD->getASTContext())) >> DeclAttrs.push_back(SDKDeclAttrKind::DAK_deprecated); >> } >> @@ -1383,6 +1401,11 @@ namespace swift { >> if (!Attributes.empty()) >> out.mapRequired(getKeyContent(KeyKind::KK_declAttributes).data(), >> Attributes); >> + // Strong reference is implied, no need for serialization. >> + if (D->getOwnership() != Ownership::Strong) { >> + uint8_t Raw = uint8_t(D->getOwnership()); >> + out.mapRequired(getKeyContent(KeyKind::KK_ownership).data(), >> Raw); >> + } >> } else if (auto T = dyn_cast<SDKNodeType>(value.get())) { >> auto Attributes = T->getTypeAttributes(); >> if (!Attributes.empty()) >> > > _______________________________________________ > swift-dev mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-dev _______________________________________________ swift-dev mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-dev
