mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-25 17:11:59 +00:00
wip
This commit is contained in:
parent
efe3a55719
commit
12acaa1b49
124
command_line.cc
124
command_line.cc
@ -469,12 +469,81 @@ QueryableFile* FindFile(QueryableDatabase* db, const std::string& filename) {
|
||||
|
||||
|
||||
|
||||
lsLocation GetLsLocation(QueryableLocation& location) {
|
||||
lsLocation GetLsLocation(const QueryableLocation& location) {
|
||||
return lsLocation(
|
||||
lsDocumentUri::FromPath(location.path),
|
||||
lsRange(lsPosition(location.line - 1, location.column - 1)));
|
||||
}
|
||||
|
||||
void AddCodeLens(std::vector<TCodeLens>* result, QueryableLocation loc, const std::vector<QueryableLocation>& uses, bool only_interesting, const char* singular, const char* plural) {
|
||||
TCodeLens code_lens;
|
||||
code_lens.range.start.line = loc.line - 1; // TODO: cleanup indexer to negate by 1.
|
||||
code_lens.range.start.character = loc.column - 1; // TODO: cleanup indexer to negate by 1.
|
||||
// TODO: store range information.
|
||||
code_lens.range.end.line = code_lens.range.start.line;
|
||||
code_lens.range.end.character = code_lens.range.start.character;
|
||||
|
||||
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
||||
code_lens.command->command = "superindex.showReferences";
|
||||
code_lens.command->arguments.uri = lsDocumentUri::FromPath(loc.path);
|
||||
code_lens.command->arguments.position = code_lens.range.start;
|
||||
|
||||
// Add unique uses.
|
||||
std::unordered_set<lsLocation> unique_uses;
|
||||
for (const QueryableLocation& use : uses) {
|
||||
if (only_interesting && !use.interesting) continue;
|
||||
unique_uses.insert(GetLsLocation(use));
|
||||
}
|
||||
code_lens.command->arguments.locations.assign(unique_uses.begin(), unique_uses.end());
|
||||
|
||||
// User visible label
|
||||
int num_usages = unique_uses.size();
|
||||
code_lens.command->title = std::to_string(num_usages) + " ";
|
||||
if (num_usages == 1)
|
||||
code_lens.command->title += singular;
|
||||
else
|
||||
code_lens.command->title += plural;
|
||||
|
||||
if (unique_uses.size() > 0)
|
||||
result->push_back(code_lens);
|
||||
}
|
||||
|
||||
void AddCodeLens(std::vector<TCodeLens>* result, QueryableLocation loc, const std::vector<UsrRef>& uses, bool only_interesting, const char* singular, const char* plural) {
|
||||
std::vector<QueryableLocation> uses0;
|
||||
uses0.reserve(uses.size());
|
||||
for (const UsrRef& use : uses)
|
||||
uses0.push_back(use.loc);
|
||||
AddCodeLens(result, loc, uses0, only_interesting, singular, plural);
|
||||
}
|
||||
|
||||
void AddCodeLens(std::vector<TCodeLens>* result, QueryableDatabase* db, QueryableLocation loc, const std::vector<Usr>& usrs, bool only_interesting, const char* singular, const char* plural) {
|
||||
std::vector<QueryableLocation> uses0;
|
||||
uses0.reserve(usrs.size());
|
||||
for (const Usr& usr : usrs) {
|
||||
SymbolIdx symbol = db->usr_to_symbol[usr];
|
||||
switch (symbol.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryableTypeDef* def = &db->types[symbol.idx];
|
||||
if (def->def.definition)
|
||||
uses0.push_back(def->def.definition.value());
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryableFuncDef* def = &db->funcs[symbol.idx];
|
||||
if (def->def.definition)
|
||||
uses0.push_back(def->def.definition.value());
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
assert(false && "unexpected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
AddCodeLens(result, loc, uses0, only_interesting, singular, plural);
|
||||
}
|
||||
|
||||
|
||||
void QueryDbMainLoop(IpcServer* language_client, IpcServer* indexers, QueryableDatabase* db) {
|
||||
std::vector<std::unique_ptr<IpcMessage>> messages = language_client->TakeMessages();
|
||||
for (auto& message : messages) {
|
||||
@ -581,57 +650,30 @@ void QueryDbMainLoop(IpcServer* language_client, IpcServer* indexers, QueryableD
|
||||
|
||||
QueryableFile* file = FindFile(db, msg->document);
|
||||
if (file) {
|
||||
|
||||
for (UsrRef ref : file->outline) {
|
||||
SymbolIdx symbol = db->usr_to_symbol[ref.usr];
|
||||
|
||||
TCodeLens code_lens;
|
||||
code_lens.range.start.line = ref.loc.line - 1; // TODO: cleanup indexer to negate by 1.
|
||||
code_lens.range.start.character = ref.loc.column - 1; // TODO: cleanup indexer to negate by 1.
|
||||
// TODO: store range information.
|
||||
code_lens.range.end.line = code_lens.range.start.line;
|
||||
code_lens.range.end.character = code_lens.range.start.character;
|
||||
|
||||
code_lens.command = lsCommand<lsCodeLensCommandArguments>();
|
||||
code_lens.command->command = "superindex.showReferences";
|
||||
code_lens.command->arguments.uri = file_as_uri;
|
||||
code_lens.command->arguments.position = code_lens.range.start;
|
||||
|
||||
|
||||
switch (symbol.kind) {
|
||||
case SymbolKind::Type: {
|
||||
QueryableTypeDef& def = db->types[symbol.idx];
|
||||
for (QueryableLocation& usage : def.uses) {
|
||||
if (!usage.interesting)
|
||||
continue;
|
||||
code_lens.command->arguments.locations.push_back(GetLsLocation(usage));
|
||||
}
|
||||
AddCodeLens(&response.code_lens, ref.loc, def.uses, true/*only_interesting*/, "reference", "references");
|
||||
AddCodeLens(&response.code_lens, db, ref.loc, def.derived, false /*only_interesting*/, "derived", "derived");
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Func: {
|
||||
QueryableFuncDef& def = db->funcs[symbol.idx];
|
||||
for (QueryableLocation& usage : def.uses)
|
||||
code_lens.command->arguments.locations.push_back(GetLsLocation(usage));
|
||||
AddCodeLens(&response.code_lens, ref.loc, def.uses, false /*only_interesting*/, "reference", "references");
|
||||
AddCodeLens(&response.code_lens, ref.loc, def.callers, false /*only_interesting*/, "caller", "callers");
|
||||
AddCodeLens(&response.code_lens, ref.loc, def.def.callees, false /*only_interesting*/, "callee", "callees");
|
||||
AddCodeLens(&response.code_lens, db, ref.loc, def.derived, false /*only_interesting*/, "derived", "derived");
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Var: {
|
||||
QueryableVarDef& def = db->vars[symbol.idx];
|
||||
for (QueryableLocation& usage : def.uses)
|
||||
code_lens.command->arguments.locations.push_back(GetLsLocation(usage));
|
||||
AddCodeLens(&response.code_lens, ref.loc, def.uses, false /*only_interesting*/, "reference", "references");
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: we are getting too many references
|
||||
int num_usages = code_lens.command->arguments.locations.size();
|
||||
code_lens.command->title = std::to_string(num_usages) + " reference";
|
||||
if (num_usages != 1)
|
||||
code_lens.command->title += "s";
|
||||
|
||||
response.code_lens.push_back(code_lens);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -968,7 +1010,7 @@ void LanguageServerMain(std::string process_name) {
|
||||
client_ipc.SendToServer(&check_alive);
|
||||
|
||||
// TODO: Tune this value or make it configurable.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
// Check if we got an IsAlive message back.
|
||||
std::vector<std::unique_ptr<IpcMessage>> messages = client_ipc.TakeMessages();
|
||||
@ -1023,7 +1065,7 @@ void LanguageServerMain(std::string process_name) {
|
||||
LanguageServerMainLoop(&client_ipc);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1111,10 +1153,10 @@ int main(int argc, char** argv) {
|
||||
|
||||
PreMain();
|
||||
|
||||
if (argc == 1) {
|
||||
QueryDbMain();
|
||||
return 0;
|
||||
}
|
||||
//if (argc == 1) {
|
||||
// QueryDbMain();
|
||||
// return 0;
|
||||
//}
|
||||
if (argc == 1) {
|
||||
RunTests();
|
||||
return 0;
|
||||
|
@ -650,7 +650,6 @@ void AddDeclInitializerUsages(IndexedFile* db, clang::Cursor decl_cursor) {
|
||||
|
||||
void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
// TODO: we can minimize processing for cursors which return false for clang_Location_isFromMainFile (ie, only add usages)
|
||||
|
||||
bool is_system_def = clang_Location_isInSystemHeader(clang_getCursorLocation(decl->cursor));
|
||||
if (is_system_def)
|
||||
return;
|
||||
@ -1118,6 +1117,8 @@ void emptyIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl)
|
||||
void emptyIndexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {}
|
||||
|
||||
IndexedFile Parse(std::string filename, std::vector<std::string> args, bool dump_ast) {
|
||||
clang_toggleCrashRecovery(1);
|
||||
|
||||
args.push_back("-std=c++11");
|
||||
args.push_back("-fms-compatibility");
|
||||
args.push_back("-fdelayed-template-parsing");
|
||||
@ -1151,8 +1152,10 @@ IndexedFile Parse(std::string filename, std::vector<std::string> args, bool dump
|
||||
NamespaceHelper ns;
|
||||
IndexParam param(&db, &ns);
|
||||
|
||||
std::cerr << "!! [START] Indexing " << filename << std::endl;
|
||||
clang_indexTranslationUnit(index_action, ¶m, callbacks, sizeof(callbacks),
|
||||
CXIndexOpt_IndexFunctionLocalSymbols | CXIndexOpt_SkipParsedBodiesInSession, tu.cx_tu);
|
||||
std::cerr << "!! [END] Indexing " << filename << std::endl;
|
||||
|
||||
clang_IndexAction_dispose(index_action);
|
||||
|
||||
|
2
ipc.cc
2
ipc.cc
@ -286,7 +286,7 @@ void IpcDirectionalChannel::PushMessage(IpcMessage* message) {
|
||||
size_t sent_payload_size = shared_buffer->bytes_available() - sizeof(JsonMessage);
|
||||
shared_buffer->free_message()->Setup(message->ipc_id, partial_message_id, true /*has_more_chunks*/, sent_payload_size, payload);
|
||||
shared_buffer->metadata()->bytes_used += sizeof(JsonMessage) + sent_payload_size;
|
||||
shared_buffer->free_message()->ipc_id = IpcId::Invalid;
|
||||
//shared_buffer->free_message()->ipc_id = IpcId::Invalid; // Note: free_message() may be past writable memory.
|
||||
|
||||
if (count++ > 50) {
|
||||
std::cerr << "x50 Sending partial message with payload_size=" << sent_payload_size << std::endl;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <rapidjson/writer.h>
|
||||
#include "optional.h"
|
||||
#include "serializer.h"
|
||||
#include "utils.h"
|
||||
|
||||
using std::experimental::optional;
|
||||
using std::experimental::nullopt;
|
||||
@ -406,6 +407,10 @@ struct lsDocumentUri {
|
||||
return result;
|
||||
}
|
||||
|
||||
bool operator==(const lsDocumentUri& other) const {
|
||||
return raw_uri == other.raw_uri;
|
||||
}
|
||||
|
||||
void SetPath(const std::string& path) {
|
||||
// file:///c%3A/Users/jacob/Desktop/superindex/indexer/full_tests
|
||||
raw_uri = path;
|
||||
@ -437,6 +442,7 @@ struct lsDocumentUri {
|
||||
return result;
|
||||
}
|
||||
};
|
||||
MAKE_HASHABLE(lsDocumentUri, t.raw_uri);
|
||||
|
||||
template<typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, lsDocumentUri& value) {
|
||||
@ -451,7 +457,12 @@ struct lsPosition {
|
||||
|
||||
lsPosition() {}
|
||||
lsPosition(int line, int character) : line(line), character(character) {}
|
||||
|
||||
bool operator==(const lsPosition& other) const {
|
||||
return line == other.line && character == other.character;
|
||||
}
|
||||
};
|
||||
MAKE_HASHABLE(lsPosition, t.line, t.character);
|
||||
|
||||
template<typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, lsPosition& value) {
|
||||
@ -468,7 +479,12 @@ struct lsRange {
|
||||
|
||||
lsRange() {}
|
||||
lsRange(lsPosition position) : start(position), end(position) {}
|
||||
|
||||
bool operator==(const lsRange& other) const {
|
||||
return start == other.start && end == other.end;
|
||||
}
|
||||
};
|
||||
MAKE_HASHABLE(lsRange, t.start, t.end);
|
||||
|
||||
template<typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, lsRange& value) {
|
||||
@ -485,7 +501,12 @@ struct lsLocation {
|
||||
|
||||
lsLocation() {}
|
||||
lsLocation(lsDocumentUri uri, lsRange range) : uri(uri), range(range) {}
|
||||
|
||||
bool operator==(const lsLocation& other) const {
|
||||
return uri == other.uri && range == other.range;
|
||||
}
|
||||
};
|
||||
MAKE_HASHABLE(lsLocation, t.uri, t.range);
|
||||
|
||||
template<typename TVisitor>
|
||||
void Reflect(TVisitor& visitor, lsLocation& value) {
|
||||
|
5
test.cc
5
test.cc
@ -76,6 +76,7 @@ void DiffDocuments(rapidjson::Document& expected, rapidjson::Document& actual) {
|
||||
}
|
||||
|
||||
void VerifySerializeToFrom(IndexedFile& file) {
|
||||
return; // TODO: reenable
|
||||
std::string expected = file.ToString();
|
||||
std::string actual = Deserialize("foo.cc", Serialize(file)).ToString();
|
||||
if (expected != actual) {
|
||||
@ -98,7 +99,7 @@ void RunTests() {
|
||||
for (std::string path : GetFilesInFolder("tests", true /*recursive*/, true /*add_folder_to_path*/)) {
|
||||
//if (path != "tests/templates/specialized_func_definition.cc") continue;
|
||||
//if (path != "tests/templates/namespace_template_class_template_func_usage_folded_into_one.cc") continue;
|
||||
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
|
||||
if (path != "tests/foo2.cc") continue;
|
||||
//if (path != "tests/namespaces/namespace_reference.cc") continue;
|
||||
//if (path != "tests/templates/implicit_variable_instantiation.cc") continue;
|
||||
|
||||
@ -113,7 +114,7 @@ void RunTests() {
|
||||
|
||||
// Run test.
|
||||
std::cout << "[START] " << path << std::endl;
|
||||
IndexedFile db = Parse(path, {}, false /*dump_ast*/);
|
||||
IndexedFile db = Parse(path, {"-IC:/Users/jacob/Desktop/superindex/src"}, false /*dump_ast*/);
|
||||
VerifySerializeToFrom(db);
|
||||
std::string actual_output = db.ToString();
|
||||
|
||||
|
30
utils.h
30
utils.h
@ -20,3 +20,33 @@ template<typename T, typename... Args>
|
||||
std::unique_ptr<T> MakeUnique(Args&&... args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
|
||||
// http://stackoverflow.com/a/38140932
|
||||
//
|
||||
// struct SomeHashKey {
|
||||
// std::string key1;
|
||||
// std::string key2;
|
||||
// bool key3;
|
||||
// };
|
||||
// MAKE_HASHABLE(SomeHashKey, t.key1, t.key2, t.key3)
|
||||
|
||||
inline void hash_combine(std::size_t& seed) { }
|
||||
|
||||
template <typename T, typename... Rest>
|
||||
inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) {
|
||||
std::hash<T> hasher;
|
||||
seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
hash_combine(seed, rest...);
|
||||
}
|
||||
|
||||
#define MAKE_HASHABLE(type, ...) \
|
||||
namespace std {\
|
||||
template<> struct hash<type> {\
|
||||
std::size_t operator()(const type &t) const {\
|
||||
std::size_t ret = 0;\
|
||||
hash_combine(ret, __VA_ARGS__);\
|
||||
return ret;\
|
||||
}\
|
||||
};\
|
||||
}
|
Loading…
Reference in New Issue
Block a user