Skip to content

Commit 2e9b17a

Browse files
committed
ObjC method rename support
We now support renaming ObjC methods even with multiple selector pieces. This requires clangd to lex each file to discover the selector pieces since the index only stores the location of the initial selector token.
1 parent 1b6a094 commit 2e9b17a

File tree

9 files changed

+439
-71
lines changed

9 files changed

+439
-71
lines changed

clang-tools-extra/clangd/ClangdLSPServer.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -844,14 +844,17 @@ void ClangdLSPServer::onWorkspaceSymbol(
844844
}
845845

846846
void ClangdLSPServer::onPrepareRename(const TextDocumentPositionParams &Params,
847-
Callback<std::optional<Range>> Reply) {
847+
Callback<PrepareRenameResult> Reply) {
848848
Server->prepareRename(
849849
Params.textDocument.uri.file(), Params.position, /*NewName*/ std::nullopt,
850850
Opts.Rename,
851851
[Reply = std::move(Reply)](llvm::Expected<RenameResult> Result) mutable {
852852
if (!Result)
853853
return Reply(Result.takeError());
854-
return Reply(std::move(Result->Target));
854+
PrepareRenameResult PrepareResult;
855+
PrepareResult.range = Result->Target;
856+
PrepareResult.placeholder = Result->Placeholder;
857+
return Reply(std::move(PrepareResult));
855858
});
856859
}
857860

clang-tools-extra/clangd/ClangdLSPServer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
134134
void onWorkspaceSymbol(const WorkspaceSymbolParams &,
135135
Callback<std::vector<SymbolInformation>>);
136136
void onPrepareRename(const TextDocumentPositionParams &,
137-
Callback<std::optional<Range>>);
137+
Callback<PrepareRenameResult>);
138138
void onRename(const RenameParams &, Callback<WorkspaceEdit>);
139139
void onHover(const TextDocumentPositionParams &,
140140
Callback<std::optional<Hover>>);

clang-tools-extra/clangd/Protocol.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,15 @@ bool fromJSON(const llvm::json::Value &Params, RenameParams &R,
11871187
O.map("position", R.position) && O.map("newName", R.newName);
11881188
}
11891189

1190+
llvm::json::Value toJSON(const PrepareRenameResult &PRR) {
1191+
if (PRR.placeholder.empty())
1192+
return toJSON(PRR.range);
1193+
return llvm::json::Object{
1194+
{"range", toJSON(PRR.range)},
1195+
{"placeholder", PRR.placeholder},
1196+
};
1197+
}
1198+
11901199
llvm::json::Value toJSON(const DocumentHighlight &DH) {
11911200
return llvm::json::Object{
11921201
{"range", toJSON(DH.range)},

clang-tools-extra/clangd/Protocol.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,14 @@ struct RenameParams {
14361436
};
14371437
bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);
14381438

1439+
struct PrepareRenameResult {
1440+
/// Range of the string to rename.
1441+
Range range;
1442+
/// Placeholder text to use in the editor if non-empty.
1443+
std::string placeholder;
1444+
};
1445+
llvm::json::Value toJSON(const PrepareRenameResult &PRR);
1446+
14391447
enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 };
14401448

14411449
/// A document highlight is a range inside a text document which deserves

clang-tools-extra/clangd/index/SymbolCollector.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,19 @@ bool isSpelled(SourceLocation Loc, const NamedDecl &ND) {
176176
if (NameKind != DeclarationName::Identifier &&
177177
NameKind != DeclarationName::CXXConstructorName &&
178178
NameKind != DeclarationName::ObjCZeroArgSelector &&
179-
NameKind != DeclarationName::ObjCOneArgSelector)
179+
NameKind != DeclarationName::ObjCOneArgSelector &&
180+
NameKind != DeclarationName::ObjCMultiArgSelector)
180181
return false;
181182
const auto &AST = ND.getASTContext();
182183
const auto &SM = AST.getSourceManager();
183184
const auto &LO = AST.getLangOpts();
184185
clang::Token Tok;
185186
if (clang::Lexer::getRawToken(Loc, Tok, SM, LO))
186187
return false;
187-
auto StrName = Name.getAsString();
188+
auto TokSpelling = clang::Lexer::getSpelling(Tok, SM, LO);
188189
if (const auto *MD = dyn_cast<ObjCMethodDecl>(&ND))
189-
StrName = MD->getSelector().getNameForSlot(0).str();
190-
return clang::Lexer::getSpelling(Tok, SM, LO) == StrName;
190+
return TokSpelling == MD->getSelector().getNameForSlot(0);
191+
return TokSpelling == Name.getAsString();
191192
}
192193
} // namespace
193194

0 commit comments

Comments
 (0)