This commit is contained in:
Jacob Dufault 2017-03-28 23:33:38 -07:00
parent cf1012b98c
commit a19d4f732f
8 changed files with 183 additions and 128 deletions

View File

@ -1,14 +1,30 @@
# Language
-xc++ -xc++
-std=c++11 -std=c++11
# Includes
-IC:/Users/jacob/Desktop/superindex/indexer/third_party -IC:/Users/jacob/Desktop/superindex/indexer/third_party
-IC:/Users/jacob/Desktop/superindex/indexer/third_party/doctest/doctest -IC:/Users/jacob/Desktop/superindex/indexer/third_party/doctest/doctest
-IC:/Users/jacob/Desktop/superindex/indexer/third_party/rapidjson/include -IC:/Users/jacob/Desktop/superindex/indexer/third_party/rapidjson/include
-IC:/Program Files/LLVM/include -IC:/Program Files/LLVM/include
-I/usr/local/Cellar/llvm/3.9.1/include
# Use libcxx (platform args)
#-stdlib=libc++
#-nostdinc++
#-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
#-fms-compatibility
#-fdelayed-template-parsing
#--sysrootC:/Users/jacob/Desktop/superindex/indexer/libcxx #--sysrootC:/Users/jacob/Desktop/superindex/indexer/libcxx
#-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include #-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
#-FC:/Users/jacob/Desktop/superindex/indexer/libcxx/include #-FC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
-fms-compatibility #-L<libcxx-install-prefix>/lib \
-fdelayed-template-parsing #-Wl,-rpath,<libcxx-install-prefix>/lib \
#-I<libcxx-install-prefix>/include/c++/v1 \

View File

@ -1,13 +1,30 @@
# Language
-xc++ -xc++
-std=c++11 -std=c++11
# Includes
-IC:/Users/jacob/Desktop/superindex/indexer/third_party -IC:/Users/jacob/Desktop/superindex/indexer/third_party
-IC:/Users/jacob/Desktop/superindex/indexer/third_party/doctest/doctest -IC:/Users/jacob/Desktop/superindex/indexer/third_party/doctest/doctest
-IC:/Users/jacob/Desktop/superindex/indexer/third_party/rapidjson/include -IC:/Users/jacob/Desktop/superindex/indexer/third_party/rapidjson/include
-IC:/Program Files/LLVM/include -IC:/Program Files/LLVM/include
# Use libcxx
-stdlib=libc++
-nostdinc++
-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
#-fms-compatibility
#-fdelayed-template-parsing
#--sysrootC:/Users/jacob/Desktop/superindex/indexer/libcxx #--sysrootC:/Users/jacob/Desktop/superindex/indexer/libcxx
#-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include #-IC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
#-FC:/Users/jacob/Desktop/superindex/indexer/libcxx/include #-FC:/Users/jacob/Desktop/superindex/indexer/libcxx/include
-fms-compatibility #-L<libcxx-install-prefix>/lib \
-fdelayed-template-parsing #-Wl,-rpath,<libcxx-install-prefix>/lib \
#-I<libcxx-install-prefix>/include/c++/v1 \

View File

@ -311,8 +311,7 @@ void QueryDbMainLoop(
std::vector<std::unique_ptr<BaseIpcMessage>> messages = language_client->GetMessages(&language_client->for_server); std::vector<std::unique_ptr<BaseIpcMessage>> messages = language_client->GetMessages(&language_client->for_server);
for (auto& message : messages) { for (auto& message : messages) {
// std::cerr << "Processing message " << static_cast<int>(message->ipc_id) std::cerr << "[querydb] Processing message " << static_cast<int>(message->method_id) << std::endl;
// << std::endl;
switch (message->method_id) { switch (message->method_id) {
case IpcId::Quit: { case IpcId::Quit: {
@ -392,58 +391,62 @@ void QueryDbMainLoop(
response.id = msg->id; response.id = msg->id;
QueryableFile* file = FindFile(db, msg->params.textDocument.uri.GetPath()); QueryableFile* file = FindFile(db, msg->params.textDocument.uri.GetPath());
if (file) { if (!file) {
for (UsrRef ref : file->outline) { std::cerr << "Unable to find file " << msg->params.textDocument.uri.GetPath() << std::endl;
SymbolIdx symbol = db->usr_to_symbol[ref.usr]; break;
}
lsSymbolInformation info; std::cerr << "File outline size is " << file->outline.size() << std::endl;
info.location.range.start.line = for (UsrRef ref : file->outline) {
ref.loc.line - 1; // TODO: cleanup indexer to negate by 1. SymbolIdx symbol = db->usr_to_symbol[ref.usr];
info.location.range.start.character =
ref.loc.column - 1; // TODO: cleanup indexer to negate by 1.
// TODO: store range information.
info.location.range.end.line = info.location.range.start.line;
info.location.range.end.character =
info.location.range.start.character;
// TODO: cleanup namespace/naming so there is only one SymbolKind. lsSymbolInformation info;
switch (symbol.kind) { info.location.range.start.line =
case SymbolKind::Type: { ref.loc.line - 1; // TODO: cleanup indexer to negate by 1.
QueryableTypeDef& def = db->types[symbol.idx]; info.location.range.start.character =
info.name = def.def.qualified_name; ref.loc.column - 1; // TODO: cleanup indexer to negate by 1.
info.kind = lsSymbolKind::Class; // TODO: store range information.
break; info.location.range.end.line = info.location.range.start.line;
} info.location.range.end.character =
case SymbolKind::Func: { info.location.range.start.character;
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
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 = lsSymbolKind::Function;
}
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Variable;
break;
}
case SymbolKind::File:
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
response.result.push_back(info); // TODO: cleanup namespace/naming so there is only one SymbolKind.
switch (symbol.kind) {
case SymbolKind::Type: {
QueryableTypeDef& def = db->types[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Class;
break;
} }
case SymbolKind::Func: {
QueryableFuncDef& def = db->funcs[symbol.idx];
info.name = def.def.qualified_name;
if (def.def.declaring_type.has_value()) {
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 = lsSymbolKind::Function;
}
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
info.name = def.def.qualified_name;
info.kind = lsSymbolKind::Variable;
break;
}
case SymbolKind::File:
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
response.result.push_back(info);
} }
SendOutMessageToClient(language_client, response); SendOutMessageToClient(language_client, response);
@ -459,46 +462,49 @@ void QueryDbMainLoop(
lsDocumentUri file_as_uri = msg->params.textDocument.uri; lsDocumentUri file_as_uri = msg->params.textDocument.uri;
QueryableFile* file = FindFile(db, file_as_uri.GetPath()); QueryableFile* file = FindFile(db, file_as_uri.GetPath());
if (file) { if (!file) {
for (UsrRef ref : file->outline) { std::cerr << "Unable to find file " << msg->params.textDocument.uri.GetPath() << std::endl;
SymbolIdx symbol = db->usr_to_symbol[ref.usr]; break;
switch (symbol.kind) { }
case SymbolKind::Type: {
QueryableTypeDef& def = db->types[symbol.idx]; for (UsrRef ref : file->outline) {
AddCodeLens(&response.result, ref.loc, def.uses, SymbolIdx symbol = db->usr_to_symbol[ref.usr];
true /*only_interesting*/, "reference", switch (symbol.kind) {
"references"); case SymbolKind::Type: {
AddCodeLens(&response.result, db, ref.loc, def.derived, QueryableTypeDef& def = db->types[symbol.idx];
false /*only_interesting*/, "derived", "derived"); AddCodeLens(&response.result, ref.loc, def.uses,
break; true /*only_interesting*/, "reference",
} "references");
case SymbolKind::Func: { AddCodeLens(&response.result, db, ref.loc, def.derived,
QueryableFuncDef& def = db->funcs[symbol.idx]; false /*only_interesting*/, "derived", "derived");
AddCodeLens(&response.result, ref.loc, def.uses, break;
false /*only_interesting*/, "reference",
"references");
AddCodeLens(&response.result, ref.loc, def.callers,
false /*only_interesting*/, "caller", "callers");
AddCodeLens(&response.result, ref.loc, def.def.callees,
false /*only_interesting*/, "callee", "callees");
AddCodeLens(&response.result, db, ref.loc, def.derived,
false /*only_interesting*/, "derived", "derived");
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
AddCodeLens(&response.result, ref.loc, def.uses,
false /*only_interesting*/, "reference",
"references");
break;
}
case SymbolKind::File:
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
} }
case SymbolKind::Func: {
QueryableFuncDef& def = db->funcs[symbol.idx];
AddCodeLens(&response.result, ref.loc, def.uses,
false /*only_interesting*/, "reference",
"references");
AddCodeLens(&response.result, ref.loc, def.callers,
false /*only_interesting*/, "caller", "callers");
AddCodeLens(&response.result, ref.loc, def.def.callees,
false /*only_interesting*/, "callee", "callees");
AddCodeLens(&response.result, db, ref.loc, def.derived,
false /*only_interesting*/, "derived", "derived");
break;
}
case SymbolKind::Var: {
QueryableVarDef& def = db->vars[symbol.idx];
AddCodeLens(&response.result, ref.loc, def.uses,
false /*only_interesting*/, "reference",
"references");
break;
}
case SymbolKind::File:
case SymbolKind::Invalid: {
assert(false && "unexpected");
break;
}
};
} }
SendOutMessageToClient(language_client, response); SendOutMessageToClient(language_client, response);
@ -693,7 +699,7 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
response.result.capabilities.completionProvider = lsCompletionOptions(); response.result.capabilities.completionProvider = lsCompletionOptions();
response.result.capabilities.completionProvider->resolveProvider = false; response.result.capabilities.completionProvider->resolveProvider = false;
response.result.capabilities.completionProvider->triggerCharacters = { ".", "::", "->", ":", ">" }; response.result.capabilities.completionProvider->triggerCharacters = { ".", "::", "->" };
response.result.capabilities.codeLensProvider = lsCodeLensOptions(); response.result.capabilities.codeLensProvider = lsCodeLensOptions();
response.result.capabilities.codeLensProvider->resolveProvider = false; response.result.capabilities.codeLensProvider->resolveProvider = false;
@ -724,6 +730,7 @@ void LanguageServerStdinLoop(IpcMessageQueue* ipc) {
case IpcId::TextDocumentDocumentSymbol: case IpcId::TextDocumentDocumentSymbol:
case IpcId::TextDocumentCodeLens: case IpcId::TextDocumentCodeLens:
case IpcId::WorkspaceSymbol: case IpcId::WorkspaceSymbol:
std::cerr << "Spending message " << (int)message->method_id << std::endl;
ipc->SendMessage(&ipc->for_server, message->method_id, *message.get()); ipc->SendMessage(&ipc->for_server, message->method_id, *message.get());
break; break;
} }

View File

@ -666,9 +666,8 @@ void indexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
IndexedFile* db = param->db; IndexedFile* db = param->db;
NamespaceHelper* ns = param->ns; NamespaceHelper* ns = param->ns;
// std::cerr << "DECL kind=" << decl->entityInfo->kind << " at " <<
// db->id_cache.Resolve(decl->cursor, false).ToPrettyString(&db->id_cache) << //std::cerr << "DECL kind=" << decl->entityInfo->kind << " at " << db->id_cache.Resolve(decl->cursor, false).ToPrettyString(&db->id_cache) << std::endl;
// std::endl;
switch (decl->entityInfo->kind) { switch (decl->entityInfo->kind) {
case CXIdxEntity_CXXNamespace: { case CXIdxEntity_CXXNamespace: {
@ -1197,21 +1196,11 @@ void indexEntityReference(CXClientData client_data,
} }
} }
void emptyIndexDeclaration(CXClientData client_data,
const CXIdxDeclInfo* decl) {}
void emptyIndexEntityReference(CXClientData client_data,
const CXIdxEntityRefInfo* ref) {}
IndexedFile Parse(std::string filename, IndexedFile Parse(std::string filename,
std::vector<std::string> args, std::vector<std::string> args,
bool dump_ast) { bool dump_ast) {
//clang_enableStackTraces(); clang_enableStackTraces();
//clang_toggleCrashRecovery(1); clang_toggleCrashRecovery(1);
#if defined(_WIN32)
args.push_back("-fms-compatibility");
args.push_back("-fdelayed-template-parsing");
#endif
clang::Index index(0 /*excludeDeclarationsFromPCH*/, clang::Index index(0 /*excludeDeclarationsFromPCH*/,
0 /*displayDiagnostics*/); 0 /*displayDiagnostics*/);

View File

@ -1,6 +1,7 @@
#include "TranslationUnit.h" #include "TranslationUnit.h"
#include "Tokens.h" #include "Tokens.h"
#include "Utility.h" #include "Utility.h"
#include "../platform.h"
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include <cassert> #include <cassert>
@ -16,9 +17,12 @@ TranslationUnit::TranslationUnit(
unsigned flags) { unsigned flags) {
std::vector<const char*> args; std::vector<const char*> args;
for (const std::string& a : arguments) { for (const std::string& a : arguments)
args.push_back(a.c_str()); args.push_back(a.c_str());
}
std::vector<std::string> platform_args = GetPlatformClangArguments();
for (const auto& arg : platform_args)
args.push_back(arg.c_str());
CXErrorCode error_code = clang_parseTranslationUnit2( CXErrorCode error_code = clang_parseTranslationUnit2(
index.cx_index, index.cx_index,

View File

@ -2,6 +2,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include <vector>
struct PlatformMutex { struct PlatformMutex {
virtual ~PlatformMutex(); virtual ~PlatformMutex();
@ -26,3 +27,6 @@ std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(
void PlatformInit(); void PlatformInit();
std::string GetWorkingDirectory(); std::string GetWorkingDirectory();
std::string NormalizePath(const std::string& path); std::string NormalizePath(const std::string& path);
// Returns any clang arguments that are specific to the current platform.
std::vector<std::string> GetPlatformClangArguments();

View File

@ -137,6 +137,14 @@ std::string NormalizePath(const std::string& path) {
return name; return name;
} }
std::vector<std::string> GetPlatformClangArguments() {
// TODO: use install config variable for path?
return {
"-stdlib=libc++",
"-nostdinc++",
"-I/usr/local/Cellar/llvm/3.9.1/include"
};
}
#undef CHECKED #undef CHECKED
#endif #endif

View File

@ -7,6 +7,7 @@
#include <io.h> #include <io.h>
#include <Windows.h> #include <Windows.h>
#include <algorithm>
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -16,21 +17,21 @@ namespace {
DWORD CheckForError(std::vector<DWORD> allow) { DWORD CheckForError(std::vector<DWORD> allow) {
DWORD error = GetLastError(); DWORD error = GetLastError();
if (error == ERROR_SUCCESS || if (error == ERROR_SUCCESS ||
std::find(allow.begin(), allow.end(), error) != allow.end()) std::find(allow.begin(), allow.end(), error) != allow.end())
return error; return error;
// See http://stackoverflow.com/a/17387176 // See http://stackoverflow.com/a/17387176
LPSTR message_buffer = nullptr; LPSTR message_buffer = nullptr;
size_t size = FormatMessageA( size_t size = FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPSTR)&message_buffer, 0, NULL); (LPSTR)&message_buffer, 0, NULL);
std::string message(message_buffer, size); std::string message(message_buffer, size);
LocalFree(message_buffer); LocalFree(message_buffer);
std::cerr << "Windows error code=" << error << ", message=" << message std::cerr << "Windows error code=" << error << ", message=" << message
<< std::endl; << std::endl;
assert(false); // debugger break assert(false); // debugger break
exit(1); exit(1);
@ -42,7 +43,7 @@ struct PlatformMutexWin : public PlatformMutex {
PlatformMutexWin(const std::string& name) { PlatformMutexWin(const std::string& name) {
std::cerr << "[win] Creating mutex with name " << name << std::endl; std::cerr << "[win] Creating mutex with name " << name << std::endl;
raw_mutex = CreateMutex(nullptr, false /*initial_owner*/, name.c_str()); raw_mutex = CreateMutex(nullptr, false /*initial_owner*/, name.c_str());
CheckForError({ERROR_ALREADY_EXISTS}); CheckForError({ ERROR_ALREADY_EXISTS });
} }
~PlatformMutexWin() override { ~PlatformMutexWin() override {
@ -72,15 +73,15 @@ struct PlatformSharedMemoryWin : public PlatformSharedMemory {
PlatformSharedMemoryWin(const std::string& name, size_t capacity) { PlatformSharedMemoryWin(const std::string& name, size_t capacity) {
std::cerr << "[win] Creating shared memory with name " << name std::cerr << "[win] Creating shared memory with name " << name
<< " and capacity " << capacity << std::endl; << " and capacity " << capacity << std::endl;
this->name = name; this->name = name;
shmem_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, shmem_ = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0,
capacity, name.c_str()); capacity, name.c_str());
CheckForError({ERROR_ALREADY_EXISTS} /*allow*/); CheckForError({ ERROR_ALREADY_EXISTS } /*allow*/);
data = MapViewOfFile(shmem_, FILE_MAP_ALL_ACCESS, 0, 0, capacity); data = MapViewOfFile(shmem_, FILE_MAP_ALL_ACCESS, 0, 0, capacity);
CheckForError({ERROR_ALREADY_EXISTS} /*allow*/); CheckForError({ ERROR_ALREADY_EXISTS } /*allow*/);
this->capacity = capacity; this->capacity = capacity;
} }
@ -101,14 +102,14 @@ std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
} }
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock( std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(
PlatformMutex* mutex) { PlatformMutex* mutex) {
return MakeUnique<PlatformScopedMutexLockWin>( return MakeUnique<PlatformScopedMutexLockWin>(
static_cast<PlatformMutexWin*>(mutex)->raw_mutex); static_cast<PlatformMutexWin*>(mutex)->raw_mutex);
} }
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory( std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(
const std::string& name, const std::string& name,
size_t size) { size_t size) {
return MakeUnique<PlatformSharedMemoryWin>(name, size); return MakeUnique<PlatformSharedMemoryWin>(name, size);
} }
@ -138,6 +139,15 @@ std::string NormalizePath(const std::string& path) {
if (retval == 0) if (retval == 0)
return path; return path;
return buffer; std::string result = buffer;
std::replace(result.begin(), result.end(), '\\', '/');
return result;
}
std::vector<std::string> GetPlatformClangArguments() {
return {
"-fms-compatibility",
"-fdelayed-template-parsing"
};
} }
#endif #endif