1 //===--- Rename.h - Symbol-rename refactorings -------------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
10 #define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
13 #include "SourceCode.h"
14 #include "clang/Basic/IdentifierTable.h"
15 #include "clang/Basic/LangOptions.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/Support/Error.h"
25 struct RenameOptions
{
26 /// The maximum number of affected files (0 means no limit), only meaningful
27 /// when AllowCrossFile = true.
28 /// If the actual number exceeds the limit, rename is forbidden.
29 size_t LimitFiles
= 50;
30 /// If true, format the rename edits, only meaningful in ClangdServer layer.
31 bool WantFormat
= false;
32 /// Allow rename of virtual method hierarchies.
33 /// Disable to support broken index implementations with missing relations.
34 /// FIXME: fix those implementations and remove this option.
35 bool RenameVirtual
= true;
39 Position Pos
; // the position triggering the rename
40 llvm::StringRef NewName
;
43 llvm::StringRef MainFilePath
;
45 // The filesystem to query when performing cross file renames.
46 // If this is set, Index must also be set, likewise if this is nullptr, Index
47 // must also be nullptr.
48 llvm::IntrusiveRefCntPtr
<llvm::vfs::FileSystem
> FS
= nullptr;
50 const SymbolIndex
*Index
= nullptr;
52 RenameOptions Opts
= {};
56 // The range of the symbol that the user can attempt to rename.
58 // Placeholder text for the rename operation if non-empty.
59 std::string Placeholder
;
60 // Rename occurrences for the current main file.
61 std::vector
<Range
> LocalChanges
;
62 // Complete edits for the rename, including LocalChanges.
63 // If the full set of changes is unknown, this field is empty.
64 FileEdits GlobalChanges
;
67 /// Represents a symbol range where the symbol can potentially have multiple
70 /// Ranges for the tokens that make up the symbol's name.
71 /// Usually a single range, but there can be multiple ranges if the tokens for
72 /// the symbol are split, e.g. ObjC selectors.
73 std::vector
<Range
> Ranges
;
76 SymbolRange(std::vector
<Range
> Ranges
);
78 /// Returns the first range.
81 friend bool operator==(const SymbolRange
&LHS
, const SymbolRange
&RHS
);
82 friend bool operator!=(const SymbolRange
&LHS
, const SymbolRange
&RHS
);
83 friend bool operator<(const SymbolRange
&LHS
, const SymbolRange
&RHS
);
86 /// Renames all occurrences of the symbol. The result edits are unformatted.
87 /// If AllowCrossFile is false, returns an error if rename a symbol that's used
88 /// in another file (per the index).
89 llvm::Expected
<RenameResult
> rename(const RenameInputs
&RInputs
);
91 /// Generates rename edits that replaces all given occurrences with the
93 /// Exposed for testing only.
94 /// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges.
95 llvm::Expected
<Edit
> buildRenameEdit(llvm::StringRef AbsFilePath
,
96 llvm::StringRef InitialCode
,
97 std::vector
<SymbolRange
> Occurrences
,
98 llvm::ArrayRef
<llvm::StringRef
> NewNames
);
100 /// Adjusts indexed occurrences to match the current state of the file.
102 /// The Index is not always up to date. Blindly editing at the locations
103 /// reported by the index may mangle the code in such cases.
104 /// This function determines whether the indexed occurrences can be applied to
105 /// this file, and heuristically repairs the occurrences if necessary.
107 /// The API assumes that Indexed contains only named occurrences (each
108 /// occurrence has the same length).
109 /// REQUIRED: Indexed is sorted.
110 std::optional
<std::vector
<SymbolRange
>>
111 adjustRenameRanges(llvm::StringRef DraftCode
, llvm::StringRef Identifier
,
112 std::vector
<Range
> Indexed
, const LangOptions
&LangOpts
,
113 std::optional
<Selector
> Selector
);
115 /// Calculates the lexed occurrences that the given indexed occurrences map to.
116 /// Returns std::nullopt if we don't find a mapping.
118 /// Exposed for testing only.
120 /// REQUIRED: Indexed and Lexed are sorted.
121 std::optional
<std::vector
<SymbolRange
>>
122 getMappedRanges(ArrayRef
<Range
> Indexed
, ArrayRef
<SymbolRange
> Lexed
);
123 /// Evaluates how good the mapped result is. 0 indicates a perfect match.
125 /// Exposed for testing only.
127 /// REQUIRED: Indexed and Lexed are sorted, Indexed and MappedIndex have the
129 size_t renameRangeAdjustmentCost(ArrayRef
<Range
> Indexed
,
130 ArrayRef
<SymbolRange
> Lexed
,
131 ArrayRef
<size_t> MappedIndex
);
133 } // namespace clangd
136 #endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H