-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[WIP]migrator: handle function hoist API changes. rdar://31234806 #9544
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
d19ef96
09da80b
c49e965
9b24e95
6d8fb6d
6f07b12
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -259,13 +259,14 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker { | |
return DeclNameViewer(); | ||
} | ||
|
||
|
||
bool isSimpleReplacement(APIDiffItem *Item, std::string &Text) { | ||
if (auto *MD = dyn_cast<TypeMemberDiffItem>(Item)) { | ||
// We need to pull the self if self index is set. | ||
if (MD->selfIndex.hasValue()) | ||
return false; | ||
Text = (llvm::Twine(MD->newTypeName) + "." + MD->newPrintedName).str(); | ||
return true; | ||
if (MD->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement) { | ||
Text = (llvm::Twine(MD->newTypeName) + "." + MD->getNewName().base()). | ||
str(); | ||
return true; | ||
} | ||
} | ||
|
||
// Simple rename. | ||
|
@@ -319,6 +320,30 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker { | |
} | ||
}; | ||
|
||
void emitRenameLabelChanges(Expr *Arg, DeclNameViewer NewName, | ||
llvm::ArrayRef<unsigned> IgnoreArgIndex) { | ||
unsigned Idx = 0; | ||
auto Ranges = getCallArgLabelRanges(SM, Arg, | ||
LabelRangeEndAt::LabelNameOnly); | ||
for (unsigned I = 0; I < Ranges.size(); I ++) { | ||
if (std::any_of(IgnoreArgIndex.begin(), IgnoreArgIndex.end(), | ||
[I](unsigned Ig) { return Ig == I; })) | ||
continue; | ||
auto LR = Ranges[I]; | ||
if (Idx < NewName.argSize()) { | ||
auto Label = NewName.args()[Idx++]; | ||
|
||
// FIXME: We update only when args are consistently valid. | ||
if (Label != "_") { | ||
if (LR.getByteLength()) | ||
Editor.replace(LR, Label); | ||
else | ||
Editor.insert(LR.getStart(), (llvm::Twine(Label) + ":").str()); | ||
} | ||
} | ||
} | ||
} | ||
|
||
void handleFuncRename(ValueDecl *FD, Expr* FuncRefContainer, Expr *Arg) { | ||
bool IgnoreBase = false; | ||
if (auto View = getFuncRename(FD, IgnoreBase)) { | ||
|
@@ -327,17 +352,76 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker { | |
Walker.walk(FuncRefContainer); | ||
Editor.replace(Walker.Result, View.base()); | ||
} | ||
unsigned Idx = 0; | ||
for (auto LR :getCallArgLabelRanges(SM, Arg, | ||
LabelRangeEndAt::LabelNameOnly)) { | ||
if (Idx < View.argSize()) { | ||
auto Label = View.args()[Idx++]; | ||
|
||
// FIXME: We update only when args are consistently valid. | ||
if (Label != "_" && LR.getByteLength()) | ||
Editor.replace(LR, Label); | ||
} | ||
emitRenameLabelChanges(Arg, View, {}); | ||
} | ||
} | ||
|
||
bool handleTypeHoist(ValueDecl *FD, CallExpr* Call, Expr *Arg) { | ||
TypeMemberDiffItem *Item = nullptr; | ||
for (auto *I: getRelatedDiffItems(FD)) { | ||
Item = dyn_cast<TypeMemberDiffItem>(I); | ||
if (Item) | ||
break; | ||
} | ||
if (!Item) | ||
return false; | ||
if (Item->Subkind == TypeMemberDiffItemSubKind::SimpleReplacement) | ||
return false; | ||
if (*Item->selfIndex) | ||
return false; | ||
std::vector<CallArgInfo> AllArgs = | ||
getCallArgInfo(SM, Arg, LabelRangeEndAt::LabelNameOnly); | ||
if (!AllArgs.size()) | ||
return false; | ||
DeclNameViewer NewName = Item->getNewName(); | ||
llvm::SmallVector<unsigned, 2> IgnoredArgIndices; | ||
IgnoredArgIndices.push_back(*Item->selfIndex); | ||
if (auto RI = Item->removedIndex) | ||
IgnoredArgIndices.push_back(*RI); | ||
emitRenameLabelChanges(Arg, NewName, IgnoredArgIndices); | ||
auto *SelfExpr = AllArgs[0].ArgExp; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this assume SelfIndex is 0? Would an assert be worthwhile? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good catch, line 370 will return if SelfIndex is not 0. Current transformation mechanism may have limitation to handle non-zero selfindex. Fortunately, we don't see any of them in real frameworks. |
||
|
||
// Remove the global function name: "Foo(a, b..." to "a, b..." | ||
Editor.remove(CharSourceRange(SM, Call->getStartLoc(), | ||
SelfExpr->getStartLoc())); | ||
|
||
std::string MemberFuncBase; | ||
if (Item->Subkind == TypeMemberDiffItemSubKind::HoistSelfAndUseProperty) | ||
MemberFuncBase = (llvm::Twine(".") + Item->getNewName().base()).str(); | ||
else | ||
MemberFuncBase = (llvm::Twine(".") + Item->getNewName().base() + "(").str(); | ||
|
||
if (AllArgs.size() > 1) { | ||
Editor.replace(CharSourceRange(SM, Lexer::getLocForEndOfToken(SM, | ||
SelfExpr->getEndLoc()), AllArgs[1].LabelRange.getStart()), | ||
MemberFuncBase); | ||
} else { | ||
Editor.insert(Lexer::getLocForEndOfToken(SM, SelfExpr->getEndLoc()), | ||
MemberFuncBase); | ||
} | ||
|
||
switch (Item->Subkind) { | ||
case TypeMemberDiffItemSubKind::SimpleReplacement: | ||
llvm_unreachable("should be handled elsewhere"); | ||
case TypeMemberDiffItemSubKind::HoistSelfOnly: | ||
// we are done here. | ||
return true; | ||
case TypeMemberDiffItemSubKind::HoistSelfAndRemoveParam: { | ||
unsigned RI = *Item->removedIndex; | ||
CallArgInfo &ToRemove = AllArgs[RI]; | ||
if (AllArgs.size() == RI + 1) { | ||
Editor.remove(ToRemove.getEntireCharRange(SM)); | ||
} else { | ||
CallArgInfo &AfterToRemove = AllArgs[RI + 1]; | ||
Editor.remove(CharSourceRange(SM, ToRemove.LabelRange.getStart(), | ||
AfterToRemove.LabelRange.getStart())); | ||
} | ||
return true; | ||
} | ||
case TypeMemberDiffItemSubKind::HoistSelfAndUseProperty: | ||
// Remove ). | ||
Editor.remove(Arg->getEndLoc()); | ||
return true; | ||
} | ||
} | ||
|
||
|
@@ -380,8 +464,10 @@ struct APIDiffMigratorPass : public ASTMigratorPass, public SourceEntityWalker { | |
auto Args = CE->getArg(); | ||
switch (Fn->getKind()) { | ||
case ExprKind::DeclRef: { | ||
if (auto FD = Fn->getReferencedDecl().getDecl()) | ||
if (auto FD = Fn->getReferencedDecl().getDecl()) { | ||
handleFuncRename(FD, Fn, Args); | ||
handleTypeHoist(FD, CE, Args); | ||
} | ||
break; | ||
} | ||
case ExprKind::DotSyntaxCall: { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typo: Viwer