@@ -625,9 +625,10 @@ void ClangdServer::rename(PathRef File, Position Pos, llvm::StringRef NewName,
625625 WorkScheduler->runWithAST (" Rename" , File, std::move (Action));
626626}
627627
628+ namespace {
628629// May generate several candidate selections, due to SelectionTree ambiguity.
629630// vector of pointers because GCC doesn't like non-copyable Selection.
630- static llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>>
631+ llvm::Expected<std::vector<std::unique_ptr<Tweak::Selection>>>
631632tweakSelection (const Range &Sel, const InputsAndAST &AST,
632633 llvm::vfs::FileSystem *FS) {
633634 auto Begin = positionToOffset (AST.Inputs .Contents , Sel.start );
@@ -648,6 +649,27 @@ tweakSelection(const Range &Sel, const InputsAndAST &AST,
648649 return std::move (Result);
649650}
650651
652+ // Some fixes may perform local renaming, we want to convert those to clangd
653+ // rename commands, such that we can leverage the index for more accurate
654+ // results.
655+ std::optional<ClangdServer::CodeActionResult::Rename>
656+ tryConvertToRename (const Diag *Diag, const Fix &Fix) {
657+ bool IsClangTidyRename = Diag->Source == Diag::ClangTidy &&
658+ Diag->Name == " readability-identifier-naming" &&
659+ !Fix.Edits .empty ();
660+ if (IsClangTidyRename && Diag->InsideMainFile ) {
661+ ClangdServer::CodeActionResult::Rename R;
662+ R.NewName = Fix.Edits .front ().newText ;
663+ R.FixMessage = Fix.Message ;
664+ R.Diag = {Diag->Range , Diag->Message };
665+ return R;
666+ }
667+
668+ return std::nullopt ;
669+ }
670+
671+ } // namespace
672+
651673void ClangdServer::codeAction (const CodeActionInputs &Params,
652674 Callback<CodeActionResult> CB) {
653675 auto Action = [Params, CB = std::move (CB),
@@ -668,16 +690,22 @@ void ClangdServer::codeAction(const CodeActionInputs &Params,
668690 CodeActionResult Result;
669691 Result.Version = InpAST->AST .version ().str ();
670692 if (KindAllowed (CodeAction::QUICKFIX_KIND)) {
671- auto FindMatchedFixes =
672- [&InpAST](const DiagRef &DR) -> llvm::ArrayRef<Fix> {
693+ auto FindMatchedDiag = [&InpAST](const DiagRef &DR) -> const Diag * {
673694 for (const auto &Diag : InpAST->AST .getDiagnostics ())
674695 if (Diag.Range == DR.Range && Diag.Message == DR.Message )
675- return Diag. Fixes ;
676- return {} ;
696+ return & Diag;
697+ return nullptr ;
677698 };
678- for (const auto &Diag : Params.Diagnostics )
679- for (const auto &Fix : FindMatchedFixes (Diag))
680- Result.QuickFixes .push_back ({Diag, Fix});
699+ for (const auto &DiagRef : Params.Diagnostics ) {
700+ if (const auto *Diag = FindMatchedDiag (DiagRef))
701+ for (const auto &Fix : Diag->Fixes ) {
702+ if (auto Rename = tryConvertToRename (Diag, Fix)) {
703+ Result.Renames .emplace_back (std::move (*Rename));
704+ } else {
705+ Result.QuickFixes .push_back ({DiagRef, Fix});
706+ }
707+ }
708+ }
681709 }
682710
683711 // Collect Tweaks
0 commit comments