Skip to content

Commit 5696fb5

Browse files
authored
Merge pull request #18341 from akyrtzi/migrator-42480588-4.2
[migrator] Handle AppKit protocol migrations
2 parents 0190642 + e369088 commit 5696fb5

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
@@ -367,6 +367,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
367367

368368
std::vector<ConversionFunctionInfo> HelperFuncInfo;
369369
SourceLoc FileEndLoc;
370+
llvm::StringSet<> OverridingRemoveNames;
370371

371372
/// For a given expression, check whether the type of this expression is
372373
/// name alias type, and the name alias type is known to change to raw
@@ -389,7 +390,8 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
389390
APIDiffMigratorPass(EditorAdapter &Editor, SourceFile *SF,
390391
const MigratorOptions &Opts):
391392
ASTMigratorPass(Editor, SF, Opts), DiffStore(Diags),
392-
FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()) {}
393+
FileEndLoc(SM.getRangeForBuffer(BufferID).getEnd()),
394+
OverridingRemoveNames(funcNamesForOverrideRemoval()) {}
393395

394396
~APIDiffMigratorPass() {
395397
Editor.disableCache();
@@ -1299,6 +1301,92 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
12991301
}
13001302
}
13011303

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

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)