Skip to content

swift-module-digester: include operator declarations in the module dump. #19647

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/swift/IDE/DigesterEnums.def
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ NODE_KIND(DeclSetter, Setter)
NODE_KIND(DeclSubscript, Subscript)
NODE_KIND_RANGE(DeclAbstractFunc, DeclFunction, DeclSubscript)

NODE_KIND(DeclOperator, OperatorDecl)
NODE_KIND(DeclType, TypeDecl)
NODE_KIND(DeclVar, Var)
NODE_KIND(DeclTypeAlias, TypeAlias)
Expand Down
2 changes: 2 additions & 0 deletions test/api-digester/Inputs/cake.swift
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,5 @@ public let GlobalVar = 1
public extension P1 {
static func +(lhs: P1, rhs: P1) -> P1 { return lhs }
}

infix operator ..*..
10 changes: 10 additions & 0 deletions test/api-digester/Outputs/cake-abi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1147,6 +1147,16 @@
"isLet": true,
"hasStorage": true
},
{
"kind": "OperatorDecl",
"name": "..*..",
"printedName": "..*..",
"declKind": "InfixOperator",
"moduleName": "cake",
"declAttributes": [
"Infix"
]
},
{
"kind": "TypeDecl",
"name": "Int",
Expand Down
10 changes: 10 additions & 0 deletions test/api-digester/Outputs/cake.json
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,16 @@
"isLet": true,
"hasStorage": true
},
{
"kind": "OperatorDecl",
"name": "..*..",
"printedName": "..*..",
"declKind": "InfixOperator",
"moduleName": "cake",
"declAttributes": [
"Infix"
]
},
{
"kind": "TypeDecl",
"name": "Int",
Expand Down
105 changes: 72 additions & 33 deletions tools/swift-api-digester/ModuleAnalyzerNodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ struct swift::ide::api::SDKNodeInitInfo {
std::vector<TypeAttrKind> TypeAttrs;

SDKNodeInitInfo(SDKContext &Ctx) : Ctx(Ctx) {}
SDKNodeInitInfo(SDKContext &Ctx, Decl *D);
SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD);
SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *D);
SDKNodeInitInfo(SDKContext &Ctx, Type Ty, bool IsImplicitlyUnwrappedOptional,
bool hasDefaultArgument);
SDKNode* createSDKNode(SDKNodeKind Kind);
Expand All @@ -55,6 +57,15 @@ SDKContext::SDKContext(CheckerOptions Opts): Diags(SourceMgr), Opts(Opts) {
#undef ADD
}

void SDKNodeRoot::registerDescendant(SDKNode *D) {
// Operator doesn't have usr
if (isa<SDKNodeDeclOperator>(D))
return;
if (auto DD = dyn_cast<SDKNodeDecl>(D)) {
assert(!DD->getUsr().empty());
DescendantDeclTable[DD->getUsr()].insert(DD);
}
}

SDKNode::SDKNode(SDKNodeInitInfo Info, SDKNodeKind Kind): Ctx(Info.Ctx),
Name(Info.Name), PrintedName(Info.PrintedName), TheKind(unsigned(Kind)) {}
Expand Down Expand Up @@ -86,12 +97,15 @@ SDKNodeTypeFunc::SDKNodeTypeFunc(SDKNodeInitInfo Info):
SDKNodeTypeAlias::SDKNodeTypeAlias(SDKNodeInitInfo Info):
SDKNodeType(Info, SDKNodeKind::TypeAlias) {}

SDKNodeDeclType::SDKNodeDeclType(SDKNodeInitInfo Info):
SDKNodeDeclType::SDKNodeDeclType(SDKNodeInitInfo Info):
SDKNodeDecl(Info, SDKNodeKind::DeclType), SuperclassUsr(Info.SuperclassUsr),
SuperclassNames(Info.SuperclassNames),
ConformingProtocols(Info.ConformingProtocols),
EnumRawTypeName(Info.EnumRawTypeName) {}

SDKNodeDeclOperator::SDKNodeDeclOperator(SDKNodeInitInfo Info):
SDKNodeDecl(Info, SDKNodeKind::DeclOperator) {}

SDKNodeDeclTypeAlias::SDKNodeDeclTypeAlias(SDKNodeInitInfo Info):
SDKNodeDecl(Info, SDKNodeKind::DeclTypeAlias) {}

Expand Down Expand Up @@ -306,6 +320,7 @@ StringRef SDKNodeType::getTypeRoleDescription() const {
case SDKNodeKind::TypeFunc:
case SDKNodeKind::TypeAlias:
case SDKNodeKind::DeclType:
case SDKNodeKind::DeclOperator:
llvm_unreachable("Type Parent is wrong");
case SDKNodeKind::DeclFunction:
case SDKNodeKind::DeclConstructor:
Expand Down Expand Up @@ -719,6 +734,7 @@ bool static isSDKNodeEqual(SDKContext &Ctx, const SDKNode &L, const SDKNode &R)
}
LLVM_FALLTHROUGH;
}
case SDKNodeKind::DeclOperator:
case SDKNodeKind::DeclTypeAlias: {
auto Left = L.getAs<SDKNodeDecl>();
auto Right = R.getAs<SDKNodeDecl>();
Expand Down Expand Up @@ -820,14 +836,14 @@ static StringRef calculateUsr(SDKContext &Ctx, ValueDecl *VD) {
return StringRef();
}

static StringRef calculateLocation(SDKContext &SDKCtx, ValueDecl *VD) {
static StringRef calculateLocation(SDKContext &SDKCtx, Decl *D) {
if (SDKCtx.getOpts().AvoidLocation)
return StringRef();
auto &Ctx = VD->getASTContext();
auto &Ctx = D->getASTContext();
auto &Importer = static_cast<ClangImporter &>(*Ctx.getClangModuleLoader());

clang::SourceManager &SM = Importer.getClangPreprocessor().getSourceManager();
if (ClangNode CN = VD->getClangNode()) {
if (ClangNode CN = D->getClangNode()) {
clang::SourceLocation Loc = CN.getLocation();
Loc = SM.getFileLoc(Loc);
if (Loc.isValid())
Expand Down Expand Up @@ -926,10 +942,10 @@ Requirement getCanonicalRequirement(Requirement &Req) {
}
}

static StringRef printGenericSignature(SDKContext &Ctx, ValueDecl *VD) {
static StringRef printGenericSignature(SDKContext &Ctx, Decl *D) {
llvm::SmallString<32> Result;
llvm::raw_svector_ostream OS(Result);
if (auto *PD = dyn_cast<ProtocolDecl>(VD)) {
if (auto *PD = dyn_cast<ProtocolDecl>(D)) {
if (PD->getRequirementSignature().empty())
return StringRef();
OS << "<";
Expand All @@ -949,7 +965,7 @@ static StringRef printGenericSignature(SDKContext &Ctx, ValueDecl *VD) {
return Ctx.buffer(OS.str());
}

if (auto *GC = VD->getAsGenericContext()) {
if (auto *GC = D->getAsGenericContext()) {
if (auto *Sig = GC->getGenericSignature()) {
if (Ctx.checkingABI())
Sig->getCanonicalSignature()->print(OS);
Expand Down Expand Up @@ -1008,23 +1024,40 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Type Ty,
}
}

SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, Decl *D):
Ctx(Ctx), DKind(D->getKind()),
Location(calculateLocation(Ctx, D)),
ModuleName(D->getModuleContext()->getName().str()),
GenericSig(printGenericSignature(Ctx, D)),
IsImplicit(D->isImplicit()),
IsDeprecated(D->getAttrs().getDeprecated(D->getASTContext())) {
// Capture all attributes.
auto AllAttrs = D->getAttrs();
std::transform(AllAttrs.begin(), AllAttrs.end(), std::back_inserter(DeclAttrs),
[](DeclAttribute *attr) { return attr->getKind(); });
}

SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, OperatorDecl *OD):
SDKNodeInitInfo(Ctx, cast<Decl>(OD)) {
Name = OD->getName().str();
PrintedName = OD->getName().str();
}

SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
: Ctx(Ctx), DKind(VD->getKind()),
Name(VD->hasName() ? getEscapedName(VD->getBaseName()) : Ctx.buffer("_")),
PrintedName(getPrintedName(Ctx, VD)),
Usr(calculateUsr(Ctx, VD)), Location(calculateLocation(Ctx, VD)),
ModuleName(VD->getModuleContext()->getName().str()),
GenericSig(printGenericSignature(Ctx, VD)),
IsImplicit(VD->isImplicit()),
IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)),
IsStatic(VD->isStatic()),
IsDeprecated(VD->getAttrs().getDeprecated(VD->getASTContext())),
IsOverriding(VD->getOverriddenDecl()),
IsProtocolReq(isa<ProtocolDecl>(VD->getDeclContext()) && VD->isProtocolRequirement()),
IsOpen(VD->getFormalAccess() == AccessLevel::Open),
IsInternal(VD->getFormalAccess() < AccessLevel::Public),
SelfIndex(getSelfIndex(VD)), FixedBinaryOrder(getFixedBinaryOrder(VD)),
ReferenceOwnership(getReferenceOwnership(VD)) {
: SDKNodeInitInfo(Ctx, cast<Decl>(VD)) {
Name = VD->hasName() ? getEscapedName(VD->getBaseName()) : Ctx.buffer("_");
PrintedName = getPrintedName(Ctx, VD);
Usr = calculateUsr(Ctx, VD);
IsThrowing = isFuncThrowing(VD);
IsMutating = isFuncMutating(VD);
IsStatic = VD->isStatic();
IsOverriding = VD->getOverriddenDecl();
IsProtocolReq = isa<ProtocolDecl>(VD->getDeclContext()) && VD->isProtocolRequirement();
IsOpen = VD->getFormalAccess() == AccessLevel::Open;
IsInternal = VD->getFormalAccess() < AccessLevel::Public;
SelfIndex = getSelfIndex(VD);
FixedBinaryOrder = getFixedBinaryOrder(VD);
ReferenceOwnership = getReferenceOwnership(VD);

// Calculate usr for its super class.
if (auto *CD = dyn_cast_or_null<ClassDecl>(VD)) {
Expand All @@ -1036,11 +1069,6 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
}
}

// Capture all attributes.
auto AllAttrs = VD->getAttrs();
std::transform(AllAttrs.begin(), AllAttrs.end(), std::back_inserter(DeclAttrs),
[](DeclAttribute *attr) { return attr->getKind(); });

// Get all protocol names this type decl conforms to.
if (auto *NTD = dyn_cast<NominalTypeDecl>(VD)) {
for (auto *P: NTD->getAllProtocols()) {
Expand Down Expand Up @@ -1178,8 +1206,6 @@ SwiftDeclCollector::shouldIgnore(Decl *D, const Decl* Parent) {
return true;
if (isa<ConstructorDecl>(D))
return false;
if (isa<OperatorDecl>(D))
return true;
if (auto VD = dyn_cast<ValueDecl>(D)) {
if (VD->getBaseName().empty())
return true;
Expand Down Expand Up @@ -1340,6 +1366,8 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules) {
KnownDecls.insert(D);
if (auto VD = dyn_cast<ValueDecl>(D))
foundDecl(VD, DeclVisibilityKind::DynamicLookup);
else
processDecl(D);
}
}

Expand All @@ -1353,7 +1381,7 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules) {
});

for (auto *VD : ClangMacros)
processDecl(VD);
processValueDecl(VD);

// Collect extensions to types from other modules and synthesize type nodes
// for them.
Expand All @@ -1370,7 +1398,18 @@ void SwiftDeclCollector::lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules) {
}
}

void SwiftDeclCollector::processDecl(ValueDecl *VD) {
SDKNode *SwiftDeclCollector::constructOperatorDeclNode(OperatorDecl *OD) {
return SDKNodeInitInfo(Ctx, OD).createSDKNode(SDKNodeKind::DeclOperator);
}

void SwiftDeclCollector::processDecl(Decl *D) {
assert(!isa<ValueDecl>(D));
if (auto *OD = dyn_cast<OperatorDecl>(D)) {
RootNode->addChild(constructOperatorDeclNode(OD));
}
}

void SwiftDeclCollector::processValueDecl(ValueDecl *VD) {
if (auto FD = dyn_cast<FuncDecl>(VD)) {
RootNode->addChild(constructFunctionNode(FD, SDKNodeKind::DeclFunction));
} else if (auto NTD = dyn_cast<NominalTypeDecl>(VD)) {
Expand All @@ -1391,7 +1430,7 @@ void SwiftDeclCollector::foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) {
return;
}

processDecl(VD);
processValueDecl(VD);
}

void SDKNode::output(json::Output &out, KeyKind Key, bool Value) {
Expand Down
19 changes: 11 additions & 8 deletions tools/swift-api-digester/ModuleAnalyzerNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,12 +339,7 @@ class SDKNodeRoot: public SDKNode {
SDKNodeRoot(SDKNodeInitInfo Info);
static SDKNode *getInstance(SDKContext &Ctx);
static bool classof(const SDKNode *N);
void registerDescendant(SDKNode *D) {
if (auto DD = dyn_cast<SDKNodeDecl>(D)) {
assert(!DD->getUsr().empty());
DescendantDeclTable[DD->getUsr()].insert(DD);
}
}
void registerDescendant(SDKNode *D);
ArrayRef<SDKNodeDecl*> getDescendantsByUsr(StringRef Usr) {
return DescendantDeclTable[Usr].getArrayRef();
}
Expand Down Expand Up @@ -468,6 +463,12 @@ class SDKNodeDeclType: public SDKNodeDecl {
void diagnose(SDKNode *Right) override;
};

class SDKNodeDeclOperator : public SDKNodeDecl {
public:
SDKNodeDeclOperator(SDKNodeInitInfo Info);
static bool classof(const SDKNode *N);
};

class SDKNodeDeclTypeAlias : public SDKNodeDecl {
public:
SDKNodeDeclTypeAlias(SDKNodeInitInfo Info);
Expand Down Expand Up @@ -600,13 +601,15 @@ class SwiftDeclCollector: public VisibleDeclConsumer {
SDKNode *constructTypeDeclNode(NominalTypeDecl *NTD);
SDKNode *constructInitNode(ConstructorDecl *CD);
SDKNode *constructFunctionNode(FuncDecl* FD, SDKNodeKind Kind);
SDKNode *constructOperatorDeclNode(OperatorDecl *OD);
std::vector<SDKNode*> createParameterNodes(ParameterList *PL);
SDKNode *constructTypeNode(Type T, bool IsImplicitlyUnwrappedOptional = false,
bool hasDefaultArgument = false);
void processValueDecl(ValueDecl *VD);
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override;
void processDecl(Decl *D);
public:
void lookupVisibleDecls(ArrayRef<ModuleDecl *> Modules);
void processDecl(ValueDecl *VD);
void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override;
};

int dumpSwiftModules(const CompilerInvocation &InitInvok,
Expand Down
1 change: 1 addition & 0 deletions tools/swift-api-digester/swift-api-digester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,7 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
break;
}

case SDKNodeKind::DeclOperator:
case SDKNodeKind::DeclSubscript:
case SDKNodeKind::DeclAssociatedType:
case SDKNodeKind::DeclFunction:
Expand Down