swift-api-digester: teach the tool do detect APINotes' moving one member variable/method to another type. (#9985)

Different from type hoist that moves global variables to static member
variables, we've also seen member variables being moved among different
types via apinotes. Swift-api-digester should be able to detect such
case so that migrator can handle them properly.

rdar://32466196
This commit is contained in:
Xi Ge
2017-05-30 14:23:32 -07:00
committed by GitHub
parent 1043628688
commit d1b0e67620
12 changed files with 60 additions and 3 deletions

View File

@@ -231,6 +231,7 @@ struct TypeMemberDiffItem: public APIDiffItem {
StringRef newPrintedName;
Optional<uint8_t> selfIndex;
Optional<uint8_t> removedIndex;
StringRef oldTypeName;
StringRef oldPrintedName;
private:
@@ -243,10 +244,10 @@ public:
public:
TypeMemberDiffItem(StringRef usr, StringRef newTypeName,
StringRef newPrintedName, Optional<uint8_t> selfIndex,
Optional<uint8_t> removedIndex,
Optional<uint8_t> removedIndex, StringRef oldTypeName,
StringRef oldPrintedName) : usr(usr),
newTypeName(newTypeName), newPrintedName(newPrintedName),
selfIndex(selfIndex), removedIndex(removedIndex),
selfIndex(selfIndex), removedIndex(removedIndex), oldTypeName(oldTypeName),
oldPrintedName(oldPrintedName), OldNameViewer(oldPrintedName),
NewNameViewer(newPrintedName), Subkind(getSubKind()) {}
static StringRef head();

View File

@@ -120,6 +120,7 @@ DIFF_ITEM_KEY_KIND_STRING(RightComment)
DIFF_ITEM_KEY_KIND_STRING(ModuleName)
DIFF_ITEM_KEY_KIND_STRING(NewTypeName)
DIFF_ITEM_KEY_KIND_STRING(NewPrintedName)
DIFF_ITEM_KEY_KIND_STRING(OldTypeName)
DIFF_ITEM_KEY_KIND_STRING(OldPrintedName)
DIFF_ITEM_KEY_KIND_STRING(SpecialCaseId)

View File

@@ -325,7 +325,7 @@ serializeDiffItem(llvm::BumpPtrAllocator &Alloc,
RemovedIndexShort = RemovedIndex.getValue();
return new (Alloc.Allocate<TypeMemberDiffItem>())
TypeMemberDiffItem(Usr, NewTypeName, NewPrintedName, SelfIndexShort,
RemovedIndexShort, OldPrintedName);
RemovedIndexShort, OldTypeName, OldPrintedName);
}
case APIDiffItemKind::ADK_NoEscapeFuncParam: {
return new (Alloc.Allocate<NoEscapeFuncParam>())
@@ -393,6 +393,8 @@ struct ObjectTraits<APIDiffItem*> {
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_Usr), Item->usr);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldPrintedName),
Item->oldPrintedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_OldTypeName),
Item->oldTypeName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewPrintedName),
Item->newPrintedName);
out.mapRequired(getKeyContent(DiffItemKeyKind::KK_NewTypeName),

View File

@@ -0,0 +1,4 @@
Name: APINotesTest
Globals:
- Name: ANTGlobalValue
SwiftName: OldType.oldMember

View File

@@ -0,0 +1,6 @@
extern int ANTGlobalValue;
@interface NewType
@end
@interface OldType
@end

View File

@@ -0,0 +1,3 @@
module APINotesTest {
header "APINotesTest.h"
}

View File

@@ -0,0 +1,4 @@
Name: APINotesTest
Globals:
- Name: ANTGlobalValue
SwiftName: NewType.newMember

View File

@@ -0,0 +1,6 @@
extern int ANTGlobalValue;
@interface NewType
@end
@interface OldType
@end

View File

@@ -0,0 +1,3 @@
module APINotesTest {
header "APINotesTest.h"
}

View File

@@ -0,0 +1,10 @@
[
{
"DiffItemKind": "TypeMemberDiffItem",
"Usr": "c:@ANTGlobalValue",
"OldPrintedName": "oldMember",
"OldTypeName": "OldType",
"NewPrintedName": "newMember",
"NewTypeName": "NewType"
}
]

View File

@@ -0,0 +1,8 @@
// REQUIRES: OS=macosx
// 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: %api-digester -dump-sdk -module APINotesTest -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesLeft
// RUN: %api-digester -dump-sdk -module APINotesTest -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %S/Inputs/APINotesRight
// RUN: %api-digester -compare-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result -json
// RUN: diff -u %S/Outputs/apinotes-migrator-gen.json %t.result

View File

@@ -2159,9 +2159,15 @@ class TypeMemberDiffFinder : public SDKNodeVisitor {
auto diffParent = diffNode->getParent();
assert(nodeParent && diffParent && "trying to check Root?");
// Move from global variable to a member variable.
if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
diffParent->getKind() == SDKNodeKind::Root)
TypeMemberDiffs.push_back({diffNode, node});
// Move from a member variable to another member variable
if (nodeParent->getKind() == SDKNodeKind::TypeDecl &&
diffParent->getKind() == SDKNodeKind::TypeDecl)
TypeMemberDiffs.push_back({diffNode, node});
// Move from a getter/setter function to a property
else if (node->getKind() == SDKNodeKind::Getter &&
diffNode->getKind() == SDKNodeKind::Function &&
node->isNameValid()) {
@@ -2998,6 +3004,7 @@ static void findTypeMemberDiffs(NodePtr leftSDKRoot, NodePtr rightSDKRoot,
RenameDetectorForMemberDiff Detector;
for (auto pair : diffFinder.getDiffs()) {
auto left = pair.first;
auto leftParent = left->getParent();
auto right = pair.second;
auto rightParent = right->getParent();
@@ -3006,6 +3013,8 @@ static void findTypeMemberDiffs(NodePtr leftSDKRoot, NodePtr rightSDKRoot,
TypeMemberDiffItem item = {
right->getAs<SDKNodeDecl>()->getUsr(), constructFullTypeName(rightParent),
right->getPrintedName(), findSelfIndex(right), None,
leftParent->getKind() == SDKNodeKind::Root ?
StringRef() : constructFullTypeName(leftParent),
left->getPrintedName()};
out.emplace_back(item);
Detector.workOn(left, right);