Skip to content

Commit 4eac669

Browse files
authored
Merge pull request #17267 from nkcsgexi/mig-revert-raw-repr
migrator: handle the reversion of raw representable changes. rdar://39498127
2 parents a7c9bd0 + 90303d1 commit 4eac669

File tree

5 files changed

+113
-0
lines changed

5 files changed

+113
-0
lines changed

lib/Migrator/APIDiffMigratorPass.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,8 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
275275

276276
std::vector<APIDiffItem*> getRelatedDiffItems(ValueDecl *VD) {
277277
std::vector<APIDiffItem*> results;
278+
if (!VD)
279+
return results;
278280
auto addDiffItems = [&](ValueDecl *VD) {
279281
llvm::SmallString<64> Buffer;
280282
llvm::raw_svector_ostream OS(Buffer);
@@ -921,9 +923,66 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker {
921923
insertHelperFunction(Kind, RawType, NewAttributeType, FromString, WrapTarget);
922924
}
923925

926+
bool hasRevertRawRepresentableChange(ValueDecl *VD) {
927+
for (auto Item: getRelatedDiffItems(VD)) {
928+
if (auto *CI = dyn_cast<CommonDiffItem>(Item)) {
929+
if (CI->DiffKind ==
930+
NodeAnnotation::RevertTypeAliasDeclToRawRepresentable)
931+
return true;
932+
}
933+
}
934+
return false;
935+
}
936+
937+
bool handleRevertRawRepresentable(Expr *E) {
938+
// Change attribute.rawValue to attribute
939+
if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
940+
auto Found = false;
941+
if (auto *Base = MRE->getBase()) {
942+
if (hasRevertRawRepresentableChange(Base->getType()->getAnyNominal())) {
943+
Found = true;
944+
}
945+
}
946+
if (!Found)
947+
return false;
948+
auto NL = MRE->getNameLoc().getStartLoc();
949+
auto DL = MRE->getDotLoc();
950+
if (NL.isInvalid() || DL.isInvalid())
951+
return false;
952+
CharSourceRange Range = Lexer::getCharSourceRangeFromSourceRange(SM, {DL, NL});
953+
if (Range.str() == ".rawValue") {
954+
Editor.remove(Range);
955+
return true;
956+
}
957+
}
958+
959+
// Change attribute(rawValue: "value") to "value"
960+
if (auto *CE = dyn_cast<CallExpr>(E)) {
961+
auto Found = false;
962+
if (auto *CRC = dyn_cast<ConstructorRefCallExpr>(CE->getFn())) {
963+
if (auto *TE = dyn_cast<TypeExpr>(CRC->getBase())) {
964+
if (hasRevertRawRepresentableChange(TE->getInstanceType()->getAnyNominal()))
965+
Found = true;
966+
}
967+
}
968+
if (!Found)
969+
return false;
970+
std::vector<CallArgInfo> AllArgs =
971+
getCallArgInfo(SM, CE->getArg(), LabelRangeEndAt::LabelNameOnly);
972+
if (AllArgs.size() == 1 && AllArgs.front().LabelRange.str() == "rawValue") {
973+
Editor.replace(CE->getSourceRange(), Lexer::getCharSourceRangeFromSourceRange(SM,
974+
AllArgs.front().ArgExp->getSourceRange()).str());
975+
return true;
976+
}
977+
}
978+
return false;
979+
}
980+
924981
bool walkToExprPre(Expr *E) override {
925982
if (E->getSourceRange().isInvalid())
926983
return false;
984+
if (handleRevertRawRepresentable(E))
985+
return false;
927986
if (handleQualifiedReplacement(E))
928987
return false;
929988
if (handleAssignDestMigration(E))

test/Migrator/Inputs/Cities.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,17 @@ public enum FontWeight: Int {
7474
case Regular
7575
case Bold
7676
}
77+
78+
public struct AwesomeCityAttribute: RawRepresentable {
79+
public init?(rawValue: String) { self.rawValue = rawValue }
80+
public var rawValue: String
81+
public typealias RawValue = String
82+
}
83+
84+
public class Wrapper {
85+
public struct Attribute: RawRepresentable {
86+
public init?(rawValue: String) { self.rawValue = rawValue }
87+
public var rawValue: String
88+
public typealias RawValue = String
89+
}
90+
}

test/Migrator/Inputs/string-representable.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,4 +227,26 @@
227227
"RightComment": "AwesomeIntWrapper",
228228
"ModuleName": "bar"
229229
},
230+
{
231+
"DiffItemKind": "CommonDiffItem",
232+
"NodeKind": "TypeDecl",
233+
"NodeAnnotation": "RevertTypeAliasDeclToRawRepresentable",
234+
"ChildIndex": "0",
235+
"LeftUsr": "s:6Cities20AwesomeCityAttributeV",
236+
"LeftComment": "String",
237+
"RightUsr": "",
238+
"RightComment": "String",
239+
"ModuleName": "Cities"
240+
},
241+
{
242+
"DiffItemKind": "CommonDiffItem",
243+
"NodeKind": "TypeDecl",
244+
"NodeAnnotation": "RevertTypeAliasDeclToRawRepresentable",
245+
"ChildIndex": "0",
246+
"LeftUsr": "s:6Cities7WrapperC9AttributeV",
247+
"LeftComment": "String",
248+
"RightUsr": "",
249+
"RightComment": "String",
250+
"ModuleName": "Cities"
251+
},
230252
]

test/Migrator/string-representable.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,12 @@ func foo(_ c: Container) -> String {
4545
}
4646

4747
class C: BarForwardDeclaredClass {}
48+
49+
func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
50+
_ = AwesomeCityAttribute(rawValue: "somevalue")
51+
_ = AwesomeCityAttribute.init(rawValue: "somevalue")
52+
_ = a.rawValue
53+
_ = Wrapper.Attribute(rawValue: "somevalue")
54+
_ = Wrapper.Attribute.init(rawValue: "somevalue")
55+
_ = b.rawValue
56+
}

test/Migrator/string-representable.swift.expected

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,15 @@ func foo(_ c: Container) -> String {
4646

4747
class C: BarForwardDeclaredClass {}
4848

49+
func revert(_ a: AwesomeCityAttribute, b: Wrapper.Attribute) {
50+
_ = "somevalue"
51+
_ = "somevalue"
52+
_ = a
53+
_ = "somevalue"
54+
_ = "somevalue"
55+
_ = b
56+
}
57+
4958
// Helper function inserted by Swift 4.2 migrator.
5059
fileprivate func convertToNewAttribute(_ input: String) -> NewAttribute {
5160
return NewAttribute(rawValue: input)

0 commit comments

Comments
 (0)