mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
swift-api-digester: Add a data structure APIDiffItemStore. (#8794)
This structure serves multiple purposes: a. Allow migrator to speak in the same language with swift-api-digester in terms of API changes. b. Serialize/Deserialize detected API change items in JSON format. c. Manage memory after deserializing API change items. d. Facilitate look up by USRs of APIs under migration. The structure is tested by round-trip serialization and deserialization.
This commit is contained in:
@@ -67,6 +67,7 @@ namespace {
|
||||
DumpSwiftModules,
|
||||
CompareSDKs,
|
||||
DiagnoseSDKs,
|
||||
DeserializeDiffItems,
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
@@ -128,7 +129,10 @@ Action(llvm::cl::desc("Mode:"), llvm::cl::init(ActionType::None),
|
||||
"Compare SDK content in JSON file"),
|
||||
clEnumValN(ActionType::DiagnoseSDKs,
|
||||
"diagnose-sdk",
|
||||
"Diagnose SDK content in JSON file")));
|
||||
"Diagnose SDK content in JSON file"),
|
||||
clEnumValN(ActionType::DeserializeDiffItems,
|
||||
"deserialize-diff",
|
||||
"Deserialize diff items in a JSON file")));
|
||||
|
||||
static llvm::cl::list<std::string>
|
||||
SDKJsonPaths("input-paths",
|
||||
@@ -147,6 +151,9 @@ IgnoreRemovedDeclUSRs("ignored-usrs",
|
||||
static llvm::cl::opt<std::string>
|
||||
SwiftVersion("swift-version",
|
||||
llvm::cl::desc("The Swift compiler version to invoke"));
|
||||
|
||||
static llvm::cl::opt<bool>
|
||||
OutputInJson("json", llvm::cl::desc("Print output in JSON format."));
|
||||
} // namespace options
|
||||
|
||||
namespace {
|
||||
@@ -766,10 +773,7 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
|
||||
for (auto Pair : *Node) {
|
||||
switch(parseKeyKind(GetScalarString(Pair.getKey()))) {
|
||||
case KeyKind::KK_kind:
|
||||
Kind = llvm::StringSwitch<SDKNodeKind>(GetScalarString(Pair.getValue()))
|
||||
#define NODE_KIND(NAME) .Case(#NAME, SDKNodeKind::NAME)
|
||||
#include "swift/IDE/DigesterEnums.def"
|
||||
;
|
||||
Kind = parseSDKNodeKind(GetScalarString(Pair.getValue()));
|
||||
break;
|
||||
case KeyKind::KK_name:
|
||||
Info.Name = GetScalarString(Pair.getValue());
|
||||
@@ -1343,14 +1347,6 @@ namespace swift {
|
||||
// In the namespace of swift::json, we define several functions so that the
|
||||
// JSON serializer will know how to interpret and dump types defined in this
|
||||
// file.
|
||||
template<>
|
||||
struct ScalarEnumerationTraits<SDKNodeKind> {
|
||||
static void enumeration(Output &out, SDKNodeKind &value) {
|
||||
#define NODE_KIND(X) out.enumCase(value, #X, SDKNodeKind::X);
|
||||
#include "swift/IDE/DigesterEnums.def"
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ScalarEnumerationTraits<TypeAttrKind> {
|
||||
static void enumeration(Output &out, TypeAttrKind &value) {
|
||||
@@ -2329,7 +2325,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::vector<DiffItem> DiffVector;
|
||||
typedef std::vector<CommonDiffItem> DiffVector;
|
||||
|
||||
typedef std::vector<TypeMemberDiffItem> TypeMemberDiffVector;
|
||||
|
||||
@@ -3068,7 +3064,8 @@ static int compareSDKs(StringRef LeftPath, StringRef RightPath,
|
||||
RefinementPass.pass(LeftModule, RightModule);
|
||||
DiffVector AllItems;
|
||||
DiffItemEmitter::collectDiffItems(LeftModule, AllItems);
|
||||
AllItems.erase(std::remove_if(AllItems.begin(), AllItems.end(), [&](DiffItem &Item) {
|
||||
AllItems.erase(std::remove_if(AllItems.begin(), AllItems.end(),
|
||||
[&](CommonDiffItem &Item) {
|
||||
return Item.DiffKind == NodeAnnotation::RemovedDecl &&
|
||||
IgnoredRemoveUsrs.find(Item.LeftUsr) != IgnoredRemoveUsrs.end();
|
||||
}), AllItems.end());
|
||||
@@ -3082,7 +3079,23 @@ static int compareSDKs(StringRef LeftPath, StringRef RightPath,
|
||||
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream Fs(DiffPath, EC, llvm::sys::fs::F_None);
|
||||
|
||||
if (options::OutputInJson) {
|
||||
std::vector<APIDiffItem*> TotalItems;
|
||||
std::transform(AllItems.begin(), AllItems.end(),
|
||||
std::back_inserter(TotalItems),
|
||||
[](CommonDiffItem &Item) { return &Item; });
|
||||
std::transform(typeMemberDiffs.begin(), typeMemberDiffs.end(),
|
||||
std::back_inserter(TotalItems),
|
||||
[](TypeMemberDiffItem &Item) { return &Item; });
|
||||
std::transform(AllNoEscapingFuncs.begin(), AllNoEscapingFuncs.end(),
|
||||
std::back_inserter(TotalItems),
|
||||
[](NoEscapeFuncParam &Item) { return &Item; });
|
||||
std::transform(Overloads.begin(), Overloads.end(),
|
||||
std::back_inserter(TotalItems),
|
||||
[](OverloadedFuncInfo &Item) { return &Item; });
|
||||
APIDiffItemStore::serialize(Fs, TotalItems);
|
||||
return 0;
|
||||
}
|
||||
serializeDiffs(Fs, AllItems);
|
||||
serializeDiffs(Fs, typeMemberDiffs);
|
||||
serializeDiffs(Fs, AllNoEscapingFuncs);
|
||||
@@ -3309,6 +3322,15 @@ static void readIgnoredUsrs(llvm::StringSet<> &IgnoredUsrs) {
|
||||
readFileLineByLine(Path, IgnoredUsrs);
|
||||
}
|
||||
|
||||
static int deserializeDiffItems(StringRef DiffPath, StringRef OutputPath) {
|
||||
APIDiffItemStore Store;
|
||||
Store.addStorePath(DiffPath);
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream FS(OutputPath, EC, llvm::sys::fs::F_None);
|
||||
APIDiffItemStore::serialize(FS, Store.getAllDiffItems());
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
INITIALIZE_LLVM(argc, argv);
|
||||
|
||||
@@ -3344,6 +3366,13 @@ int main(int argc, char *argv[]) {
|
||||
else
|
||||
return diagnoseModuleChange(options::SDKJsonPaths[0],
|
||||
options::SDKJsonPaths[1]);
|
||||
case ActionType::DeserializeDiffItems: {
|
||||
if (options::SDKJsonPaths.size() != 1) {
|
||||
llvm::cl::PrintHelpMessage();
|
||||
return 1;
|
||||
}
|
||||
return deserializeDiffItems(options::SDKJsonPaths[0], options::OutputFile);
|
||||
}
|
||||
case ActionType::None:
|
||||
llvm::errs() << "Action required\n";
|
||||
llvm::cl::PrintHelpMessage();
|
||||
|
||||
Reference in New Issue
Block a user