@@ -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,26 @@ 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 ClangdServer::DiagRef &DR, const Fix &Fix) {
657+ bool IsClangTidyRename = Diag->Source == Diag::ClangTidy &&
658+ Diag->Name == " readability-identifier-naming" &&
659+ !Fix.Edits .empty ();
660+ if (IsClangTidyRename) {
661+ ClangdServer::CodeActionResult::Rename R;
662+ R.NewName = Fix.Edits .front ().newText ;
663+ R.Diag = DR;
664+ return R;
665+ }
666+
667+ return std::nullopt ;
668+ }
669+
670+ } // namespace
671+
651672void ClangdServer::codeAction (const CodeActionInputs &Params,
652673 Callback<CodeActionResult> CB) {
653674 auto Action = [Params, CB = std::move (CB),
@@ -668,16 +689,22 @@ void ClangdServer::codeAction(const CodeActionInputs &Params,
668689 CodeActionResult Result;
669690 Result.Version = InpAST->AST .version ().str ();
670691 if (KindAllowed (CodeAction::QUICKFIX_KIND)) {
671- auto FindMatchedFixes =
672- [&InpAST](const DiagRef &DR) -> llvm::ArrayRef<Fix> {
692+ auto FindMatchedDiag = [&InpAST](const DiagRef &DR) -> const Diag * {
673693 for (const auto &Diag : InpAST->AST .getDiagnostics ())
674694 if (Diag.Range == DR.Range && Diag.Message == DR.Message )
675- return Diag. Fixes ;
676- return {} ;
695+ return & Diag;
696+ return nullptr ;
677697 };
678- for (const auto &Diag : Params.Diagnostics )
679- for (const auto &Fix : FindMatchedFixes (Diag))
680- Result.QuickFixes .push_back ({Diag, Fix});
698+ for (const auto &DiagRef : Params.Diagnostics ) {
699+ if (const auto *Diag = FindMatchedDiag (DiagRef))
700+ for (const auto &Fix : Diag->Fixes ) {
701+ if (auto Rename = TryConvertToRename (Diag, DiagRef, Fix)) {
702+ Result.Renames .emplace_back (std::move (*Rename));
703+ } else {
704+ Result.QuickFixes .push_back ({DiagRef, Fix});
705+ }
706+ }
707+ }
681708 }
682709
683710 // Collect Tweaks
0 commit comments