Skip to content

Commit 91ce6fb

Browse files
committed
[clangd] Abort rename when given the same name
When user wants to rename the symbol to the same name we shouldn't do any work. Bail out early and return error to save compute. Resolves: clangd/clangd#580 Reviewed By: hokein Differential Revision: https://reviews.llvm.org/D91134
1 parent 898a81d commit 91ce6fb

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

clang-tools-extra/clangd/refactor/Rename.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ enum class ReasonToReject {
123123

124124
// name validation.
125125
RenameToKeywords,
126+
SameName,
126127
};
127128

128129
llvm::Optional<ReasonToReject> renameable(const NamedDecl &RenameDecl,
@@ -213,6 +214,8 @@ llvm::Error makeError(ReasonToReject Reason) {
213214
return "there are multiple symbols at the given location";
214215
case ReasonToReject::RenameToKeywords:
215216
return "the chosen name is a keyword";
217+
case ReasonToReject::SameName:
218+
return "new name is the same as the old name";
216219
}
217220
llvm_unreachable("unhandled reason kind");
218221
};
@@ -556,6 +559,8 @@ llvm::Expected<RenameResult> rename(const RenameInputs &RInputs) {
556559
return makeError(ReasonToReject::AmbiguousSymbol);
557560
const auto &RenameDecl =
558561
llvm::cast<NamedDecl>(*(*DeclsUnderCursor.begin())->getCanonicalDecl());
562+
if (RenameDecl.getName() == RInputs.NewName)
563+
return makeError(ReasonToReject::SameName);
559564
auto Invalid = checkName(RenameDecl, RInputs.NewName);
560565
if (Invalid)
561566
return makeError(*Invalid);

clang-tools-extra/clangd/unittests/RenameTests.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,13 @@ TEST(RenameTest, Renameable) {
774774
}
775775
)cpp",
776776
nullptr, !HeaderFile, nullptr, "Conflict"},
777+
778+
{R"cpp(// Trying to rename into the same name, SameName == SameName.
779+
void func() {
780+
int S^ameName;
781+
}
782+
)cpp",
783+
"new name is the same", !HeaderFile, nullptr, "SameName"},
777784
};
778785

779786
for (const auto& Case : Cases) {
@@ -876,23 +883,23 @@ TEST(RenameTest, PrepareRename) {
876883

877884
auto Results = runPrepareRename(Server, FooCCPath, FooCC.point(),
878885
/*NewName=*/llvm::None, {/*CrossFile=*/true});
879-
// verify that for multi-file rename, we only return main-file occurrences.
886+
// Verify that for multi-file rename, we only return main-file occurrences.
880887
ASSERT_TRUE(bool(Results)) << Results.takeError();
881888
// We don't know the result is complete in prepareRename (passing a nullptr
882889
// index internally), so GlobalChanges should be empty.
883890
EXPECT_TRUE(Results->GlobalChanges.empty());
884891
EXPECT_THAT(FooCC.ranges(),
885892
testing::UnorderedElementsAreArray(Results->LocalChanges));
886893

887-
// verify name validation.
894+
// Name validation.
888895
Results =
889896
runPrepareRename(Server, FooCCPath, FooCC.point(),
890897
/*NewName=*/std::string("int"), {/*CrossFile=*/true});
891898
EXPECT_FALSE(Results);
892899
EXPECT_THAT(llvm::toString(Results.takeError()),
893900
testing::HasSubstr("keyword"));
894901

895-
// single-file rename on global symbols, we should report an error.
902+
// Single-file rename on global symbols, we should report an error.
896903
Results = runPrepareRename(Server, FooCCPath, FooCC.point(),
897904
/*NewName=*/llvm::None, {/*CrossFile=*/false});
898905
EXPECT_FALSE(Results);

0 commit comments

Comments
 (0)