Skip to content

Commit

Permalink
swift-api-digester: teach the tool to keep track of ownership attribu…
Browse files Browse the repository at this point in the history
…tes.
  • Loading branch information
nkcsgexi committed Oct 27, 2016
1 parent d0581ea commit 4475b07
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 8 deletions.
2 changes: 2 additions & 0 deletions test/api-digester/Inputs/cake.swift
Expand Up @@ -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()
}
142 changes: 142 additions & 0 deletions test/api-digester/Outputs/cake.json
Expand Up @@ -90,6 +90,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",
Expand Down
1 change: 1 addition & 0 deletions tools/swift-api-digester/DigesterEnums.def
Expand Up @@ -73,6 +73,7 @@ KEY(static)
KEY(typeAttributes)
KEY(declAttributes)
KEY(declKind)
KEY(ownership)

KNOWN_TYPE(Optional)
KNOWN_TYPE(ImplicitlyUnwrappedOptional)
Expand Down
39 changes: 31 additions & 8 deletions tools/swift-api-digester/swift-api-digester.cpp
Expand Up @@ -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"
};
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -344,20 +345,22 @@ 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; }
StringRef getLocation() const { return Location; }
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; }
Expand Down Expand Up @@ -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;
Expand All @@ -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());
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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))
Expand All @@ -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);
}
Expand Down Expand Up @@ -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())
Expand Down

0 comments on commit 4475b07

Please sign in to comment.