Skip to content

Commit ff26227

Browse files
authored
migrator: handle the special migration cases of NSOpenGLSetOption/NSOpenGLGetOption. rdar://32178753 (#9591)
1 parent 4674ad5 commit ff26227

File tree

9 files changed

+117
-7
lines changed

9 files changed

+117
-7
lines changed

include/swift/IDE/APIDigesterData.h

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ enum class NodeAnnotation: uint8_t{
4040

4141
NodeAnnotation parseSDKNodeAnnotation(StringRef Content);
4242

43+
enum class SpecialCaseId: uint8_t{
44+
#define SPECIAL_CASE_ID(NAME) NAME,
45+
#include "DigesterEnums.def"
46+
};
47+
48+
SpecialCaseId parseSpecialCaseId(StringRef Content);
49+
4350
enum class APIDiffItemKind: uint8_t{
4451
#define DIFF_ITEM_KIND(NAME) ADK_##NAME,
4552
#include "DigesterEnums.def"
@@ -252,10 +259,10 @@ struct TypeMemberDiffItem: public APIDiffItem {
252259
/// transformation on an entity.
253260
struct SpecialCaseDiffItem: public APIDiffItem {
254261
StringRef usr;
255-
StringRef caseId;
262+
SpecialCaseId caseId;
256263
public:
257264
SpecialCaseDiffItem(StringRef usr, StringRef caseId): usr(usr),
258-
caseId(caseId) {}
265+
caseId(parseSpecialCaseId(caseId)) {}
259266
StringRef getKey() const override { return usr; }
260267
void streamDef(llvm::raw_ostream &S) const override {};
261268
static bool classof(const APIDiffItem *D);

include/swift/IDE/DigesterEnums.def

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@
2626
#define DIFF_ITEM_KEY_KIND(NAME)
2727
#endif
2828

29+
#ifndef SPECIAL_CASE_ID
30+
#define SPECIAL_CASE_ID(NAME)
31+
#endif
32+
2933
NODE_KIND(Root)
3034
NODE_KIND(TypeDecl)
3135
NODE_KIND(TypeNominal)
@@ -123,6 +127,10 @@ DIFF_ITEM_KEY_KIND_INT(SelfIndex)
123127
DIFF_ITEM_KEY_KIND_INT(RemovedIndex)
124128
DIFF_ITEM_KEY_KIND_INT(Index)
125129

130+
SPECIAL_CASE_ID(NSOpenGLSetOption)
131+
SPECIAL_CASE_ID(NSOpenGLGetOption)
132+
133+
#undef SPECIAL_CASE_ID
126134
#undef DIFF_ITEM_KEY_KIND_INT
127135
#undef DIFF_ITEM_KEY_KIND_STRING
128136

lib/IDE/APIDigesterData.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ NodeAnnotation swift::ide::api::parseSDKNodeAnnotation(StringRef Content) {
5151
;
5252
}
5353

54+
SpecialCaseId swift::ide::api::parseSpecialCaseId(StringRef Content) {
55+
return llvm::StringSwitch<SpecialCaseId>(Content)
56+
#define SPECIAL_CASE_ID(NAME) .Case(#NAME, SpecialCaseId::NAME)
57+
#include "swift/IDE/DigesterEnums.def"
58+
;
59+
}
60+
5461
swift::ide::api::CommonDiffItem::
5562
CommonDiffItem(SDKNodeKind NodeKind, NodeAnnotation DiffKind,
5663
StringRef ChildIndex, StringRef LeftUsr, StringRef RightUsr,

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,56 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
356356
}
357357
}
358358

359+
bool handleSpecialCases(ValueDecl *FD, CallExpr* Call, Expr *Arg) {
360+
SpecialCaseDiffItem *Item = nullptr;
361+
for (auto *I: getRelatedDiffItems(FD)) {
362+
Item = dyn_cast<SpecialCaseDiffItem>(I);
363+
if (Item)
364+
break;
365+
}
366+
if (!Item)
367+
return false;
368+
std::vector<CallArgInfo> AllArgs =
369+
getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly);
370+
switch(Item->caseId) {
371+
case SpecialCaseId::NSOpenGLSetOption: {
372+
// swift 3.2:
373+
// NSOpenGLSetOption(NSOpenGLGOFormatCacheSize, 5)
374+
// swift 4:
375+
// NSOpenGLGOFormatCacheSize.globalValue = 5
376+
CallArgInfo &FirstArg = AllArgs[0];
377+
CallArgInfo &SecondArg = AllArgs[1];
378+
Editor.remove(CharSourceRange(SM, Call->getStartLoc(),
379+
FirstArg.ArgExp->getStartLoc()));
380+
Editor.replace(CharSourceRange(SM, Lexer::getLocForEndOfToken(SM,
381+
FirstArg.ArgExp->getEndLoc()), SecondArg.LabelRange.getStart()),
382+
".globalValue = ");
383+
Editor.remove(Call->getEndLoc());
384+
return true;
385+
}
386+
case SpecialCaseId::NSOpenGLGetOption: {
387+
// swift 3.2:
388+
// NSOpenGLGetOption(NSOpenGLGOFormatCacheSize, &cacheSize)
389+
// swift 4:
390+
// cacheSize = NSOpenGLGOFormatCacheSize.globalValue
391+
CallArgInfo &FirstArg = AllArgs[0];
392+
CallArgInfo &SecondArg = AllArgs[1];
393+
394+
StringRef SecondArgContent = SecondArg.getEntireCharRange(SM).str();
395+
if (SecondArgContent[0] == '&')
396+
SecondArgContent = SecondArgContent.substr(1);
397+
398+
Editor.replace(CharSourceRange(SM, Call->getStartLoc(),
399+
FirstArg.ArgExp->getStartLoc()),
400+
(llvm::Twine(SecondArgContent) + " = ").str());
401+
Editor.replace(CharSourceRange(SM, FirstArg.getEntireCharRange(SM).getEnd(),
402+
Lexer::getLocForEndOfToken(SM, Call->getEndLoc())),
403+
".globalValue");
404+
return true;
405+
}
406+
}
407+
}
408+
359409
bool handleTypeHoist(ValueDecl *FD, CallExpr* Call, Expr *Arg) {
360410
TypeMemberDiffItem *Item = nullptr;
361411
for (auto *I: getRelatedDiffItems(FD)) {
@@ -475,6 +525,7 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
475525
if (auto FD = Fn->getReferencedDecl().getDecl()) {
476526
handleFuncRename(FD, Fn, Args);
477527
handleTypeHoist(FD, CE, Args);
528+
handleSpecialCases(FD, CE, Args);
478529
}
479530
break;
480531
}

test/Migrator/API.json

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,10 +421,5 @@
421421
"NewTypeName": "example",
422422
"SelfIndex": 0,
423423
"RemovedIndex": 1
424-
},
425-
{
426-
"DiffItemKind": "SpecialCaseDiffItem",
427-
"Usr": "c:@shouldnotexistspecial",
428-
"SpecialCaseId": "rdar://1234567"
429424
}
430425
]

test/Migrator/Inputs/MyAppKit.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
public class NSOpenGLOption {}
3+
public func NSOpenGLGetOption(_ c : NSOpenGLOption, _ p :UnsafePointer<Int>) {}
4+
public func NSOpenGLSetOption(_ c : NSOpenGLOption, _ p : Int) {}

test/Migrator/SpecialCaseAPI.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[
2+
{
3+
"DiffItemKind": "SpecialCaseDiffItem",
4+
"Usr": "s:8MyAppKit17NSOpenGLSetOptionyAA0D8GLOptionC_SitF",
5+
"SpecialCaseId": "NSOpenGLSetOption"
6+
},
7+
{
8+
"DiffItemKind": "SpecialCaseDiffItem",
9+
"Usr": "s:8MyAppKit17NSOpenGLGetOptionyAA0D8GLOptionC_SPySiGtF",
10+
"SpecialCaseId": "NSOpenGLGetOption"
11+
}
12+
]

test/Migrator/api-special-cases.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// REQUIRES: objc_interop
2+
// RUN: rm -rf %t.mod && mkdir -p %t.mod
3+
// RUN: %target-swift-frontend -emit-module -o %t.mod/MyAppKit.swiftmodule %S/Inputs/MyAppKit.swift -module-name MyAppKit -parse-as-library
4+
// RUN: rm -rf %t && mkdir -p %t && %target-swift-frontend -c -update-code -primary-file %s -I %t.mod -emit-migrated-file-path %t/api-special-cases.swift.result -emit-remap-file-path %t/api-special-cases.swift.remap -o /dev/null -api-diff-data-file %S/SpecialCaseAPI.json
5+
// RUN: diff -u %S/api-special-cases.swift.expected %t/api-special-cases.swift.result
6+
7+
import MyAppKit
8+
9+
func foo(_ Opt: NSOpenGLOption) {
10+
var Value = 1
11+
NSOpenGLSetOption(Opt, 1)
12+
NSOpenGLGetOption(Opt, &Value)
13+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// REQUIRES: objc_interop
2+
// RUN: rm -rf %t.mod && mkdir -p %t.mod
3+
// RUN: %target-swift-frontend -emit-module -o %t.mod/MyAppKit.swiftmodule %S/Inputs/MyAppKit.swift -module-name MyAppKit -parse-as-library
4+
// RUN: rm -rf %t && mkdir -p %t && %target-swift-frontend -c -update-code -primary-file %s -I %t.mod -emit-migrated-file-path %t/api-special-cases.swift.result -emit-remap-file-path %t/api-special-cases.swift.remap -o /dev/null -api-diff-data-file %S/SpecialCaseAPI.json
5+
// RUN: diff -u %S/api-special-cases.swift.expected %t/api-special-cases.swift.result
6+
7+
import MyAppKit
8+
9+
func foo(_ Opt: NSOpenGLOption) {
10+
var Value = 1
11+
Opt.globalValue = 1
12+
Value = Opt.globalValue
13+
}

0 commit comments

Comments
 (0)