[SourceKit/Refactoring] Macro expansion

Add refactoring "Expand Macro" that expands macro expressions.

rdar://102739026
This commit is contained in:
Rintaro Ishizaki
2022-12-06 14:45:25 -08:00
parent 0b29450a3d
commit 9f137074af
6 changed files with 116 additions and 4 deletions

View File

@@ -8421,6 +8421,62 @@ bool RefactoringActionAddAsyncWrapper::performChange() {
return false;
}
static MacroExpansionExpr *
findMacroExpansionTargetExpr(const ResolvedCursorInfo &Info) {
// Handle '#' position in '#macroName(...)'.
if (auto exprInfo = dyn_cast<ResolvedExprStartCursorInfo>(&Info)) {
if (auto target =
dyn_cast_or_null<MacroExpansionExpr>(exprInfo->getTrailingExpr()))
if (target->getRewritten())
return target;
return nullptr;
}
// Handle 'macroName' position in '#macroName(...)'.
if (auto refInfo = dyn_cast<ResolvedValueRefCursorInfo>(&Info)) {
if (refInfo->isRef() && isa_and_nonnull<MacroDecl>(refInfo->getValueD())) {
ContextFinder Finder(
*Info.getSourceFile(), Info.getLoc(), [&](ASTNode N) {
auto *expr =
dyn_cast_or_null<MacroExpansionExpr>(N.dyn_cast<Expr *>());
return expr &&
(expr->getMacroNameLoc().getBaseNameLoc() == Info.getLoc());
});
Finder.resolve();
if (!Finder.getContexts().empty()) {
auto *target =
dyn_cast<MacroExpansionExpr>(Finder.getContexts()[0].get<Expr *>());
if (target->getRewritten())
return target;
}
}
return nullptr;
}
// TODO: handle MacroExpansionDecl.
return nullptr;
}
bool RefactoringActionExpandMacro::isApplicable(const ResolvedCursorInfo &Info,
DiagnosticEngine &Diag) {
return findMacroExpansionTargetExpr(Info) != nullptr;
}
bool RefactoringActionExpandMacro::performChange() {
auto target = findMacroExpansionTargetExpr(CursorInfo);
if (!target)
return true;
auto exprRange =
Lexer::getCharSourceRangeFromSourceRange(SM, target->getSourceRange());
auto rewrittenRange = Lexer::getCharSourceRangeFromSourceRange(
SM, target->getRewritten()->getSourceRange());
auto rewrittenBuffer = SM.extractText(rewrittenRange);
EditConsumer.accept(SM, exprRange, rewrittenBuffer);
return false;
}
} // end of anonymous namespace
StringRef swift::ide::