Browse Source

fixes

pull/2/head
Jacob Dufault 8 years ago
parent
commit
1508ac85d8
  1. 162
      command_line.cc
  2. 12
      indexer.cpp
  3. 1834
      language_server_api.h
  4. 1
      serializer.h
  5. 9
      test.cc
  6. 3
      test.h
  7. 19
      tests/outline/outline.cc

162
command_line.cc

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

12
indexer.cpp

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

1834
language_server_api.h

File diff suppressed because it is too large

1
serializer.h

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

9
test.cc

@ -1,3 +1,5 @@
#include "test.h"
#include "indexer.h" #include "indexer.h"
#include "serializer.h" #include "serializer.h"
#include "utils.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 // 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*/)) { for (std::string path : GetFilesInFolder("tests", true /*add_folder_to_path*/)) {
//if (path != "tests/templates/specialized_func_definition.cc") continue; //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/inheritance/class_inherit_templated_parent.cc") continue;
//if (path != "tests/namespaces/namespace_reference.cc") continue; //if (path != "tests/namespaces/namespace_reference.cc") continue;
//if (path != "tests/stl.cc") continue; //if (path != "tests/stl.cc") continue;
@ -111,7 +113,7 @@ int main(int argc, char** argv) {
// Run test. // Run test.
std::cout << "[START] " << path << std::endl; std::cout << "[START] " << path << std::endl;
IndexedFile db = Parse(path, {}, false /*dump_ast*/); IndexedFile db = Parse(path, {}, true /*dump_ast*/);
VerifySerializeToFrom(db); VerifySerializeToFrom(db);
std::string actual_output = db.ToString(); std::string actual_output = db.ToString();
@ -135,7 +137,6 @@ int main(int argc, char** argv) {
} }
std::cin.get(); std::cin.get();
return 0;
} }
// TODO: ctor/dtor, copy ctor // TODO: ctor/dtor, copy ctor

3
test.h

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

19
tests/outline/outline.cc

@ -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"]
}]
}
*/
Loading…
Cancel
Save