mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[SourceKit/Refactoring] Macro expansion
Add refactoring "Expand Macro" that expands macro expressions. rdar://102739026
This commit is contained in:
@@ -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::
|
||||
|
||||
Reference in New Issue
Block a user