2019-05-07 15:11:56 +08:00
|
|
|
//===--- 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
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2019-06-11 16:50:35 +08:00
|
|
|
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
|
|
|
|
#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
|
|
|
|
|
2019-09-03 23:34:47 +08:00
|
|
|
#include "Protocol.h"
|
2019-10-23 20:40:20 +08:00
|
|
|
#include "SourceCode.h"
|
[clangd] Move non-clang base pieces into separate support/ lib. NFCI
Summary:
This enforces layering, reduces a sprawling clangd/ directory, and makes life
easier for embedders.
Reviewers: kbobyrev
Subscribers: mgorny, ilya-biryukov, javed.absar, MaskRay, jkorous, arphaman, jfb, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D79014
2020-04-28 23:49:17 +08:00
|
|
|
#include "support/Path.h"
|
2019-12-10 00:00:51 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2019-05-07 15:11:56 +08:00
|
|
|
#include "clang/Tooling/Core/Replacement.h"
|
|
|
|
#include "llvm/Support/Error.h"
|
|
|
|
|
|
|
|
namespace clang {
|
|
|
|
namespace clangd {
|
2019-09-03 23:34:47 +08:00
|
|
|
class ParsedAST;
|
|
|
|
class SymbolIndex;
|
2019-05-07 15:11:56 +08:00
|
|
|
|
2020-02-19 22:37:36 +08:00
|
|
|
struct RenameOptions {
|
2020-04-05 14:28:11 +08:00
|
|
|
/// The maximum number of affected files (0 means no limit), only meaningful
|
2020-02-19 22:37:36 +08:00
|
|
|
/// 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;
|
|
|
|
};
|
|
|
|
|
2019-10-23 20:40:20 +08:00
|
|
|
struct RenameInputs {
|
|
|
|
Position Pos; // the position triggering the rename
|
|
|
|
llvm::StringRef NewName;
|
|
|
|
|
|
|
|
ParsedAST *
|
|
|
|
llvm::StringRef MainFilePath;
|
|
|
|
|
2021-03-10 21:41:27 +08:00
|
|
|
// 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;
|
|
|
|
|
2019-10-23 20:40:20 +08:00
|
|
|
const SymbolIndex *Index = nullptr;
|
|
|
|
|
2020-02-19 22:37:36 +08:00
|
|
|
RenameOptions Opts = {};
|
2019-10-23 20:40:20 +08:00
|
|
|
};
|
|
|
|
|
2020-10-02 22:01:25 +08:00
|
|
|
struct RenameResult {
|
|
|
|
// The range of the symbol that the user can attempt to rename.
|
|
|
|
Range Target;
|
|
|
|
// 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;
|
|
|
|
};
|
|
|
|
|
2020-02-19 22:37:36 +08:00
|
|
|
/// Renames all occurrences of the symbol. The result edits are unformatted.
|
2019-10-23 20:40:20 +08:00
|
|
|
/// If AllowCrossFile is false, returns an error if rename a symbol that's used
|
|
|
|
/// in another file (per the index).
|
2020-10-02 22:01:25 +08:00
|
|
|
llvm::Expected<RenameResult> rename(const RenameInputs &RInputs);
|
2019-05-07 15:11:56 +08:00
|
|
|
|
2019-11-19 22:23:36 +08:00
|
|
|
/// Generates rename edits that replaces all given occurrences with the
|
|
|
|
/// NewName.
|
|
|
|
/// Exposed for testing only.
|
[clangd] Deduplicate refs from index for cross-file rename.
Summary:
If the index returns duplicated refs, it will trigger the assertion in
BuildRenameEdit (we expect the processing position is always larger the
the previous one, but it is not true if we have duplication), and also
breaks our heuristics.
This patch make the code robost enough to handle duplications, also
save some cost of redundnat llvm::sort.
Though clangd's index doesn't return duplications, our internal index
kythe will.
Reviewers: ilya-biryukov
Subscribers: MaskRay, jkorous, mgrang, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71300
2019-12-11 05:15:29 +08:00
|
|
|
/// REQUIRED: Occurrences is sorted and doesn't have duplicated ranges.
|
2019-11-28 23:48:49 +08:00
|
|
|
llvm::Expected<Edit> buildRenameEdit(llvm::StringRef AbsFilePath,
|
|
|
|
llvm::StringRef InitialCode,
|
2019-11-19 22:23:36 +08:00
|
|
|
std::vector<Range> Occurrences,
|
|
|
|
llvm::StringRef NewName);
|
|
|
|
|
2019-12-10 00:00:51 +08:00
|
|
|
/// 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).
|
[clangd] Deduplicate refs from index for cross-file rename.
Summary:
If the index returns duplicated refs, it will trigger the assertion in
BuildRenameEdit (we expect the processing position is always larger the
the previous one, but it is not true if we have duplication), and also
breaks our heuristics.
This patch make the code robost enough to handle duplications, also
save some cost of redundnat llvm::sort.
Though clangd's index doesn't return duplications, our internal index
kythe will.
Reviewers: ilya-biryukov
Subscribers: MaskRay, jkorous, mgrang, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D71300
2019-12-11 05:15:29 +08:00
|
|
|
/// REQUIRED: Indexed is sorted.
|
2019-12-10 00:00:51 +08:00
|
|
|
llvm::Optional<std::vector<Range>>
|
|
|
|
adjustRenameRanges(llvm::StringRef DraftCode, llvm::StringRef Identifier,
|
|
|
|
std::vector<Range> Indexed, const LangOptions &LangOpts);
|
|
|
|
|
|
|
|
/// Calculates the lexed occurrences that the given indexed occurrences map to.
|
|
|
|
/// Returns None if we don't find a mapping.
|
|
|
|
///
|
|
|
|
/// Exposed for testing only.
|
|
|
|
///
|
|
|
|
/// REQUIRED: Indexed and Lexed are sorted.
|
|
|
|
llvm::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);
|
|
|
|
|
2019-05-07 15:11:56 +08:00
|
|
|
} // namespace clangd
|
|
|
|
} // namespace clang
|
2019-06-11 16:50:35 +08:00
|
|
|
|
|
|
|
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_REFACTOR_RENAME_H
|