This commit is contained in:
Jacob Dufault 2017-03-09 23:06:01 -08:00
parent afc6db80dd
commit 1508ac85d8
7 changed files with 1433 additions and 1427 deletions

View File

@ -1,4 +1,3 @@
#if false
#include <iostream>
#include <string>
#include <unordered_map>
@ -10,6 +9,7 @@
#include "ipc.h"
#include "query.h"
#include "language_server_api.h"
#include "test.h"
#include "third_party/tiny-process-library/process.hpp"
@ -21,7 +21,6 @@
#include <fcntl.h>
#endif
std::unordered_map<std::string, std::string> ParseOptions(int argc, char** argv) {
std::unordered_map<std::string, std::string> output;
@ -54,7 +53,7 @@ bool HasOption(const std::unordered_map<std::string, std::string>& options, cons
std::unique_ptr<language_server_api::InMessage> ParseMessage() {
std::unique_ptr<InMessage> ParseMessage() {
int content_length = -1;
int iteration = 0;
while (true) {
@ -93,7 +92,7 @@ std::unique_ptr<language_server_api::InMessage> ParseMessage() {
document.Parse(content.c_str(), content_length);
assert(!document.HasParseError());
return language_server_api::MessageRegistry::instance()->Parse(document);
return MessageRegistry::instance()->Parse(document);
}
@ -176,51 +175,49 @@ IpcMessageId IpcMessage_OpenProject::kId = "OpenProject";
struct IpcMessage_DocumentSymbolsRequest : public BaseIpcMessage<IpcMessage_DocumentSymbolsRequest> {
language_server_api::RequestId id;
RequestId id;
std::string document;
// BaseIpcMessage:
static IpcMessageId kId;
void Serialize(Writer& writer) override {
using namespace language_server_api;
void Serialize(Writer& visitor) override {
// TODO: dedup
auto& value = *this;
writer.StartObject();
SERIALIZE_MEMBER(id);
SERIALIZE_MEMBER(document);
writer.EndObject();
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(document);
REFLECT_MEMBER_END();
}
void Deserialize(Reader& reader) override {
using namespace language_server_api;
void Deserialize(Reader& visitor) override {
// TODO: dedup
auto& value = *this;
DESERIALIZE_MEMBER(id);
DESERIALIZE_MEMBER(document);
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(document);
REFLECT_MEMBER_END();
}
};
IpcMessageId IpcMessage_DocumentSymbolsRequest::kId = "IpcMessage_DocumentSymbolsRequest";
struct IpcMessage_DocumentSymbolsResponse : public BaseIpcMessage<IpcMessage_DocumentSymbolsResponse> {
language_server_api::RequestId id;
std::vector<language_server_api::SymbolInformation> symbols;
RequestId id;
std::vector<lsSymbolInformation> symbols;
// BaseIpcMessage:
static IpcMessageId kId;
void Serialize(Writer& writer) override {
using namespace language_server_api;
void Serialize(Writer& visitor) override {
auto& value = *this;
writer.StartObject();
SERIALIZE_MEMBER(id);
SERIALIZE_MEMBER(symbols);
writer.EndObject();
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(symbols);
REFLECT_MEMBER_END();
}
void Deserialize(Reader& reader) override {
using namespace language_server_api;
void Deserialize(Reader& visitor) override {
auto& value = *this;
DESERIALIZE_MEMBER(id);
DESERIALIZE_MEMBER(symbols);
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(symbols);
REFLECT_MEMBER_END();
}
};
IpcMessageId IpcMessage_DocumentSymbolsResponse::kId = "IpcMessage_DocumentSymbolsResponse";
@ -231,51 +228,47 @@ IpcMessageId IpcMessage_DocumentSymbolsResponse::kId = "IpcMessage_DocumentSymbo
struct IpcMessage_WorkspaceSymbolsRequest : public BaseIpcMessage<IpcMessage_WorkspaceSymbolsRequest> {
language_server_api::RequestId id;
RequestId id;
std::string query;
// BaseIpcMessage:
static IpcMessageId kId;
void Serialize(Writer& writer) override {
using namespace language_server_api;
void Serialize(Writer& visitor) override {
auto& value = *this;
writer.StartObject();
SERIALIZE_MEMBER(id);
SERIALIZE_MEMBER(query);
writer.EndObject();
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(query);
REFLECT_MEMBER_END();
}
void Deserialize(Reader& reader) override {
using namespace language_server_api;
void Deserialize(Reader& visitor) override {
auto& value = *this;
DESERIALIZE_MEMBER(id);
DESERIALIZE_MEMBER(query);
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(query);
REFLECT_MEMBER_END();
}
};
IpcMessageId IpcMessage_WorkspaceSymbolsRequest::kId = "IpcMessage_WorkspaceSymbolsRequest";
struct IpcMessage_WorkspaceSymbolsResponse : public BaseIpcMessage<IpcMessage_WorkspaceSymbolsResponse> {
language_server_api::RequestId id;
std::vector<language_server_api::SymbolInformation> symbols;
RequestId id;
std::vector<lsSymbolInformation> symbols;
// BaseIpcMessage:
static IpcMessageId kId;
void Serialize(Writer& writer) override {
using namespace language_server_api;
void Serialize(Writer& visitor) override {
auto& value = *this;
writer.StartObject();
SERIALIZE_MEMBER(id);
SERIALIZE_MEMBER(symbols);
writer.EndObject();
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(symbols);
REFLECT_MEMBER_END();
}
void Deserialize(Reader& reader) override {
using namespace language_server_api;
void Deserialize(Reader& visitor) override {
auto& value = *this;
DESERIALIZE_MEMBER(id);
DESERIALIZE_MEMBER(symbols);
REFLECT_MEMBER_START();
REFLECT_MEMBER(id);
REFLECT_MEMBER(symbols);
REFLECT_MEMBER_END();
}
};
IpcMessageId IpcMessage_WorkspaceSymbolsResponse::kId = "IpcMessage_WorkspaceSymbolsResponse";
@ -308,8 +301,6 @@ IpcMessageId IpcMessage_WorkspaceSymbolsResponse::kId = "IpcMessage_WorkspaceSym
void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
using namespace language_server_api;
std::vector<std::unique_ptr<BaseIpcMessageElided>> messages = ipc->TakeMessages();
for (auto& message : messages) {
@ -361,7 +352,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
for (UsrRef ref : file.outline) {
SymbolIdx symbol = db->usr_to_symbol[ref.usr];
SymbolInformation info;
lsSymbolInformation info;
info.location.range.start.line = ref.loc.line - 1; // TODO: cleanup indexer to negate by 1.
info.location.range.start.character = ref.loc.column - 1; // TODO: cleanup indexer to negate by 1.
// TODO: store range information.
@ -374,20 +365,20 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
{
QueryableTypeDef& def = db->types[symbol.idx];
info.name = def.def.qualified_name;
info.kind = language_server_api::SymbolKind::Class;
info.kind = lsSymbolKind::Class;
break;
}
case ::SymbolKind::Func:
case SymbolKind::Func:
{
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
info.kind = language_server_api::SymbolKind::Method;
info.kind = lsSymbolKind::Method;
Usr declaring = def.def.declaring_type.value();
info.containerName = db->types[db->usr_to_symbol[declaring].idx].def.qualified_name;
}
else {
info.kind = language_server_api::SymbolKind::Function;
info.kind = lsSymbolKind::Function;
}
break;
}
@ -395,7 +386,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
{
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = language_server_api::SymbolKind::Variable;
info.kind = lsSymbolKind::Variable;
break;
}
};
@ -430,7 +421,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
if (name.find(msg->query) != std::string::npos) {
SymbolInformation info;
lsSymbolInformation info;
info.name = name;
SymbolIdx symbol = db->symbols[i];
@ -442,7 +433,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
{
QueryableTypeDef& def = db->types[symbol.idx];
info.name = def.def.qualified_name;
info.kind = language_server_api::SymbolKind::Class;
info.kind = lsSymbolKind::Class;
if (def.def.definition.has_value()) {
info.location.range.start.line = def.def.definition->line - 1;
@ -455,12 +446,12 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
info.kind = language_server_api::SymbolKind::Method;
info.kind = lsSymbolKind::Method;
Usr declaring = def.def.declaring_type.value();
info.containerName = db->types[db->usr_to_symbol[declaring].idx].def.qualified_name;
}
else {
info.kind = language_server_api::SymbolKind::Function;
info.kind = lsSymbolKind::Function;
}
if (def.def.definition.has_value()) {
@ -473,7 +464,7 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
{
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = language_server_api::SymbolKind::Variable;
info.kind = lsSymbolKind::Variable;
if (def.def.definition.has_value()) {
info.location.range.start.line = def.def.definition->line - 1;
@ -546,8 +537,6 @@ void QueryDbMainLoop(IpcServer* ipc, QueryableDatabase* db) {
//
// |ipc| is connected to a server.
void LanguageServerStdinLoop(IpcClient* ipc) {
using namespace language_server_api;
while (true) {
std::unique_ptr<InMessage> message = ParseMessage();
@ -557,7 +546,7 @@ void LanguageServerStdinLoop(IpcClient* ipc) {
std::cerr << "[info]: Got message of type " << MethodIdToString(message->method_id) << std::endl;
switch (message->method_id) {
case MethodId::Initialize:
case lsMethodId::Initialize:
{
auto request = static_cast<In_InitializeRequest*>(message.get());
if (request->params.rootUri) {
@ -576,7 +565,7 @@ void LanguageServerStdinLoop(IpcClient* ipc) {
break;
}
case MethodId::TextDocumentDocumentSymbol:
case lsMethodId::TextDocumentDocumentSymbol:
{
// TODO: response should take id as input.
// TODO: message should not have top-level id.
@ -590,7 +579,7 @@ void LanguageServerStdinLoop(IpcClient* ipc) {
break;
}
case MethodId::WorkspaceSymbol:
case lsMethodId::WorkspaceSymbol:
{
auto request = static_cast<In_WorkspaceSymbolRequest*>(message.get());
IpcMessage_WorkspaceSymbolsRequest ipc_request;
@ -605,8 +594,6 @@ void LanguageServerStdinLoop(IpcClient* ipc) {
}
void LanguageServerMainLoop(IpcClient* ipc) {
using namespace language_server_api;
std::vector<std::unique_ptr<BaseIpcMessageElided>> messages = ipc->TakeMessages();
for (auto& message : messages) {
if (IpcMessage_Quit::kId == message->runtime_id()) {
@ -763,7 +750,12 @@ void LanguageServerMain(std::string process_name) {
int mai2525252n(int argc, char** argv) {
int main(int argc, char** argv) {
if (argc == 1) {
RunTests();
return 0;
}
// We need to write to stdout in binary mode because in Windows, writing
// \n will implicitly write \r\n. Language server API will ignore a
// \r\r\n split request.
@ -783,11 +775,11 @@ int mai2525252n(int argc, char** argv) {
IpcRegistry::instance()->Register<IpcMessage_WorkspaceSymbolsRequest>();
IpcRegistry::instance()->Register<IpcMessage_WorkspaceSymbolsResponse>();
language_server_api::MessageRegistry::instance()->Register<language_server_api::In_CancelRequest>();
language_server_api::MessageRegistry::instance()->Register<language_server_api::In_InitializeRequest>();
language_server_api::MessageRegistry::instance()->Register<language_server_api::In_InitializedNotification>();
language_server_api::MessageRegistry::instance()->Register<language_server_api::In_DocumentSymbolRequest>();
language_server_api::MessageRegistry::instance()->Register<language_server_api::In_WorkspaceSymbolRequest>();
MessageRegistry::instance()->Register<In_CancelRequest>();
MessageRegistry::instance()->Register<In_InitializeRequest>();
MessageRegistry::instance()->Register<In_InitializedNotification>();
MessageRegistry::instance()->Register<In_DocumentSymbolRequest>();
MessageRegistry::instance()->Register<In_WorkspaceSymbolRequest>();
@ -820,5 +812,3 @@ int mai2525252n(int argc, char** argv) {
return 1;
}
#endif

View File

@ -284,7 +284,7 @@ struct NamespaceHelper {
// Anonymous namespaces are not processed by indexDeclaration. If we
// encounter one insert it into map.
if (container->cursor.kind == CXCursor_Namespace) {
assert(clang::Cursor(container->cursor).get_spelling() == "");
//assert(clang::Cursor(container->cursor).get_spelling() == "");
container_usr_to_qualified_name[container_usr] = "::";
return "::" + unqualified_name;
}
@ -940,11 +940,11 @@ void indexEntityReference(CXClientData client_data, const CXIdxEntityRefInfo* re
IndexedFuncDef* called_def = db->Resolve(called_id);
// I suspect it is possible for the declaring type to be null
// when the class is invalid.
//if (called_def->def.declaring_type) {
assert(called_def->def.declaring_type.has_value());
IndexedTypeDef* type_def = db->Resolve(called_def->def.declaring_type.value());
type_def->AddUsage(our_loc);
//}
if (called_def->def.declaring_type) {
//assert(called_def->def.declaring_type.has_value());
IndexedTypeDef* type_def = db->Resolve(called_def->def.declaring_type.value());
type_def->AddUsage(our_loc);
}
}
}
break;

File diff suppressed because it is too large Load Diff

View File

@ -156,7 +156,6 @@ void ReflectMember(Reader& visitor, const char* name, T& value) {
#if false
void Serialize(Writer& writer, int value);

View File

@ -1,3 +1,5 @@
#include "test.h"
#include "indexer.h"
#include "serializer.h"
#include "utils.h"
@ -82,7 +84,7 @@ void VerifySerializeToFrom(IndexedFile& file) {
}
}
int main(int argc, char** argv) {
void RunTests() {
// TODO: Assert that we need to be on clang >= 3.9.1
/*
@ -95,7 +97,7 @@ int main(int argc, char** argv) {
for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) {
//if (path != "tests/templates/specialized_func_definition.cc") continue;
//if (path != "tests/constructors/invalid_reference.cc") continue;
if (path != "tests/outline/outline.cc") continue;
//if (path == "tests/inheritance/class_inherit_templated_parent.cc") continue;
//if (path != "tests/namespaces/namespace_reference.cc") continue;
//if (path != "tests/stl.cc") continue;
@ -111,7 +113,7 @@ int main(int argc, char** argv) {
// Run test.
std::cout << "[START] " << path << std::endl;
IndexedFile db = Parse(path, {}, false /*dump_ast*/);
IndexedFile db = Parse(path, {}, true /*dump_ast*/);
VerifySerializeToFrom(db);
std::string actual_output = db.ToString();
@ -135,7 +137,6 @@ int main(int argc, char** argv) {
}
std::cin.get();
return 0;
}
// TODO: ctor/dtor, copy ctor

3
test.h Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void RunTests();

19
tests/outline/outline.cc Normal file
View File

@ -0,0 +1,19 @@
#include <vector>
struct MergeableUpdate {
std::vector<int> to_add;
};
/*
OUTPUT:
{
"types": [{
"id": 0,
"usr": "c:@S@MergeableUpdate",
"short_name": "MergeableUpdate",
"qualified_name": "MergeableUpdate",
"definition": "1:1:8",
"uses": ["*1:1:8"]
}]
}
*/