[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