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
25struct 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;
36};
37
38struct RenameInputs {
39 Position Pos; // the position triggering the rename
40 llvm::StringRef NewName;
41
42 ParsedAST &AST;
43 llvm::StringRef MainFilePath;
44
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;
49
50 const SymbolIndex *Index = nullptr;
51
52 RenameOptions Opts = {};
53};
54
55struct RenameResult {
56 // The range of the symbol that the user can attempt to rename.
57 Range Target;
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;
65};
66
67/// Represents a symbol range where the symbol can potentially have multiple
68/// tokens.
69struct SymbolRange {
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;
74
75 SymbolRange(Range R);
76 SymbolRange(std::vector<Range> Ranges);
77
78 /// Returns the first range.
79 Range range() const;
80
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);
84};
85
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).
89llvm::Expected<RenameResult> rename(const RenameInputs &RInputs);
90
91/// Generates rename edits that replaces all given occurrences with the
92/// NewName.
93/// Exposed for testing only.
94/// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges.
95llvm::Expected<Edit> buildRenameEdit(llvm::StringRef AbsFilePath,
96 llvm::StringRef InitialCode,
97 std::vector<SymbolRange> Occurrences,
98 llvm::ArrayRef<llvm::StringRef> NewNames);
99
100/// Adjusts indexed occurrences to match the current state of the file.
101///
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.
106///
107/// The API assumes that Indexed contains only named occurrences (each
108/// occurrence has the same length).
109/// REQUIRED: Indexed is sorted.
110std::optional<std::vector<SymbolRange>>
111adjustRenameRanges(llvm::StringRef DraftCode, llvm::StringRef Identifier,
112 std::vector<Range> Indexed, const LangOptions &LangOpts,
113 std::optional<Selector> Selector);
114
115/// Calculates the lexed occurrences that the given indexed occurrences map to.
116/// Returns std::nullopt if we don't find a mapping.
117///
118/// Exposed for testing only.
119///
120/// REQUIRED: Indexed and Lexed are sorted.
121std::optional<std::vector<SymbolRange>>
122getMappedRanges(ArrayRef<Range> Indexed, ArrayRef<SymbolRange> Lexed);
123/// Evaluates how good the mapped result is. 0 indicates a perfect match.
124///
125/// Exposed for testing only.
126///
127/// REQUIRED: Indexed and Lexed are sorted, Indexed and MappedIndex have the
128/// same size.
129size_t renameRangeAdjustmentCost(ArrayRef<Range> Indexed,
130 ArrayRef<SymbolRange> Lexed,
131 ArrayRef<size_t> MappedIndex);
132
133} // namespace clangd
134} // namespace clang
135
136#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
137

source code of clang-tools-extra/clangd/refactor/Rename.h