File: Rename.h

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (140 lines) | stat: -rw-r--r-- 5,474 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//===--- Rename.h - Symbol-rename refactorings -------------------*- C++-*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H

#include "Protocol.h"
#include "SourceCode.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Tooling/Refactoring/Rename/SymbolName.h"
#include "llvm/Support/Error.h"
#include <optional>

namespace clang {
namespace clangd {
class ParsedAST;
class SymbolIndex;

struct RenameOptions {
  /// The maximum number of affected files (0 means no limit), only meaningful
  /// when AllowCrossFile = true.
  /// If the actual number exceeds the limit, rename is forbidden.
  size_t LimitFiles = 50;
  /// If true, format the rename edits, only meaningful in ClangdServer layer.
  bool WantFormat = false;
  /// Allow rename of virtual method hierarchies.
  /// Disable to support broken index implementations with missing relations.
  /// FIXME: fix those implementations and remove this option.
  bool RenameVirtual = true;
};

struct RenameInputs {
  /// The position triggering the rename
  Position Pos;

  /// The new name to give to the symbol or `nullopt` to perform a fake rename
  /// that checks if rename is possible.
  std::optional<llvm::StringRef> NewName;

  ParsedAST &AST;
  llvm::StringRef MainFilePath;

  // The filesystem to query when performing cross file renames.
  // If this is set, Index must also be set, likewise if this is nullptr, Index
  // must also be nullptr.
  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr;

  const SymbolIndex *Index = nullptr;

  RenameOptions Opts = {};
};

/// Compute the edits that need to be applied to rename symbols in `Ranges` from
/// `OldName` to `NewName`. The key of `Ranges` is the file path of the file in
/// which the range resides.
///
/// If `OldName` and `NewName` are single-piece identifiers, this just creates
/// edits to change the ranges to `NewName`.
///
/// If `OldName` and `NewName` are multi-piece Objective-C selectors, only the
/// start of the ranges is considered and the file is lexed to find the argument
/// labels of the selector to rename.
llvm::Expected<FileEdits>
editsForLocations(const llvm::StringMap<std::vector<Range>> &Ranges,
                  const tooling::SymbolName &OldName,
                  const tooling::SymbolName &NewName, llvm::vfs::FileSystem &FS,
                  const LangOptions &LangOpts);

struct RenameResult {
  /// The range of the symbol that the user can attempt to rename.
  Range Target;
  /// The current name of the declaration at the cursor.
  std::string OldName;
  /// Rename occurrences for the current main file.
  std::vector<Range> LocalChanges;
  /// Complete edits for the rename, including LocalChanges.
  /// If the full set of changes is unknown, this field is empty.
  FileEdits GlobalChanges;
};

/// Renames all occurrences of the symbol. The result edits are unformatted.
/// If AllowCrossFile is false, returns an error if rename a symbol that's used
/// in another file (per the index).
llvm::Expected<RenameResult> rename(const RenameInputs &RInputs);

/// Generates rename edits that replaces all given occurrences with the
/// `NewName`.
///
/// `OldName` and `Tokens` are used to to find the argument labels of
/// Objective-C selectors.
///
/// Exposed for testing only.
///
/// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges.
llvm::Expected<Edit>
buildRenameEdit(llvm::StringRef AbsFilePath, llvm::StringRef InitialCode,
                std::vector<Range> Occurrences, tooling::SymbolName OldName,
                tooling::SymbolName NewName,
                const syntax::UnexpandedTokenBuffer &Tokens);

/// Adjusts indexed occurrences to match the current state of the file.
///
/// The Index is not always up to date. Blindly editing at the locations
/// reported by the index may mangle the code in such cases.
/// This function determines whether the indexed occurrences can be applied to
/// this file, and heuristically repairs the occurrences if necessary.
///
/// The API assumes that Indexed contains only named occurrences (each
/// occurrence has the same length).
/// REQUIRED: Indexed is sorted.
std::optional<std::vector<Range>>
adjustRenameRanges(const syntax::UnexpandedTokenBuffer &Tokens,
                   llvm::StringRef Identifier, std::vector<Range> Indexed);

/// Calculates the lexed occurrences that the given indexed occurrences map to.
/// Returns std::nullopt if we don't find a mapping.
///
/// Exposed for testing only.
///
/// REQUIRED: Indexed and Lexed are sorted.
std::optional<std::vector<Range>> getMappedRanges(ArrayRef<Range> Indexed,
                                                  ArrayRef<Range> Lexed);
/// Evaluates how good the mapped result is. 0 indicates a perfect match.
///
/// Exposed for testing only.
///
/// REQUIRED: Indexed and Lexed are sorted, Indexed and MappedIndex have the
/// same size.
size_t renameRangeAdjustmentCost(ArrayRef<Range> Indexed, ArrayRef<Range> Lexed,
                                 ArrayRef<size_t> MappedIndex);

} // namespace clangd
} // namespace clang

#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H