Skip to content

Commit 93e1afd

Browse files
authored
Merge pull request #18310 from akyrtzi/migrator-42480588
[migrator] Handle AppKit protocol migrations
2 parents 09c72e2 + 7d1d095 commit 93e1afd

File tree

3 files changed

+351
-1
lines changed

3 files changed

+351
-1
lines changed

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
363363

364364
std::vector<ConversionFunctionInfo> HelperFuncInfo;
365365
SourceLoc FileEndLoc;
366+
llvm::StringSet<> OverridingRemoveNames;
366367

367368
/// For a given expression, check whether the type of this expression is
368369
/// name alias type, and the name alias type is known to change to raw
@@ -385,7 +386,8 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
385386
APIDiffMigratorPass(EditorAdapter &Editor, SourceFile *SF,
386387
const MigratorOptions &Opts):
387388
ASTMigratorPass(Editor, SF, Opts), DiffStore(Diags),
388-
FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()) {}
389+
FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()),
390+
OverridingRemoveNames(funcNamesForOverrideRemoval()) {}
389391

390392
~APIDiffMigratorPass() {
391393
Editor.disableCache();
@@ -1290,6 +1292,92 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
12901292
}
12911293
}
12921294

1295+
llvm::StringSet<> funcNamesForOverrideRemoval() {
1296+
llvm::StringSet<> Results;
1297+
Results.insert("c:objc(cs)NSObject(im)application:delegateHandlesKey:");
1298+
Results.insert("c:objc(cs)NSObject(im)changeColor:");
1299+
Results.insert("c:objc(cs)NSObject(im)controlTextDidBeginEditing:");
1300+
Results.insert("c:objc(cs)NSObject(im)controlTextDidEndEditing:");
1301+
Results.insert("c:objc(cs)NSObject(im)controlTextDidChange:");
1302+
Results.insert("c:objc(cs)NSObject(im)changeFont:");
1303+
Results.insert("c:objc(cs)NSObject(im)validModesForFontPanel:");
1304+
Results.insert("c:objc(cs)NSObject(im)discardEditing");
1305+
Results.insert("c:objc(cs)NSObject(im)commitEditing");
1306+
Results.insert("c:objc(cs)NSObject(im)commitEditingWithDelegate:didCommitSelector:contextInfo:");
1307+
Results.insert("c:objc(cs)NSObject(im)commitEditingAndReturnError:");
1308+
Results.insert("c:objc(cs)NSObject(im)objectDidBeginEditing:");
1309+
Results.insert("c:objc(cs)NSObject(im)objectDidEndEditing:");
1310+
Results.insert("c:objc(cs)NSObject(im)validateMenuItem:");
1311+
Results.insert("c:objc(cs)NSObject(im)pasteboard:provideDataForType:");
1312+
Results.insert("c:objc(cs)NSObject(im)pasteboardChangedOwner:");
1313+
Results.insert("c:objc(cs)NSObject(im)validateToolbarItem:");
1314+
Results.insert("c:objc(cs)NSObject(im)layer:shouldInheritContentsScale:fromWindow:");
1315+
Results.insert("c:objc(cs)NSObject(im)view:stringForToolTip:point:userData:");
1316+
return Results;
1317+
}
1318+
1319+
SourceLoc shouldRemoveOverride(AbstractFunctionDecl *AFD) {
1320+
if (AFD->getKind() != DeclKind::Func)
1321+
return SourceLoc();
1322+
SourceLoc OverrideLoc;
1323+
1324+
// Get the location of override keyword.
1325+
if (auto *Override = AFD->getAttrs().getAttribute<OverrideAttr>()) {
1326+
if (Override->getRange().isValid()) {
1327+
OverrideLoc = Override->getLocation();
1328+
}
1329+
}
1330+
if (OverrideLoc.isInvalid())
1331+
return SourceLoc();
1332+
auto *OD = AFD->getOverriddenDecl();
1333+
llvm::SmallString<64> Buffer;
1334+
llvm::raw_svector_ostream OS(Buffer);
1335+
if (swift::ide::printDeclUSR(OD, OS))
1336+
return SourceLoc();
1337+
return OverridingRemoveNames.find(OS.str()) == OverridingRemoveNames.end() ?
1338+
SourceLoc() : OverrideLoc;
1339+
}
1340+
1341+
struct SuperRemoval: public ASTWalker {
1342+
EditorAdapter &Editor;
1343+
llvm::StringSet<> &USRs;
1344+
SuperRemoval(EditorAdapter &Editor, llvm::StringSet<> &USRs):
1345+
Editor(Editor), USRs(USRs) {}
1346+
bool isSuperExpr(Expr *E) {
1347+
if (E->isImplicit())
1348+
return false;
1349+
// Check if the expression is super.foo().
1350+
if (auto *CE = dyn_cast<CallExpr>(E)) {
1351+
if (auto *DSC = dyn_cast<DotSyntaxCallExpr>(CE->getFn())) {
1352+
if (DSC->getBase()->getKind() != ExprKind::SuperRef)
1353+
return false;
1354+
llvm::SmallString<64> Buffer;
1355+
llvm::raw_svector_ostream OS(Buffer);
1356+
auto *RD = DSC->getFn()->getReferencedDecl().getDecl();
1357+
if (swift::ide::printDeclUSR(RD, OS))
1358+
return false;
1359+
return USRs.find(OS.str()) != USRs.end();
1360+
}
1361+
}
1362+
// We should handle try super.foo() too.
1363+
if (auto *TE = dyn_cast<AnyTryExpr>(E)) {
1364+
return isSuperExpr(TE->getSubExpr());
1365+
}
1366+
return false;
1367+
}
1368+
std::pair<bool, Stmt*> walkToStmtPre(Stmt *S) override {
1369+
if (auto *BS = dyn_cast<BraceStmt>(S)) {
1370+
for(auto Ele: BS->getElements()) {
1371+
if (Ele.is<Expr*>() && isSuperExpr(Ele.get<Expr*>())) {
1372+
Editor.remove(Ele.getSourceRange());
1373+
}
1374+
}
1375+
}
1376+
// We only handle top-level expressions, so avoid visiting further.
1377+
return {false, S};
1378+
}
1379+
};
1380+
12931381
bool walkToDeclPre(Decl *D, CharSourceRange Range) override {
12941382
if (D->isImplicit())
12951383
return true;
@@ -1305,6 +1393,14 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
13051393
handleLocalParameterBridge(AFD, DiffItem);
13061394
}
13071395
}
1396+
auto OverrideLoc = shouldRemoveOverride(AFD);
1397+
if (OverrideLoc.isValid()) {
1398+
// Remove override keyword.
1399+
Editor.remove(OverrideLoc);
1400+
// Remove super-dot call.
1401+
SuperRemoval Removal(Editor, OverridingRemoveNames);
1402+
D->walk(Removal);
1403+
}
13081404
}
13091405
return true;
13101406
}

test/Migrator/remove_override.swift

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// REQUIRES: OS=macosx
2+
// RUN: %empty-directory(%t)
3+
// RUN: %target-swift-frontend -c -update-code -swift-version 4 -disable-migrator-fixits -primary-file %s -emit-migrated-file-path %t/remove_override.result.swift -o %t/rename-func-decl.swift.remap
4+
// RUN: diff -u %S/remove_override.swift.expected %t/remove_override.result.swift
5+
6+
import AppKit
7+
8+
class AppDelegate: NSObject {
9+
override class func application(_ sender: NSApplication, delegateHandlesKey key: String) -> Bool {
10+
super.application(sender, delegateHandlesKey: key)
11+
return false
12+
}
13+
override func application(_ sender: NSApplication, delegateHandlesKey key: String) -> Bool {
14+
return super.application(sender, delegateHandlesKey: key)
15+
}
16+
override class func changeColor(_ sender: Any?) {
17+
super.changeColor(sender)
18+
}
19+
override func changeColor(_ sender: Any?) {
20+
21+
}
22+
override class func controlTextDidBeginEditing(_ obj: Notification) {
23+
24+
}
25+
override func controlTextDidBeginEditing(_ obj: Notification) {
26+
27+
}
28+
override class func controlTextDidEndEditing(_ obj: Notification) {
29+
30+
}
31+
override func controlTextDidEndEditing(_ obj: Notification) {
32+
33+
}
34+
override class func controlTextDidChange(_ obj: Notification) {
35+
36+
}
37+
override func controlTextDidChange(_ obj: Notification) {
38+
39+
}
40+
override class func changeFont(_ sender: Any?) {
41+
42+
}
43+
override func changeFont(_ sender: Any?) {
44+
45+
}
46+
override class func validModesForFontPanel(_ fontPanel: NSFontPanel) -> NSFontPanel.ModeMask {
47+
return []
48+
}
49+
override func validModesForFontPanel(_ fontPanel: NSFontPanel) -> NSFontPanel.ModeMask {
50+
return []
51+
}
52+
override class func discardEditing() {
53+
54+
}
55+
override func discardEditing() {
56+
57+
}
58+
override class func commitEditing() -> Bool {
59+
return false
60+
}
61+
override func commitEditing() -> Bool {
62+
return false
63+
}
64+
override class func commitEditing(withDelegate delegate: Any?, didCommit didCommitSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
65+
66+
}
67+
override func commitEditing(withDelegate delegate: Any?, didCommit didCommitSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
68+
69+
}
70+
override class func commitEditingAndReturnError() throws {
71+
72+
}
73+
override func commitEditingAndReturnError() throws {
74+
75+
}
76+
override class func objectDidBeginEditing(_ editor: Any) {
77+
78+
}
79+
override func objectDidBeginEditing(_ editor: Any) {
80+
81+
}
82+
override class func objectDidEndEditing(_ editor: Any) {
83+
84+
}
85+
override func objectDidEndEditing(_ editor: Any) {
86+
87+
}
88+
override class func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
89+
return false
90+
}
91+
override func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
92+
return false
93+
}
94+
override class func pasteboard(_ sender: NSPasteboard, provideDataForType type: NSPasteboard.PasteboardType) {
95+
96+
}
97+
override func pasteboard(_ sender: NSPasteboard, provideDataForType type: NSPasteboard.PasteboardType) {
98+
99+
}
100+
override class func pasteboardChangedOwner(_ sender: NSPasteboard) {
101+
102+
}
103+
override func pasteboardChangedOwner(_ sender: NSPasteboard) {
104+
105+
}
106+
override class func layer(_ layer: CALayer, shouldInheritContentsScale newScale: CGFloat, from window: NSWindow) -> Bool {
107+
return false
108+
}
109+
override func layer(_ layer: CALayer, shouldInheritContentsScale newScale: CGFloat, from window: NSWindow) -> Bool {
110+
return false
111+
}
112+
override class func view(_ view: NSView, stringForToolTip tag: NSView.ToolTipTag, point: NSPoint, userData data: UnsafeMutableRawPointer?) -> String {
113+
return ""
114+
}
115+
override func view(_ view: NSView, stringForToolTip tag: NSView.ToolTipTag, point: NSPoint, userData data: UnsafeMutableRawPointer?) -> String {
116+
return ""
117+
}
118+
}
119+
120+
// We shouldn't migrate further sub-class.
121+
class MyAppDelegate: AppDelegate {
122+
override func commitEditing() -> Bool {
123+
super.commitEditing()
124+
return false
125+
}
126+
}
127+
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// REQUIRES: OS=macosx
2+
// RUN: %empty-directory(%t)
3+
// RUN: %target-swift-frontend -c -update-code -swift-version 4 -disable-migrator-fixits -primary-file %s -emit-migrated-file-path %t/remove_override.result.swift -o %t/rename-func-decl.swift.remap
4+
// RUN: diff -u %S/remove_override.swift.expected %t/remove_override.result.swift
5+
6+
import AppKit
7+
8+
class AppDelegate: NSObject {
9+
class func application(_ sender: NSApplication, delegateHandlesKey key: String) -> Bool {
10+
11+
return false
12+
}
13+
func application(_ sender: NSApplication, delegateHandlesKey key: String) -> Bool {
14+
return super.application(sender, delegateHandlesKey: key)
15+
}
16+
class func changeColor(_ sender: Any?) {
17+
18+
}
19+
func changeColor(_ sender: Any?) {
20+
21+
}
22+
class func controlTextDidBeginEditing(_ obj: Notification) {
23+
24+
}
25+
func controlTextDidBeginEditing(_ obj: Notification) {
26+
27+
}
28+
class func controlTextDidEndEditing(_ obj: Notification) {
29+
30+
}
31+
func controlTextDidEndEditing(_ obj: Notification) {
32+
33+
}
34+
class func controlTextDidChange(_ obj: Notification) {
35+
36+
}
37+
func controlTextDidChange(_ obj: Notification) {
38+
39+
}
40+
class func changeFont(_ sender: Any?) {
41+
42+
}
43+
func changeFont(_ sender: Any?) {
44+
45+
}
46+
class func validModesForFontPanel(_ fontPanel: NSFontPanel) -> NSFontPanel.ModeMask {
47+
return []
48+
}
49+
func validModesForFontPanel(_ fontPanel: NSFontPanel) -> NSFontPanel.ModeMask {
50+
return []
51+
}
52+
class func discardEditing() {
53+
54+
}
55+
func discardEditing() {
56+
57+
}
58+
class func commitEditing() -> Bool {
59+
return false
60+
}
61+
func commitEditing() -> Bool {
62+
return false
63+
}
64+
class func commitEditing(withDelegate delegate: Any?, didCommit didCommitSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
65+
66+
}
67+
func commitEditing(withDelegate delegate: Any?, didCommit didCommitSelector: Selector?, contextInfo: UnsafeMutableRawPointer?) {
68+
69+
}
70+
class func commitEditingAndReturnError() throws {
71+
72+
}
73+
func commitEditingAndReturnError() throws {
74+
75+
}
76+
class func objectDidBeginEditing(_ editor: Any) {
77+
78+
}
79+
func objectDidBeginEditing(_ editor: Any) {
80+
81+
}
82+
class func objectDidEndEditing(_ editor: Any) {
83+
84+
}
85+
func objectDidEndEditing(_ editor: Any) {
86+
87+
}
88+
class func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
89+
return false
90+
}
91+
func validateMenuItem(_ menuItem: NSMenuItem) -> Bool {
92+
return false
93+
}
94+
class func pasteboard(_ sender: NSPasteboard, provideDataForType type: NSPasteboard.PasteboardType) {
95+
96+
}
97+
func pasteboard(_ sender: NSPasteboard, provideDataForType type: NSPasteboard.PasteboardType) {
98+
99+
}
100+
class func pasteboardChangedOwner(_ sender: NSPasteboard) {
101+
102+
}
103+
func pasteboardChangedOwner(_ sender: NSPasteboard) {
104+
105+
}
106+
class func layer(_ layer: CALayer, shouldInheritContentsScale newScale: CGFloat, from window: NSWindow) -> Bool {
107+
return false
108+
}
109+
func layer(_ layer: CALayer, shouldInheritContentsScale newScale: CGFloat, from window: NSWindow) -> Bool {
110+
return false
111+
}
112+
class func view(_ view: NSView, stringForToolTip tag: NSView.ToolTipTag, point: NSPoint, userData data: UnsafeMutableRawPointer?) -> String {
113+
return ""
114+
}
115+
func view(_ view: NSView, stringForToolTip tag: NSView.ToolTipTag, point: NSPoint, userData data: UnsafeMutableRawPointer?) -> String {
116+
return ""
117+
}
118+
}
119+
120+
// We shouldn't migrate further sub-class.
121+
class MyAppDelegate: AppDelegate {
122+
override func commitEditing() -> Bool {
123+
super.commitEditing()
124+
return false
125+
}
126+
}
127+

0 commit comments

Comments
 (0)