1 //===--- Rename.h - Symbol-rename refactorings -------------------*- C++-*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H 10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H 11 12 #include "Protocol.h" 13 #include "SourceCode.h" 14 #include "support/Path.h" 15 #include "clang/Basic/LangOptions.h" 16 #include "clang/Tooling/Core/Replacement.h" 17 #include "llvm/Support/Error.h" 18 19 namespace clang { 20 namespace clangd { 21 class ParsedAST; 22 class SymbolIndex; 23 24 struct RenameOptions { 25 /// The maximum number of affected files (0 means no limit), only meaningful 26 /// when AllowCrossFile = true. 27 /// If the actual number exceeds the limit, rename is forbidden. 28 size_t LimitFiles = 50; 29 /// If true, format the rename edits, only meaningful in ClangdServer layer. 30 bool WantFormat = false; 31 }; 32 33 struct RenameInputs { 34 Position Pos; // the position triggering the rename 35 llvm::StringRef NewName; 36 37 ParsedAST &AST; 38 llvm::StringRef MainFilePath; 39 40 // The filesystem to query when performing cross file renames. 41 // If this is set, Index must also be set, likewise if this is nullptr, Index 42 // must also be nullptr. 43 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr; 44 45 const SymbolIndex *Index = nullptr; 46 47 RenameOptions Opts = {}; 48 }; 49 50 struct RenameResult { 51 // The range of the symbol that the user can attempt to rename. 52 Range Target; 53 // Rename occurrences for the current main file. 54 std::vector<Range> LocalChanges; 55 // Complete edits for the rename, including LocalChanges. 56 // If the full set of changes is unknown, this field is empty. 57 FileEdits GlobalChanges; 58 }; 59 60 /// Renames all occurrences of the symbol. The result edits are unformatted. 61 /// If AllowCrossFile is false, returns an error if rename a symbol that's used 62 /// in another file (per the index). 63 llvm::Expected<RenameResult> rename(const RenameInputs &RInputs); 64 65 /// Generates rename edits that replaces all given occurrences with the 66 /// NewName. 67 /// Exposed for testing only. 68 /// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges. 69 llvm::Expected<Edit> buildRenameEdit(llvm::StringRef AbsFilePath, 70 llvm::StringRef InitialCode, 71 std::vector<Range> Occurrences, 72 llvm::StringRef NewName); 73 74 /// Adjusts indexed occurrences to match the current state of the file. 75 /// 76 /// The Index is not always up to date. Blindly editing at the locations 77 /// reported by the index may mangle the code in such cases. 78 /// This function determines whether the indexed occurrences can be applied to 79 /// this file, and heuristically repairs the occurrences if necessary. 80 /// 81 /// The API assumes that Indexed contains only named occurrences (each 82 /// occurrence has the same length). 83 /// REQUIRED: Indexed is sorted. 84 llvm::Optional<std::vector<Range>> 85 adjustRenameRanges(llvm::StringRef DraftCode, llvm::StringRef Identifier, 86 std::vector<Range> Indexed, const LangOptions &LangOpts); 87 88 /// Calculates the lexed occurrences that the given indexed occurrences map to. 89 /// Returns None if we don't find a mapping. 90 /// 91 /// Exposed for testing only. 92 /// 93 /// REQUIRED: Indexed and Lexed are sorted. 94 llvm::Optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed, 95 ArrayRef<Range> Lexed); 96 /// Evaluates how good the mapped result is. 0 indicates a perfect match. 97 /// 98 /// Exposed for testing only. 99 /// 100 /// REQUIRED: Indexed and Lexed are sorted, Indexed and MappedIndex have the 101 /// same size. 102 size_t renameRangeAdjustmentCost(ArrayRef<Range> Indexed, ArrayRef<Range> Lexed, 103 ArrayRef<size_t> MappedIndex); 104 105 } // namespace clangd 106 } // namespace clang 107 108 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H 109