Skip to content

Add support for renaming objc methods, even those with multiple selector pieces #76466

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 15, 2024
7 changes: 5 additions & 2 deletions clang-tools-extra/clangd/ClangdLSPServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -844,14 +844,17 @@ void ClangdLSPServer::onWorkspaceSymbol(
}

void ClangdLSPServer::onPrepareRename(const TextDocumentPositionParams &Params,
Callback<std::optional<Range>> Reply) {
Callback<PrepareRenameResult> Reply) {
Server->prepareRename(
Params.textDocument.uri.file(), Params.position, /*NewName*/ std::nullopt,
Opts.Rename,
[Reply = std::move(Reply)](llvm::Expected<RenameResult> Result) mutable {
if (!Result)
return Reply(Result.takeError());
return Reply(std::move(Result->Target));
PrepareRenameResult PrepareResult;
PrepareResult.range = Result->Target;
PrepareResult.placeholder = Result->Placeholder;
return Reply(std::move(PrepareResult));
});
}

Expand Down
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/ClangdLSPServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class ClangdLSPServer : private ClangdServer::Callbacks,
void onWorkspaceSymbol(const WorkspaceSymbolParams &,
Callback<std::vector<SymbolInformation>>);
void onPrepareRename(const TextDocumentPositionParams &,
Callback<std::optional<Range>>);
Callback<PrepareRenameResult>);
void onRename(const RenameParams &, Callback<WorkspaceEdit>);
void onHover(const TextDocumentPositionParams &,
Callback<std::optional<Hover>>);
Expand Down
9 changes: 9 additions & 0 deletions clang-tools-extra/clangd/Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,15 @@ bool fromJSON(const llvm::json::Value &Params, RenameParams &R,
O.map("position", R.position) && O.map("newName", R.newName);
}

llvm::json::Value toJSON(const PrepareRenameResult &PRR) {
if (PRR.placeholder.empty())
return toJSON(PRR.range);
return llvm::json::Object{
{"range", toJSON(PRR.range)},
{"placeholder", PRR.placeholder},
};
}

llvm::json::Value toJSON(const DocumentHighlight &DH) {
return llvm::json::Object{
{"range", toJSON(DH.range)},
Expand Down
30 changes: 30 additions & 0 deletions clang-tools-extra/clangd/Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,14 @@ struct RenameParams {
};
bool fromJSON(const llvm::json::Value &, RenameParams &, llvm::json::Path);

struct PrepareRenameResult {
/// Range of the string to rename.
Range range;
/// Placeholder text to use in the editor if non-empty.
std::string placeholder;
};
llvm::json::Value toJSON(const PrepareRenameResult &PRR);

enum class DocumentHighlightKind { Text = 1, Read = 2, Write = 3 };

/// A document highlight is a range inside a text document which deserves
Expand Down Expand Up @@ -1969,6 +1977,28 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &, const ASTNode &);
} // namespace clang

namespace llvm {

template <> struct DenseMapInfo<clang::clangd::Range> {
using Range = clang::clangd::Range;
static inline Range getEmptyKey() {
static clang::clangd::Position Tomb{-1, -1};
static Range R{Tomb, Tomb};
return R;
}
static inline Range getTombstoneKey() {
static clang::clangd::Position Tomb{-2, -2};
static Range R{Tomb, Tomb};
return R;
}
static unsigned getHashValue(const Range &Val) {
return llvm::hash_combine(Val.start.line, Val.start.character, Val.end.line,
Val.end.character);
}
static bool isEqual(const Range &LHS, const Range &RHS) {
return std::tie(LHS.start, LHS.end) == std::tie(RHS.start, RHS.end);
}
};

template <> struct format_provider<clang::clangd::Position> {
static void format(const clang::clangd::Position &Pos, raw_ostream &OS,
StringRef Style) {
Expand Down
11 changes: 8 additions & 3 deletions clang-tools-extra/clangd/index/SymbolCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,21 @@ bool isSpelled(SourceLocation Loc, const NamedDecl &ND) {
auto Name = ND.getDeclName();
const auto NameKind = Name.getNameKind();
if (NameKind != DeclarationName::Identifier &&
NameKind != DeclarationName::CXXConstructorName)
NameKind != DeclarationName::CXXConstructorName &&
NameKind != DeclarationName::ObjCZeroArgSelector &&
NameKind != DeclarationName::ObjCOneArgSelector &&
NameKind != DeclarationName::ObjCMultiArgSelector)
return false;
const auto &AST = ND.getASTContext();
const auto &SM = AST.getSourceManager();
const auto &LO = AST.getLangOpts();
clang::Token Tok;
if (clang::Lexer::getRawToken(Loc, Tok, SM, LO))
return false;
auto StrName = Name.getAsString();
return clang::Lexer::getSpelling(Tok, SM, LO) == StrName;
auto TokSpelling = clang::Lexer::getSpelling(Tok, SM, LO);
if (const auto *MD = dyn_cast<ObjCMethodDecl>(&ND))
return TokSpelling == MD->getSelector().getNameForSlot(0);
return TokSpelling == Name.getAsString();
}
} // namespace

Expand Down
Loading