[swift] master: swift-api-digester: teach the tool to keep track of ownership attributes. (4475b07)

Just curious - what is the swift-api-digester?

-Kenny

···

On Oct 27, 2016, at 11:55 AM, Xi Ge via swift-commits <swift-commits@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@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())

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.

···

On Oct 31, 2016, at 12:00 PM, Kenny Leung via swift-dev <swift-dev@swift.org> wrote:

-Kenny

On Oct 27, 2016, at 11:55 AM, Xi Ge via swift-commits <swift-commits@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@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@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

@Xi_Ge I see that this tool isn't shipped with Xcode or Swift.org toolchains. Do you think it'd be appropriate to use it for purposes other than testing? The functionality of dumping module to a JSON file would be pretty handy.

Do you have a particular use case in mind ? It would help to persuade @mishal_shah for putting it in the OSS toolchains.

That is for an internal analysis tool, for which I first have to have an overview of system SDKs. I already do this for ObjC modules with clang AST matchers, and would like to extend it for Swift since soon stdlib, overlay libraries won’t be bundled in application product.

As an example, you can see the JSON output for the stdlib here: https://raw.githubusercontent.com/apple/swift/master/test/api-digester/Inputs/stdlib-stable.json
Could you let us know if it's definitely going to be useful for your analysis tool ?

Yes, definitely. I was looking into the included information earlier today and it’s really promising. It even seems like I will be able to drop clang solution and use the tool for both ObjC and Swift, since we’re not using it for standalone headers, but actual frameworks anyway. Some of the things will be useful as they are and other can be extracted with little formatting (e.g. actual ObjC selectors). I’ve compiled it myself, but would certainly be nice if it was included in the toolchains.

Could you file a Jira task for putting swift-api-digester to the OSS toolchain? https://bugs.swift.org

sure, here's the task, thank you!