From ab9b035dbcc689da07b703e018f411612f9ce6b4 Mon Sep 17 00:00:00 2001 From: Xi Ge Date: Thu, 13 Oct 2016 11:21:44 -0700 Subject: [PATCH 1/2] [test] api-digester: add a test to ensure the dumped module content is expected. --- test/api-digester/Inputs/cake.swift | 4 ++ test/api-digester/Outputs/cake.json | 66 +++++++++++++++++++ test/api-digester/dump-module.swift | 7 ++ .../swift-api-digester/swift-api-digester.cpp | 4 ++ 4 files changed, 81 insertions(+) create mode 100644 test/api-digester/Inputs/cake.swift create mode 100644 test/api-digester/Outputs/cake.json create mode 100644 test/api-digester/dump-module.swift diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift new file mode 100644 index 0000000000000..e38e5be38944e --- /dev/null +++ b/test/api-digester/Inputs/cake.swift @@ -0,0 +1,4 @@ +public struct S1 { + public func foo1() {} + public func foo2() {} +} \ No newline at end of file diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json new file mode 100644 index 0000000000000..ba7646f44bc7f --- /dev/null +++ b/test/api-digester/Outputs/cake.json @@ -0,0 +1,66 @@ +{ + "kind": "Root", + "name": "TopLevel", + "printedName": "TopLevel", + "children": [ + { + "kind": "TypeDecl", + "name": "S1", + "printedName": "S1", + "declKind": "Struct", + "usr": "s:V4cake2S1", + "location": "", + "moduleName": "cake", + "children": [ + { + "kind": "Function", + "name": "foo1", + "printedName": "foo1()", + "declKind": "Func", + "usr": "s:FV4cake2S14foo1FT_T_", + "location": "", + "moduleName": "cake", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ] + }, + { + "kind": "Function", + "name": "foo2", + "printedName": "foo2()", + "declKind": "Func", + "usr": "s:FV4cake2S14foo2FT_T_", + "location": "", + "moduleName": "cake", + "children": [ + { + "kind": "TypeNominal", + "name": "Void", + "printedName": "()" + } + ] + }, + { + "kind": "Constructor", + "name": "init", + "printedName": "init()", + "declKind": "Constructor", + "usr": "s:FV4cake2S1cFT_S0_", + "location": "", + "moduleName": "cake", + "children": [ + { + "kind": "TypeNominal", + "name": "S1", + "printedName": "S1" + } + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/test/api-digester/dump-module.swift b/test/api-digester/dump-module.swift new file mode 100644 index 0000000000000..9673dc563e1d2 --- /dev/null +++ b/test/api-digester/dump-module.swift @@ -0,0 +1,7 @@ +// RUN: rm -rf %t.mod && mkdir -p %t.mod +// RUN: rm -rf %t.sdk && mkdir -p %t.sdk +// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache +// RUN: %swift -emit-module -o %t.mod/cake.swiftmodule %S/Inputs/cake.swift -parse-as-library +// RUN: %api-digester -dump-sdk -module cake -o %t.dump.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3.0 -I %t.mod +// RUN: diff -u %t.dump.json %S/Outputs/cake.json +// RUN: %api-digester -diagnose-sdk --input-paths %t.dump.json -input-paths %S/Outputs/cake.json diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp index 02a9e72cf05cb..b91ee79651b35 100644 --- a/tools/swift-api-digester/swift-api-digester.cpp +++ b/tools/swift-api-digester/swift-api-digester.cpp @@ -98,6 +98,9 @@ ResourceDir("resource-dir", static llvm::cl::list FrameworkPaths("F", llvm::cl::desc("add a directory to the framework search path")); +static llvm::cl::list +ModuleInputPaths("I", llvm::cl::desc("add a module for input")); + static llvm::cl::opt AbortOnModuleLoadFailure("abort-on-module-fail", llvm::cl::desc("Abort if a module failed to load")); @@ -3303,6 +3306,7 @@ static int prepareForDump(const char *Main, InitInvok.setRuntimeResourcePath(options::ResourceDir); } InitInvok.setFrameworkSearchPaths(options::FrameworkPaths); + InitInvok.setImportSearchPaths(options::ModuleInputPaths); if (!options::ModuleList.empty()) { if (readFileLineByLine(options::ModuleList, Modules)) From 55f194b3efe6a353fcee522df154d361d8135e59 Mon Sep 17 00:00:00 2001 From: Xi Ge Date: Thu, 13 Oct 2016 11:38:52 -0700 Subject: [PATCH 2/2] api-digester: in module dump, record whether a func decl is mutating. --- test/api-digester/Inputs/cake.swift | 2 +- test/api-digester/Outputs/cake.json | 1 + tools/swift-api-digester/DigesterEnums.def | 1 + .../swift-api-digester/swift-api-digester.cpp | 18 +++++++++++++++++- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/test/api-digester/Inputs/cake.swift b/test/api-digester/Inputs/cake.swift index e38e5be38944e..b956e7b575591 100644 --- a/test/api-digester/Inputs/cake.swift +++ b/test/api-digester/Inputs/cake.swift @@ -1,4 +1,4 @@ public struct S1 { public func foo1() {} - public func foo2() {} + mutating public func foo2() {} } \ No newline at end of file diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json index ba7646f44bc7f..bff7b72633a15 100644 --- a/test/api-digester/Outputs/cake.json +++ b/test/api-digester/Outputs/cake.json @@ -36,6 +36,7 @@ "usr": "s:FV4cake2S14foo2FT_T_", "location": "", "moduleName": "cake", + "mutating": true, "children": [ { "kind": "TypeNominal", diff --git a/tools/swift-api-digester/DigesterEnums.def b/tools/swift-api-digester/DigesterEnums.def index 1ddbdf2bb7f9b..e2e8852d35a20 100644 --- a/tools/swift-api-digester/DigesterEnums.def +++ b/tools/swift-api-digester/DigesterEnums.def @@ -66,6 +66,7 @@ KEY(children) KEY(printedName) KEY(moduleName) KEY(throwing) +KEY(mutating) KEY(typeAttributes) KEY(declAttributes) KEY(declKind) diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp index b91ee79651b35..9bb45fe005f16 100644 --- a/tools/swift-api-digester/swift-api-digester.cpp +++ b/tools/swift-api-digester/swift-api-digester.cpp @@ -261,6 +261,7 @@ struct SDKNodeInitInfo { StringRef Location; StringRef ModuleName; bool IsThrowing = false; + bool IsMutating = false; Optional SelfIndex; std::vector DeclAttrs; std::vector TypeAttrs; @@ -683,15 +684,18 @@ class SDKNodeVar : public SDKNodeDecl { class SDKNodeAbstractFunc : public SDKNodeDecl { const bool IsThrowing; + const bool IsMutating; const Optional SelfIndex; protected: SDKNodeAbstractFunc(SDKNodeInitInfo Info, SDKNodeKind Kind) : SDKNodeDecl(Info, Kind), IsThrowing(Info.IsThrowing), + IsMutating(Info.IsMutating), SelfIndex(Info.SelfIndex){} public: bool isThrowing() const { return IsThrowing; } + bool isMutating() const { return IsMutating; } uint8_t getSelfIndex() const { return SelfIndex.getValue(); } Optional getSelfIndexOptional() const { return SelfIndex; } bool hasSelfIndex() const { return SelfIndex.hasValue(); } @@ -800,6 +804,8 @@ NodeUniquePtr SDKNode::constructSDKNode(llvm::yaml::MappingNode *Node) { Info.ModuleName = GetScalarString(Pair.getValue()); } else if (Key == Key_throwing) { Info.IsThrowing = true; + } else if (Key == Key_mutating) { + Info.IsMutating = true; } else if (Key == Key_typeAttributes) { auto *Seq = cast(Pair.getValue()); for (auto It = Seq->begin(); It != Seq->end(); ++ It) { @@ -946,6 +952,13 @@ static bool isFuncThrowing(ValueDecl *VD) { return false; } +static bool isFuncMutating(ValueDecl *VD) { + if (auto AF = dyn_cast(VD)) { + return AF->isMutating(); + } + return false; +} + static Optional getSelfIndex(ValueDecl *VD) { if (auto AF = dyn_cast(VD)) { if (AF->isImportAsInstanceMember()) @@ -965,7 +978,8 @@ SDKNodeInitInfo::SDKNodeInitInfo(ValueDecl *VD) : PrintedName(getPrintedName(VD)), DKind(VD->getKind()), USR(calculateUsr(VD)), Location(calculateLocation(VD)), ModuleName(VD->getModuleContext()->getName().str()), - IsThrowing(isFuncThrowing(VD)), SelfIndex(getSelfIndex(VD)) { + IsThrowing(isFuncThrowing(VD)), IsMutating(isFuncMutating(VD)), + SelfIndex(getSelfIndex(VD)) { if (VD->getAttrs().getDeprecated(VD->getASTContext())) DeclAttrs.push_back(SDKDeclAttrKind::DAK_deprecated); } @@ -1296,6 +1310,8 @@ namespace swift { if (auto F = dyn_cast(value.get())) { if (bool isThrowing = F->isThrowing()) out.mapRequired(Key_throwing, isThrowing); + if (bool isMutating = F->isMutating()) + out.mapRequired(Key_mutating, isMutating); if (F->hasSelfIndex()) { auto Index = F->getSelfIndex(); out.mapRequired(Key_selfIndex, Index);