Skip to content

Commit 8b26dd0

Browse files
authored
swift-api-digester: Various improvements for migrator script generation. (#8745)
* swift-api-digester: Add a test for generating migrator script. * swift-api-digester: Add #ifndef guard before each macro category. * swift-api-digester: Avoid printing macro categories with empty content. * swift-api-digester: Add test for multiple type changes in a single decl. * swift-api-digester: simplify some code. NFC
1 parent 6dd7b8c commit 8b26dd0

File tree

5 files changed

+164
-79
lines changed

5 files changed

+164
-79
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public struct S1 {
2+
public init(_ : Int) {}
3+
public func foo1() {}
4+
mutating public func foo2() {}
5+
public func foo3() {}
6+
public func foo4() -> Void {}
7+
public func foo5(x : Int, y: Int) {}
8+
}
9+
10+
public class C1 {
11+
public class func foo1() {}
12+
public func foo2(_ : Int, _ b: Int) -> String { return ""}
13+
public weak var CIIns1 : C1?
14+
public var CIIns2 : C1?
15+
public func foo3(a : Void?) {}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
public struct S1 {
2+
public init(_ : Double) {}
3+
mutating public func foo1() {}
4+
mutating public func foo2() {}
5+
public static func foo3() {}
6+
public func foo4() {}
7+
public func foo5(x : Int, y: Int, z: Int) {}
8+
}
9+
10+
public class C1 {
11+
public func foo1() {}
12+
public func foo2(_ : ()->(), _ b : String) -> Int { return 0 }
13+
public var CIIns1 : C1?
14+
public weak var CIIns2 : C1?
15+
public func foo3(a : ()?) {}
16+
}
+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
#ifndef SDK_CHANGE
3+
#define SDK_CHANGE(NODE_KIND, DIFF_KIND, CHILD_INDEX, LEFT_USR, RIGHT_USR, LEFT_COMMENT, RIGHT_COMMENT, MODULENAME)
4+
#endif
5+
SDK_CHANGE(Function, TypeRewritten, "0", "s:12macrogenleft2C1C4foo2SSSi_SitF", "", "String", "Int", "macrogenleft")
6+
SDK_CHANGE(Function, TypeRewritten, "1", "s:12macrogenleft2C1C4foo2SSSi_SitF", "", "Int", "() -> ()", "macrogenleft")
7+
SDK_CHANGE(Function, TypeRewritten, "2", "s:12macrogenleft2C1C4foo2SSSi_SitF", "", "Int", "String", "macrogenleft")
8+
SDK_CHANGE(Function, Rename, "0", "s:12macrogenleft2S1V4foo5ySi1x_Si1ytF", "", "foo5(x:y:)", "foo5(x:y:z:)", "macrogenleft")
9+
SDK_CHANGE(Constructor, TypeRewritten, "1", "s:12macrogenleft2S1VACSicfc", "", "Int", "Double", "macrogenleft")
10+
#undef SDK_CHANGE
11+

test/api-digester/macro-gen.swift

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: rm -rf %t.mod && mkdir -p %t.mod
2+
// RUN: rm -rf %t.sdk && mkdir -p %t.sdk
3+
// RUN: rm -rf %t.module-cache && mkdir -p %t.module-cache
4+
// RUN: %swift -emit-module -o %t.mod/macrogenleft.swiftmodule %S/Inputs/macro-gen-left.swift -parse-as-library
5+
// RUN: %swift -emit-module -o %t.mod/macrogenright.swiftmodule %S/Inputs/macro-gen-right.swift -parse-as-library
6+
// RUN: %api-digester -dump-sdk -module macrogenleft -o %t.dump1.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 3 -I %t.mod
7+
// RUN: %api-digester -dump-sdk -module macrogenright -o %t.dump2.json -module-cache-path %t.module-cache -sdk %t.sdk -swift-version 4 -I %t.mod
8+
// RUN: %api-digester -compare-sdk --input-paths %t.dump1.json -input-paths %t.dump2.json -o %t.result
9+
// RUN: diff -u %S/Outputs/macro-gen.def %t.result

tools/swift-api-digester/swift-api-digester.cpp

+112-79
Original file line numberDiff line numberDiff line change
@@ -2361,8 +2361,7 @@ class ChangeRefinementPass : public SDKTreeDiffPass, public SDKNodeVisitor {
23612361
// Similarly, the second JSON element describes a type parameter down cast in the
23622362
// second parameter of function "c:objc(cs)NSXMLDocument(im)insertChildren:atIndex:".
23632363
// We keep both usrs because in the future this may support auto-rename.
2364-
class DiffItem {
2365-
public:
2364+
struct DiffItem {
23662365
SDKNodeKind NodeKind;
23672366
NodeAnnotation DiffKind;
23682367
StringRef ChildIndex;
@@ -2381,6 +2380,10 @@ class DiffItem {
23812380
assert(!ChildIndex.empty() && "Child index is empty.");
23822381
}
23832382

2383+
static StringRef head() {
2384+
return "SDK_CHANGE";
2385+
}
2386+
23842387
bool operator<(DiffItem Other) const {
23852388
if (auto UsrCompare = LeftUsr.compare(Other.LeftUsr))
23862389
return UsrCompare < 0;
@@ -2394,16 +2397,19 @@ class DiffItem {
23942397
}
23952398

23962399
static void describe(llvm::raw_ostream &os) {
2397-
os << "// SDK_CHANGE(node kind, diff kind, child index, left USR, "
2398-
"right USR, left comment, right comment)\n";
2400+
os << "#ifndef " << head() << "\n";
2401+
os << "#define " << head() << "(NODE_KIND, DIFF_KIND, CHILD_INDEX, LEFT_USR, "
2402+
"RIGHT_USR, LEFT_COMMENT, RIGHT_COMMENT, "
2403+
"MODULENAME)\n";
2404+
os << "#endif\n";
23992405
}
24002406

24012407
static void undef(llvm::raw_ostream &os) {
2402-
os << "#undef SDK_CHANGE\n";
2408+
os << "#undef " << head() << "\n";
24032409
}
24042410

24052411
void streamDef(llvm::raw_ostream &S) const {
2406-
S << "SDK_CHANGE(" << NodeKind << ", " << DiffKind << ", \"" << ChildIndex
2412+
S << head() << "(" << NodeKind << ", " << DiffKind << ", \"" << ChildIndex
24072413
<< "\", \"" << LeftUsr << "\", \"" << RightUsr << "\", \""
24082414
<< LeftComment << "\", \"" << RightComment
24092415
<< "\", \"" << ModuleName << "\")";
@@ -2500,20 +2506,26 @@ struct TypeMemberDiffItem {
25002506
Optional<uint8_t> selfIndex;
25012507
StringRef oldPrintedName;
25022508

2509+
static StringRef head() {
2510+
return "SDK_CHANGE_TYPE_MEMBER";
2511+
}
2512+
25032513
static void describe(llvm::raw_ostream &os) {
2504-
os << "// SDK_CHANGE_TYPE_MEMBER(USR, new typename, new printed name, "
2505-
"self index, old printed name)\n";
2514+
os << "#ifndef " << head() << "\n";
2515+
os << "#define " << head() << "(USR, NEW_TYPE_NAME, NEW_PRINTED_NAME, "
2516+
"SELF_INDEX, OLD_PRINTED_NAME)\n";
2517+
os << "#endif\n";
25062518
}
25072519

25082520
static void undef(llvm::raw_ostream &os) {
2509-
os << "#undef SDK_CHANGE_TYPE_MEMBER\n";
2521+
os << "#undef " << head() << "\n";
25102522
}
25112523

25122524
void streamDef(llvm::raw_ostream &os) const {
25132525
std::string IndexContent = selfIndex.hasValue() ?
25142526
std::to_string(selfIndex.getValue()) : "";
25152527

2516-
os << "SDK_CHANGE_TYPE_MEMBER("
2528+
os << head() << "("
25172529
<< "\"" << usr << "\"" << ", "
25182530
<< "\"" << newTypeName << "\"" << ", "
25192531
<< "\"" << newPrintedName << "\"" << ", "
@@ -2583,6 +2595,8 @@ void removeRedundantAndSort(std::vector<T> &Diffs) {
25832595
template<typename T>
25842596
void serializeDiffs(llvm::raw_ostream &Fs, std::vector<T> &Diffs) {
25852597
removeRedundantAndSort(Diffs);
2598+
if (Diffs.empty())
2599+
return;
25862600
Fs << "\n";
25872601
T::describe(Fs);
25882602
for (auto &Diff : Diffs) {
@@ -2603,61 +2617,68 @@ static bool isTypeChangeInterestedFuncNode(NodePtr Decl) {
26032617
}
26042618
}
26052619

2606-
static bool isInterested(SDKNodeDecl* Decl, NodeAnnotation Anno) {
2607-
switch (Anno) {
2608-
case NodeAnnotation::WrapOptional:
2609-
case NodeAnnotation::UnwrapOptional:
2610-
case NodeAnnotation::ImplicitOptionalToOptional:
2611-
case NodeAnnotation::OptionalToImplicitOptional:
2612-
case NodeAnnotation::UnwrapUnmanaged:
2613-
case NodeAnnotation::TypeRewritten:
2614-
return isTypeChangeInterestedFuncNode(Decl) &&
2615-
Decl->getParent()->getKind() == SDKNodeKind::TypeDecl;
2616-
default:
2617-
return true;
2618-
}
2619-
}
2620-
26212620
class DiffItemEmitter : public SDKNodeVisitor {
26222621
DiffVector &AllItems;
26232622

2623+
static bool isInterested(SDKNodeDecl* Decl, NodeAnnotation Anno) {
2624+
switch (Anno) {
2625+
case NodeAnnotation::WrapOptional:
2626+
case NodeAnnotation::UnwrapOptional:
2627+
case NodeAnnotation::ImplicitOptionalToOptional:
2628+
case NodeAnnotation::OptionalToImplicitOptional:
2629+
case NodeAnnotation::UnwrapUnmanaged:
2630+
case NodeAnnotation::TypeRewritten:
2631+
return isTypeChangeInterestedFuncNode(Decl) &&
2632+
Decl->getParent()->getKind() == SDKNodeKind::TypeDecl;
2633+
default:
2634+
return true;
2635+
}
2636+
}
2637+
26242638
bool doesAncestorHaveTypeRewritten() {
26252639
return std::find_if(Ancestors.begin(), Ancestors.end(),[](NodePtr N) {
26262640
return N->isAnnotatedAs(NodeAnnotation::TypeRewritten);
26272641
}) != Ancestors.end();
26282642
}
26292643

2630-
StringRef getLeftComment(NodePtr Node, NodeAnnotation Anno) {
2631-
if (Anno == NodeAnnotation::TypeRewritten)
2632-
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenLeft);
2633-
else if (Anno == NodeAnnotation::Rename)
2634-
return Node->getAnnotateComment(NodeAnnotation::RenameOldName);
2635-
return StringRef();
2636-
}
2637-
2638-
StringRef getRightComment(NodePtr Node, NodeAnnotation Anno) {
2639-
if (Anno == NodeAnnotation::TypeRewritten)
2640-
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenRight);
2641-
else if (Anno == NodeAnnotation::ModernizeEnum)
2642-
return Node->getAnnotateComment(NodeAnnotation::ModernizeEnum);
2643-
else if (Anno == NodeAnnotation::Rename)
2644-
return Node->getAnnotateComment(NodeAnnotation::RenameNewName);
2645-
return StringRef();
2646-
}
2647-
2648-
bool handleAnnotation(NodePtr Node, SDKNodeDecl *NonTypeParent,
2649-
StringRef Index, NodeAnnotation Annotation) {
2650-
if (isInterested(NonTypeParent, Annotation) &&
2651-
Node->isAnnotatedAs(Annotation)) {
2652-
auto Kind = NonTypeParent->getKind();
2653-
StringRef LC = getLeftComment(Node, Annotation);
2654-
StringRef RC = getRightComment(Node, Annotation);
2655-
AllItems.emplace_back(Kind, Annotation, Index,
2656-
NonTypeParent->getUsr(), StringRef(), LC, RC,
2657-
NonTypeParent->getModuleName());
2658-
return true;
2644+
static StringRef getLeftComment(NodePtr Node, NodeAnnotation Anno) {
2645+
switch(Anno) {
2646+
case NodeAnnotation::TypeRewritten:
2647+
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenLeft);
2648+
case NodeAnnotation::Rename:
2649+
return Node->getAnnotateComment(NodeAnnotation::RenameOldName);
2650+
default:
2651+
return StringRef();
2652+
}
2653+
}
2654+
2655+
static StringRef getRightComment(NodePtr Node, NodeAnnotation Anno) {
2656+
switch (Anno) {
2657+
case NodeAnnotation::TypeRewritten:
2658+
return Node->getAnnotateComment(NodeAnnotation::TypeRewrittenRight);
2659+
case NodeAnnotation::ModernizeEnum:
2660+
return Node->getAnnotateComment(NodeAnnotation::ModernizeEnum);
2661+
case NodeAnnotation::Rename:
2662+
return Node->getAnnotateComment(NodeAnnotation::RenameNewName);
2663+
default:
2664+
return StringRef();
2665+
}
2666+
}
2667+
2668+
void handleAnnotations(NodePtr Node, SDKNodeDecl *NonTypeParent,
2669+
StringRef Index, ArrayRef<NodeAnnotation> Annotations) {
2670+
for (auto Annotation: Annotations) {
2671+
if (isInterested(NonTypeParent, Annotation) &&
2672+
Node->isAnnotatedAs(Annotation)) {
2673+
auto Kind = NonTypeParent->getKind();
2674+
StringRef LC = getLeftComment(Node, Annotation);
2675+
StringRef RC = getRightComment(Node, Annotation);
2676+
AllItems.emplace_back(Kind, Annotation, Index,
2677+
NonTypeParent->getUsr(), StringRef(), LC, RC,
2678+
NonTypeParent->getModuleName());
2679+
return;
2680+
}
26592681
}
2660-
return false;
26612682
}
26622683

26632684
void visit(NodePtr Node) override {
@@ -2670,22 +2691,24 @@ class DiffItemEmitter : public SDKNodeVisitor {
26702691

26712692
if (!Parent)
26722693
return;
2673-
auto Index = isa<SDKNodeType>(Node) ? getIndexString(Node) : "0";
2674-
2675-
bool Result =
2676-
doesAncestorHaveTypeRewritten() ||
2677-
handleAnnotation(Node, Parent, Index, NodeAnnotation::WrapOptional) ||
2678-
handleAnnotation(Node, Parent, Index, NodeAnnotation::UnwrapOptional) ||
2679-
handleAnnotation(Node, Parent, Index, NodeAnnotation::ImplicitOptionalToOptional) ||
2680-
handleAnnotation(Node, Parent, Index, NodeAnnotation::OptionalToImplicitOptional) ||
2681-
handleAnnotation(Node, Parent, Index, NodeAnnotation::UnwrapUnmanaged) ||
2682-
handleAnnotation(Node, Parent, Index, NodeAnnotation::TypeRewritten) ||
2683-
handleAnnotation(Node, Parent, Index, NodeAnnotation::SetterToProperty) ||
2684-
handleAnnotation(Node, Parent, Index, NodeAnnotation::GetterToProperty) ||
2685-
handleAnnotation(Node, Parent, Index, NodeAnnotation::ModernizeEnum) ||
2686-
handleAnnotation(Node, Parent, Index, NodeAnnotation::Rename) ||
2687-
handleAnnotation(Node, Parent, Index, NodeAnnotation::NowThrowing);
2688-
(void) Result;
2694+
if (doesAncestorHaveTypeRewritten())
2695+
return;
2696+
2697+
handleAnnotations(Node, Parent,
2698+
isa<SDKNodeType>(Node) ? getIndexString(Node) : "0",
2699+
{
2700+
NodeAnnotation::WrapOptional,
2701+
NodeAnnotation::UnwrapOptional,
2702+
NodeAnnotation::ImplicitOptionalToOptional,
2703+
NodeAnnotation::OptionalToImplicitOptional,
2704+
NodeAnnotation::UnwrapUnmanaged,
2705+
NodeAnnotation::TypeRewritten,
2706+
NodeAnnotation::SetterToProperty,
2707+
NodeAnnotation::GetterToProperty,
2708+
NodeAnnotation::ModernizeEnum,
2709+
NodeAnnotation::Rename,
2710+
NodeAnnotation::NowThrowing
2711+
});
26892712
}
26902713

26912714
StringRef getIndexString(NodePtr Node) {
@@ -3053,17 +3076,22 @@ struct NoEscapeFuncParam {
30533076

30543077
NoEscapeFuncParam(StringRef Usr, unsigned Index) : Usr(Usr), Index(Index) {}
30553078

3079+
static StringRef head() {
3080+
return "NOESCAPE_FUNC_PARAM";
3081+
}
3082+
30563083
static void describe(llvm::raw_ostream &os) {
3057-
os << "// NOESCAPE_FUNC_PARAM(USR, Index)\n";
3084+
os << "#ifndef " << head() << "\n";
3085+
os << "#define " << head() << "(USR, Index)\n";
3086+
os << "#endif\n";
30583087
}
30593088

30603089
static void undef(llvm::raw_ostream &os) {
3061-
os << "#undef NOESCAPE_FUNC_PARAM\n";
3090+
os << "#undef " << head() << "\n";
30623091
}
30633092

30643093
void streamDef(llvm::raw_ostream &os) const {
3065-
os << "NOESCAPE_FUNC_PARAM("
3066-
<< "\"" << Usr << "\"" << ", "
3094+
os << head() << "(" << "\"" << Usr << "\"" << ", "
30673095
<< "\"" << Index << "\"" << ")";
30683096
}
30693097

@@ -3108,17 +3136,22 @@ struct OverloadedFuncInfo {
31083136
StringRef Usr;
31093137
OverloadedFuncInfo(StringRef Usr) : Usr(Usr) {}
31103138

3139+
static StringRef head() {
3140+
return "OVERLOAD_FUNC_TRAILING_CLOSURE";
3141+
}
3142+
31113143
static void describe(llvm::raw_ostream &os) {
3112-
os << "// OVERLOAD_FUNC_TRAILING_CLOSURE(USR)\n";
3144+
os << "#ifndef " << head() << "\n";
3145+
os << "#define " << head() << "(USR)\n";
3146+
os << "#endif\n";
31133147
}
31143148

31153149
static void undef(llvm::raw_ostream &os) {
3116-
os << "#undef OVERLOAD_FUNC_TRAILING_CLOSURE\n";
3150+
os << "#undef " << head() << "\n";
31173151
}
31183152

31193153
void streamDef(llvm::raw_ostream &os) const {
3120-
os << "OVERLOAD_FUNC_TRAILING_CLOSURE("
3121-
<< "\"" << Usr << "\"" << ")";
3154+
os << head() << "(" << "\"" << Usr << "\"" << ")";
31223155
}
31233156

31243157
bool operator<(OverloadedFuncInfo Other) const {

0 commit comments

Comments
 (0)