[swift-dev] [swift] master: swift-api-digester: teach the tool to keep track of ownership attributes. (4475b07)
Xi Ge
xi_ge at apple.com
Mon Oct 31 14:03:55 CDT 2016
> On Oct 31, 2016, at 12:00 PM, Kenny Leung via swift-dev <swift-dev at swift.org> 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 <swift-commits at swift.org> wrote:
>>
>> Repository : github.com/apple/swift
>> On branch : master
>> Link : github.com/apple/swift/commit/4475b0761337b3a379d0a88561a659c9c6d946db
>>
>>> ---------------------------------------------------------------
>>
>> commit 4475b0761337b3a379d0a88561a659c9c6d946db
>> Author: Xi Ge <xi_ge at apple.com>
>> 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
> swift-dev at swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev
More information about the swift-dev
mailing list