clang-tools 22.0.0git
Rename.h
Go to the documentation of this file.
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 "clang/Basic/IdentifierTable.h"
15#include "clang/Basic/LangOptions.h"
16#include "llvm/ADT/SmallVector.h"
17#include "llvm/Support/Error.h"
18#include <optional>
19
20namespace clang {
21namespace clangd {
22class ParsedAST;
23class SymbolIndex;
24
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;
36};
37
38/// A name of a symbol that should be renamed.
39///
40/// Symbol's name can be composed of multiple strings. For example, Objective-C
41/// methods can contain multiple argument labels:
42///
43/// \code
44/// - (void) myMethodNamePiece: (int)x anotherNamePieces:(int)y;
45/// ^~ string 0 ~~~~~ ^~ string 1 ~~~~~
46/// \endcode
48 llvm::SmallVector<std::string, 1> NamePieces;
49
50public:
52
53 /// Create a new \c SymbolName with the specified pieces.
54 explicit RenameSymbolName(ArrayRef<std::string> NamePieces);
55
56 explicit RenameSymbolName(const DeclarationName &Name);
57
58 ArrayRef<std::string> getNamePieces() const { return NamePieces; }
59
60 /// If this symbol consists of a single piece return it, otherwise return
61 /// `None`.
62 ///
63 /// Only symbols in Objective-C can consist of multiple pieces, so this
64 /// function always returns a value for non-Objective-C symbols.
65 std::optional<std::string> getSinglePiece() const;
66
67 /// Returns a human-readable version of this symbol name.
68 ///
69 /// If the symbol consists of multiple pieces (aka. it is an Objective-C
70 /// selector/method name), the pieces are separated by `:`, otherwise just an
71 /// identifier name.
72 std::string getAsString() const;
73
74 void print(raw_ostream &OS) const;
75
76 bool operator==(const RenameSymbolName &Other) const {
77 return NamePieces == Other.NamePieces;
78 }
79};
80
82 Position Pos; // the position triggering the rename
83 llvm::StringRef NewName;
84
86 llvm::StringRef MainFilePath;
87
88 // The filesystem to query when performing cross file renames.
89 // If this is set, Index must also be set, likewise if this is nullptr, Index
90 // must also be nullptr.
91 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr;
92
93 const SymbolIndex *Index = nullptr;
94
96};
97
99 // The range of the symbol that the user can attempt to rename.
101 // Placeholder text for the rename operation if non-empty.
102 std::string Placeholder;
103 // Rename occurrences for the current main file.
104 std::vector<Range> LocalChanges;
105 // Complete edits for the rename, including LocalChanges.
106 // If the full set of changes is unknown, this field is empty.
108};
109
110/// Represents a symbol range where the symbol can potentially have multiple
111/// tokens.
113 /// Ranges for the tokens that make up the symbol's name.
114 /// Usually a single range, but there can be multiple ranges if the tokens for
115 /// the symbol are split, e.g. ObjC selectors.
116 std::vector<Range> Ranges;
117
119 SymbolRange(std::vector<Range> Ranges);
120
121 /// Returns the first range.
122 Range range() const;
123
124 friend bool operator==(const SymbolRange &LHS, const SymbolRange &RHS);
125 friend bool operator!=(const SymbolRange &LHS, const SymbolRange &RHS);
126 friend bool operator<(const SymbolRange &LHS, const SymbolRange &RHS);
127};
128
129/// Renames all occurrences of the symbol. The result edits are unformatted.
130/// If AllowCrossFile is false, returns an error if rename a symbol that's used
131/// in another file (per the index).
132llvm::Expected<RenameResult> rename(const RenameInputs &RInputs);
133
134/// Generates rename edits that replaces all given occurrences with the
135/// NewName.
136/// Exposed for testing only.
137/// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges.
138llvm::Expected<Edit> buildRenameEdit(llvm::StringRef AbsFilePath,
139 llvm::StringRef InitialCode,
140 std::vector<SymbolRange> Occurrences,
141 llvm::ArrayRef<llvm::StringRef> NewNames);
142
143/// Adjusts indexed occurrences to match the current state of the file.
144///
145/// The Index is not always up to date. Blindly editing at the locations
146/// reported by the index may mangle the code in such cases.
147/// This function determines whether the indexed occurrences can be applied to
148/// this file, and heuristically repairs the occurrences if necessary.
149///
150/// The API assumes that Indexed contains only named occurrences (each
151/// occurrence has the same length).
152/// REQUIRED: Indexed is sorted.
153std::optional<std::vector<SymbolRange>>
154adjustRenameRanges(llvm::StringRef DraftCode, const RenameSymbolName &Name,
155 std::vector<Range> Indexed, const LangOptions &LangOpts);
156
157/// Calculates the lexed occurrences that the given indexed occurrences map to.
158/// Returns std::nullopt if we don't find a mapping.
159///
160/// Exposed for testing only.
161///
162/// REQUIRED: Indexed and Lexed are sorted.
163std::optional<std::vector<SymbolRange>>
164getMappedRanges(ArrayRef<Range> Indexed, ArrayRef<SymbolRange> Lexed);
165/// Evaluates how good the mapped result is. 0 indicates a perfect match.
166///
167/// Exposed for testing only.
168///
169/// REQUIRED: Indexed and Lexed are sorted, Indexed and MappedIndex have the
170/// same size.
171size_t renameRangeAdjustmentCost(ArrayRef<Range> Indexed,
172 ArrayRef<SymbolRange> Lexed,
173 ArrayRef<size_t> MappedIndex);
174
175} // namespace clangd
176} // namespace clang
177
178#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
Stores and provides access to parsed AST.
Definition ParsedAST.h:46
A name of a symbol that should be renamed.
Definition Rename.h:47
std::string getAsString() const
Returns a human-readable version of this symbol name.
Definition Rename.cpp:1048
ArrayRef< std::string > getNamePieces() const
Definition Rename.h:58
bool operator==(const RenameSymbolName &Other) const
Definition Rename.h:76
void print(raw_ostream &OS) const
Definition Rename.cpp:1055
std::optional< std::string > getSinglePiece() const
If this symbol consists of a single piece return it, otherwise return None.
Definition Rename.cpp:1041
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
Definition Index.h:134
FIXME: Skip testing on windows temporarily due to the different escaping code mode.
Definition AST.cpp:45
std::optional< std::vector< SymbolRange > > adjustRenameRanges(llvm::StringRef DraftCode, const RenameSymbolName &Name, std::vector< Range > Indexed, const LangOptions &LangOpts)
Adjusts indexed occurrences to match the current state of the file.
Definition Rename.cpp:1285
llvm::Expected< Edit > buildRenameEdit(llvm::StringRef AbsFilePath, llvm::StringRef InitialCode, std::vector< SymbolRange > Occurrences, llvm::ArrayRef< llvm::StringRef > NewNames)
Generates rename edits that replaces all given occurrences with the NewName.
Definition Rename.cpp:1202
llvm::Expected< RenameResult > rename(const RenameInputs &RInputs)
Renames all occurrences of the symbol.
Definition Rename.cpp:1076
llvm::StringMap< Edit > FileEdits
A mapping from absolute file path (the one used for accessing the underlying VFS) to edits.
Definition SourceCode.h:209
size_t renameRangeAdjustmentCost(ArrayRef< Range > Indexed, ArrayRef< SymbolRange > Lexed, ArrayRef< size_t > MappedIndex)
Evaluates how good the mapped result is.
Definition Rename.cpp:1364
std::optional< std::vector< SymbolRange > > getMappedRanges(ArrayRef< Range > Indexed, ArrayRef< SymbolRange > Lexed)
Calculates the lexed occurrences that the given indexed occurrences map to.
Definition Rename.cpp:1297
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
llvm::StringRef NewName
Definition Rename.h:83
const SymbolIndex * Index
Definition Rename.h:93
llvm::StringRef MainFilePath
Definition Rename.h:86
llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS
Definition Rename.h:91
size_t LimitFiles
The maximum number of affected files (0 means no limit), only meaningful when AllowCrossFile = true.
Definition Rename.h:29
bool WantFormat
If true, format the rename edits, only meaningful in ClangdServer layer.
Definition Rename.h:31
bool RenameVirtual
Allow rename of virtual method hierarchies.
Definition Rename.h:35
std::vector< Range > LocalChanges
Definition Rename.h:104
friend bool operator==(const SymbolRange &LHS, const SymbolRange &RHS)
Definition Rename.cpp:1066
friend bool operator!=(const SymbolRange &LHS, const SymbolRange &RHS)
Definition Rename.cpp:1069
std::vector< Range > Ranges
Ranges for the tokens that make up the symbol's name.
Definition Rename.h:116
friend bool operator<(const SymbolRange &LHS, const SymbolRange &RHS)
Definition Rename.cpp:1072
Range range() const
Returns the first range.
Definition Rename.cpp:1064