-
Notifications
You must be signed in to change notification settings - Fork 260
/
textDocument_rename.cc
71 lines (60 loc) · 2.19 KB
/
textDocument_rename.cc
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
// Copyright 2017-2018 ccls Authors
// SPDX-License-Identifier: Apache-2.0
#include "message_handler.hh"
#include "query.hh"
#include <clang/Basic/CharInfo.h>
#include <unordered_set>
using namespace clang;
namespace ccls {
namespace {
WorkspaceEdit buildWorkspaceEdit(DB *db, WorkingFiles *wfiles, SymbolRef sym,
std::string_view old_text,
const std::string &new_text) {
std::unordered_map<int, std::pair<WorkingFile *, TextDocumentEdit>> path2edit;
std::unordered_map<int, std::unordered_set<Range>> edited;
eachOccurrence(db, sym, true, [&](Use use) {
int file_id = use.file_id;
QueryFile &file = db->files[file_id];
if (!file.def || !edited[file_id].insert(use.range).second)
return;
std::optional<Location> loc = getLsLocation(db, wfiles, use);
if (!loc)
return;
auto [it, inserted] = path2edit.try_emplace(file_id);
auto &edit = it->second.second;
if (inserted) {
const std::string &path = file.def->path;
edit.textDocument.uri = DocumentUri::fromPath(path);
if ((it->second.first = wfiles->getFile(path)))
edit.textDocument.version = it->second.first->version;
}
// TODO LoadIndexedContent if wf is nullptr.
if (WorkingFile *wf = it->second.first) {
int start = getOffsetForPosition(loc->range.start, wf->buffer_content),
end = getOffsetForPosition(loc->range.end, wf->buffer_content);
if (wf->buffer_content.compare(start, end - start, old_text))
return;
}
edit.edits.push_back({loc->range, new_text});
});
WorkspaceEdit ret;
for (auto &x : path2edit)
ret.documentChanges.push_back(std::move(x.second.second));
return ret;
}
} // namespace
void MessageHandler::textDocument_rename(RenameParam ¶m, ReplyOnce &reply) {
auto [file, wf] = findOrFail(param.textDocument.uri.getPath(), reply);
if (!wf)
return;
WorkspaceEdit result;
for (SymbolRef sym : findSymbolsAtLocation(wf, file, param.position)) {
result = buildWorkspaceEdit(
db, wfiles, sym,
lexIdentifierAroundPos(param.position, wf->buffer_content),
param.newName);
break;
}
reply(result);
}
} // namespace ccls