mirror of
https://github.com/MaskRay/ccls.git
synced 2025-02-16 13:48:04 +00:00
Format code
This commit is contained in:
parent
566b508b8e
commit
01fe19f280
@ -38,8 +38,8 @@ struct RealCacheManager : ICacheManager {
|
||||
if (!file_content || !serialized_indexed_content)
|
||||
return nullptr;
|
||||
|
||||
return Deserialize(config_->cacheFormat, path, *serialized_indexed_content,*file_content,
|
||||
IndexFile::kMajorVersion);
|
||||
return Deserialize(config_->cacheFormat, path, *serialized_indexed_content,
|
||||
*file_content, IndexFile::kMajorVersion);
|
||||
}
|
||||
|
||||
std::string GetCachePath(const std::string& source_file) {
|
||||
@ -91,7 +91,8 @@ struct FakeCacheManager : ICacheManager {
|
||||
std::unique_ptr<IndexFile> RawCacheLoad(const std::string& path) override {
|
||||
for (const FakeCacheEntry& entry : entries_) {
|
||||
if (entry.path == path) {
|
||||
return Deserialize(SerializeFormat::Json, path, entry.json, "<empty>", nullopt);
|
||||
return Deserialize(SerializeFormat::Json, path, entry.json, "<empty>",
|
||||
nullopt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,59 +161,87 @@ void BuildCompletionItemTexts(std::vector<lsCompletionItem>& out,
|
||||
int num_chunks = clang_getNumCompletionChunks(completion_string);
|
||||
for (int i = 0; i < num_chunks; ++i) {
|
||||
CXCompletionChunkKind kind =
|
||||
clang_getCompletionChunkKind(completion_string, i);
|
||||
clang_getCompletionChunkKind(completion_string, i);
|
||||
|
||||
std::string text;
|
||||
switch (kind) {
|
||||
case CXCompletionChunk_LeftParen: text = '('; break;
|
||||
case CXCompletionChunk_RightParen: text = ')'; break;
|
||||
case CXCompletionChunk_LeftBracket: text = '['; break;
|
||||
case CXCompletionChunk_RightBracket: text = ']'; break;
|
||||
case CXCompletionChunk_LeftBrace: text = '{'; break;
|
||||
case CXCompletionChunk_RightBrace: text = '}'; break;
|
||||
case CXCompletionChunk_LeftAngle: text = '<'; break;
|
||||
case CXCompletionChunk_RightAngle: text = '>'; break;
|
||||
case CXCompletionChunk_Comma: text = ", "; break;
|
||||
case CXCompletionChunk_Colon: text = ':'; break;
|
||||
case CXCompletionChunk_SemiColon: text = ';'; break;
|
||||
case CXCompletionChunk_Equal: text = '='; break;
|
||||
case CXCompletionChunk_HorizontalSpace: text = ' '; break;
|
||||
case CXCompletionChunk_VerticalSpace: text = ' '; break;
|
||||
case CXCompletionChunk_LeftParen:
|
||||
text = '(';
|
||||
break;
|
||||
case CXCompletionChunk_RightParen:
|
||||
text = ')';
|
||||
break;
|
||||
case CXCompletionChunk_LeftBracket:
|
||||
text = '[';
|
||||
break;
|
||||
case CXCompletionChunk_RightBracket:
|
||||
text = ']';
|
||||
break;
|
||||
case CXCompletionChunk_LeftBrace:
|
||||
text = '{';
|
||||
break;
|
||||
case CXCompletionChunk_RightBrace:
|
||||
text = '}';
|
||||
break;
|
||||
case CXCompletionChunk_LeftAngle:
|
||||
text = '<';
|
||||
break;
|
||||
case CXCompletionChunk_RightAngle:
|
||||
text = '>';
|
||||
break;
|
||||
case CXCompletionChunk_Comma:
|
||||
text = ", ";
|
||||
break;
|
||||
case CXCompletionChunk_Colon:
|
||||
text = ':';
|
||||
break;
|
||||
case CXCompletionChunk_SemiColon:
|
||||
text = ';';
|
||||
break;
|
||||
case CXCompletionChunk_Equal:
|
||||
text = '=';
|
||||
break;
|
||||
case CXCompletionChunk_HorizontalSpace:
|
||||
text = ' ';
|
||||
break;
|
||||
case CXCompletionChunk_VerticalSpace:
|
||||
text = ' ';
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_ResultType:
|
||||
result_type =
|
||||
ToString(clang_getCompletionChunkText(completion_string, i));
|
||||
continue;
|
||||
case CXCompletionChunk_ResultType:
|
||||
result_type =
|
||||
ToString(clang_getCompletionChunkText(completion_string, i));
|
||||
continue;
|
||||
|
||||
case CXCompletionChunk_TypedText:
|
||||
case CXCompletionChunk_Placeholder:
|
||||
case CXCompletionChunk_Text:
|
||||
case CXCompletionChunk_Informative:
|
||||
text = ToString(clang_getCompletionChunkText(completion_string, i));
|
||||
case CXCompletionChunk_TypedText:
|
||||
case CXCompletionChunk_Placeholder:
|
||||
case CXCompletionChunk_Text:
|
||||
case CXCompletionChunk_Informative:
|
||||
text = ToString(clang_getCompletionChunkText(completion_string, i));
|
||||
|
||||
for (auto i = out_first; i < out.size(); ++i) {
|
||||
// first typed text is used for filtering
|
||||
if (kind == CXCompletionChunk_TypedText && !out[i].filterText)
|
||||
out[i].filterText = text;
|
||||
for (auto i = out_first; i < out.size(); ++i) {
|
||||
// first typed text is used for filtering
|
||||
if (kind == CXCompletionChunk_TypedText && !out[i].filterText)
|
||||
out[i].filterText = text;
|
||||
|
||||
if (kind == CXCompletionChunk_Placeholder)
|
||||
out[i].parameters_.push_back(text);
|
||||
if (kind == CXCompletionChunk_Placeholder)
|
||||
out[i].parameters_.push_back(text);
|
||||
}
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_CurrentParameter:
|
||||
// We have our own parsing logic for active parameter. This doesn't seem
|
||||
// to be very reliable.
|
||||
continue;
|
||||
|
||||
case CXCompletionChunk_Optional: {
|
||||
CXCompletionString nested =
|
||||
clang_getCompletionChunkCompletionString(completion_string, i);
|
||||
// duplicate last element, the recursive call will complete it
|
||||
out.push_back(out.back());
|
||||
BuildCompletionItemTexts(out, nested, include_snippets);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
|
||||
case CXCompletionChunk_CurrentParameter:
|
||||
// We have our own parsing logic for active parameter. This doesn't seem
|
||||
// to be very reliable.
|
||||
continue;
|
||||
|
||||
case CXCompletionChunk_Optional: {
|
||||
CXCompletionString nested =
|
||||
clang_getCompletionChunkCompletionString(completion_string, i);
|
||||
// duplicate last element, the recursive call will complete it
|
||||
out.push_back(out.back());
|
||||
BuildCompletionItemTexts(out, nested, include_snippets);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = out_first; i < out.size(); ++i)
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "position.h"
|
||||
#include "nt_string.h"
|
||||
#include "position.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
#include <optional.h>
|
||||
|
@ -98,23 +98,27 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
|
||||
auto make_msg = [&]() {
|
||||
return "Please try running the following, identify which flag causes the "
|
||||
"issue, and report a bug. cquery will then filter the flag for you "
|
||||
" automatically:\n$ " + StringJoin(args, " ") + " -fsyntax-only";
|
||||
" automatically:\n$ " +
|
||||
StringJoin(args, " ") + " -fsyntax-only";
|
||||
};
|
||||
|
||||
switch (error_code) {
|
||||
case CXError_Success:
|
||||
return MakeUnique<ClangTranslationUnit>(cx_tu);
|
||||
case CXError_Failure:
|
||||
LOG_S(ERROR) << "libclang generic failure for " << filepath << ". " << make_msg();
|
||||
LOG_S(ERROR) << "libclang generic failure for " << filepath << ". "
|
||||
<< make_msg();
|
||||
return nullptr;
|
||||
case CXError_Crashed:
|
||||
LOG_S(ERROR) << "libclang crashed for " << filepath << ". " << make_msg();
|
||||
return nullptr;
|
||||
case CXError_InvalidArguments:
|
||||
LOG_S(ERROR) << "libclang had invalid arguments for " << filepath << ". " << make_msg();
|
||||
LOG_S(ERROR) << "libclang had invalid arguments for " << filepath << ". "
|
||||
<< make_msg();
|
||||
return nullptr;
|
||||
case CXError_ASTReadError:
|
||||
LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". " << make_msg();
|
||||
LOG_S(ERROR) << "libclang had ast read error for " << filepath << ". "
|
||||
<< make_msg();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -135,8 +135,8 @@ struct Config {
|
||||
int includeMaxPathSize = 30;
|
||||
|
||||
// Whitelist that file paths will be tested against. If a file path does not
|
||||
// end in one of these values, it will not be considered for auto-completion.
|
||||
// An example value is { ".h", ".hpp" }
|
||||
// end in one of these values, it will not be considered for
|
||||
// auto-completion. An example value is { ".h", ".hpp" }
|
||||
//
|
||||
// This is significantly faster than using a regex.
|
||||
std::vector<std::string> includeSuffixWhitelist = {".h", ".hpp", ".hh"};
|
||||
@ -154,8 +154,8 @@ struct Config {
|
||||
bool attributeMakeCallsToCtor = true;
|
||||
|
||||
// If a translation unit's absolute path matches any EMCAScript regex in the
|
||||
// whitelist, or does not match any regex in the blacklist, it will be indexed.
|
||||
// To only index files in the whitelist, add ".*" to the blacklist.
|
||||
// whitelist, or does not match any regex in the blacklist, it will be
|
||||
// indexed. To only index files in the whitelist, add ".*" to the blacklist.
|
||||
// `std::regex_search(path, regex, std::regex_constants::match_any)`
|
||||
//
|
||||
// Example: `ash/.*\.cc`
|
||||
|
@ -66,7 +66,7 @@ IndexFile* FileConsumer::TryConsumeFile(CXFile file,
|
||||
|
||||
// No result in local; we need to query global.
|
||||
bool did_insert = shared_->Mark(file_name);
|
||||
|
||||
|
||||
// We did not take the file from global. Cache that we failed so we don't try
|
||||
// again and return nullptr.
|
||||
if (!did_insert) {
|
||||
@ -75,7 +75,8 @@ IndexFile* FileConsumer::TryConsumeFile(CXFile file,
|
||||
}
|
||||
|
||||
// Read the file contents, if we fail then we cannot index the file.
|
||||
optional<std::string> contents = GetFileContents(file_name, file_contents_map);
|
||||
optional<std::string> contents =
|
||||
GetFileContents(file_name, file_contents_map);
|
||||
if (!contents) {
|
||||
*is_first_ownership = false;
|
||||
return nullptr;
|
||||
|
@ -143,7 +143,8 @@ ShouldParse FileNeedsParse(
|
||||
return ShouldParse::NoSuchFile;
|
||||
|
||||
optional<int64_t> last_cached_modification =
|
||||
timestamp_manager->GetLastCachedModificationTime(cache_manager.get(), path);
|
||||
timestamp_manager->GetLastCachedModificationTime(cache_manager.get(),
|
||||
path);
|
||||
|
||||
// File has been changed.
|
||||
if (!last_cached_modification ||
|
||||
@ -236,8 +237,9 @@ CacheLoadResult TryLoadFromCache(
|
||||
PerformanceImportFile perf;
|
||||
|
||||
std::vector<Index_DoIdMap> result;
|
||||
result.push_back(Index_DoIdMap(cache_manager->TakeOrLoad(path_to_index), cache_manager, perf,
|
||||
is_interactive, false /*write_to_disk*/));
|
||||
result.push_back(Index_DoIdMap(cache_manager->TakeOrLoad(path_to_index),
|
||||
cache_manager, perf, is_interactive,
|
||||
false /*write_to_disk*/));
|
||||
for (const std::string& dependency : previous_index->dependencies) {
|
||||
// Only load a dependency if it is not already loaded.
|
||||
//
|
||||
@ -257,8 +259,9 @@ CacheLoadResult TryLoadFromCache(
|
||||
if (!dependency_index)
|
||||
continue;
|
||||
|
||||
result.push_back(Index_DoIdMap(std::move(dependency_index), cache_manager, perf,
|
||||
is_interactive, false /*write_to_disk*/));
|
||||
result.push_back(Index_DoIdMap(std::move(dependency_index), cache_manager,
|
||||
perf, is_interactive,
|
||||
false /*write_to_disk*/));
|
||||
}
|
||||
|
||||
QueueManager::instance()->do_id_map.EnqueueAll(std::move(result));
|
||||
@ -344,7 +347,7 @@ void ParseFile(Config* config,
|
||||
|
||||
LOG_S(INFO) << "Parsing " << path_to_index;
|
||||
std::vector<FileContents> file_contents = PreloadFileContents(
|
||||
request.cache_manager, entry, request.contents, path_to_index);
|
||||
request.cache_manager, entry, request.contents, path_to_index);
|
||||
|
||||
std::vector<Index_DoIdMap> result;
|
||||
PerformanceImportFile perf;
|
||||
@ -375,8 +378,8 @@ void ParseFile(Config* config,
|
||||
// When main thread does IdMap request it will request the previous index if
|
||||
// needed.
|
||||
LOG_S(INFO) << "Emitting index result for " << new_index->path;
|
||||
result.push_back(Index_DoIdMap(std::move(new_index), request.cache_manager, perf,
|
||||
request.is_interactive,
|
||||
result.push_back(Index_DoIdMap(std::move(new_index), request.cache_manager,
|
||||
perf, request.is_interactive,
|
||||
true /*write_to_disk*/));
|
||||
}
|
||||
|
||||
@ -401,8 +404,8 @@ bool IndexMain_DoParse(
|
||||
entry.filename = request->path;
|
||||
entry.args = request->args;
|
||||
ParseFile(config, working_files, file_consumer_shared, timestamp_manager,
|
||||
modification_timestamp_fetcher, import_manager,
|
||||
indexer, request.value(), entry);
|
||||
modification_timestamp_fetcher, import_manager, indexer,
|
||||
request.value(), entry);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -477,7 +480,8 @@ bool IndexMain_LoadPreviousIndex() {
|
||||
if (!response)
|
||||
return false;
|
||||
|
||||
response->previous = response->cache_manager->TryTakeOrLoad(response->current->path);
|
||||
response->previous =
|
||||
response->cache_manager->TryTakeOrLoad(response->current->path);
|
||||
LOG_IF_S(ERROR, !response->previous)
|
||||
<< "Unable to load previous index for already imported index "
|
||||
<< response->current->path;
|
||||
@ -584,14 +588,13 @@ void Indexer_Main(Config* config,
|
||||
// IndexMain_DoCreateIndexUpdate so we don't starve querydb from doing any
|
||||
// work. Running both also lets the user query the partially constructed
|
||||
// index.
|
||||
did_work = IndexMain_DoParse(
|
||||
config, working_files, file_consumer_shared,
|
||||
timestamp_manager, &modification_timestamp_fetcher,
|
||||
import_manager, indexer.get()) ||
|
||||
did_work;
|
||||
did_work =
|
||||
IndexMain_DoParse(config, working_files, file_consumer_shared,
|
||||
timestamp_manager, &modification_timestamp_fetcher,
|
||||
import_manager, indexer.get()) ||
|
||||
did_work;
|
||||
|
||||
did_work = IndexMain_DoCreateIndexUpdate(timestamp_manager) ||
|
||||
did_work;
|
||||
did_work = IndexMain_DoCreateIndexUpdate(timestamp_manager) || did_work;
|
||||
|
||||
did_work = IndexMain_LoadPreviousIndex() || did_work;
|
||||
|
||||
@ -743,10 +746,9 @@ TEST_SUITE("ImportPipeline") {
|
||||
}
|
||||
|
||||
bool PumpOnce() {
|
||||
return IndexMain_DoParse(&config, &working_files, &file_consumer_shared,
|
||||
×tamp_manager,
|
||||
&modification_timestamp_fetcher, &import_manager,
|
||||
indexer.get());
|
||||
return IndexMain_DoParse(
|
||||
&config, &working_files, &file_consumer_shared, ×tamp_manager,
|
||||
&modification_timestamp_fetcher, &import_manager, indexer.get());
|
||||
}
|
||||
|
||||
void MakeRequest(const std::string& path,
|
||||
|
@ -82,7 +82,7 @@ lsCompletionItem BuildCompletionItem(Config* config,
|
||||
bool is_stl) {
|
||||
lsCompletionItem item;
|
||||
item.label = ElideLongPath(config, path);
|
||||
item.detail = path; // the include path, used in de-duplicating
|
||||
item.detail = path; // the include path, used in de-duplicating
|
||||
item.textEdit = lsTextEdit();
|
||||
item.textEdit->newText = path;
|
||||
item.insertTextFormat = lsInsertTextFormat::PlainText;
|
||||
@ -142,7 +142,8 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path,
|
||||
completion_items[it->second].detail.length() > item.detail.length())
|
||||
absolute_path_to_completion_item[absolute_path] = completion_items.size();
|
||||
} else {
|
||||
lsCompletionItem& inserted_item = completion_items[inserted_paths[item.detail]];
|
||||
lsCompletionItem& inserted_item =
|
||||
completion_items[inserted_paths[item.detail]];
|
||||
// Update |use_angle_brackets_|, prefer quotes.
|
||||
if (!item.use_angle_brackets_)
|
||||
inserted_item.use_angle_brackets_ = false;
|
||||
@ -150,8 +151,7 @@ void IncludeComplete::InsertCompletionItem(const std::string& absolute_path,
|
||||
}
|
||||
|
||||
void IncludeComplete::AddFile(const std::string& absolute_path) {
|
||||
if (!EndsWithAny(absolute_path,
|
||||
config_->completion.includeSuffixWhitelist))
|
||||
if (!EndsWithAny(absolute_path, config_->completion.includeSuffixWhitelist))
|
||||
return;
|
||||
if (match_ && !match_->IsMatch(absolute_path))
|
||||
return;
|
||||
@ -183,8 +183,7 @@ void IncludeComplete::InsertIncludesFromDirectory(std::string directory,
|
||||
GetFilesInFolder(
|
||||
directory, true /*recursive*/, false /*add_folder_to_path*/,
|
||||
[&](const std::string& path) {
|
||||
if (!EndsWithAny(path,
|
||||
config_->completion.includeSuffixWhitelist))
|
||||
if (!EndsWithAny(path, config_->completion.includeSuffixWhitelist))
|
||||
return;
|
||||
if (match_ && !match_->IsMatch(directory + path))
|
||||
return;
|
||||
|
169
src/indexer.cc
169
src/indexer.cc
@ -83,25 +83,25 @@ Role GetRole(const CXIdxEntityRefInfo* ref_info, Role role) {
|
||||
|
||||
SymbolKind GetSymbolKind(CXCursorKind kind) {
|
||||
switch (kind) {
|
||||
default:
|
||||
return SymbolKind::Invalid;
|
||||
default:
|
||||
return SymbolKind::Invalid;
|
||||
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_CXXMethod:
|
||||
case CXCursor_Constructor:
|
||||
case CXCursor_Destructor:
|
||||
case CXCursor_ConversionFunction:
|
||||
case CXCursor_FunctionTemplate:
|
||||
case CXCursor_OverloadedDeclRef:
|
||||
case CXCursor_LambdaExpr:
|
||||
return SymbolKind::Func;
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_CXXMethod:
|
||||
case CXCursor_Constructor:
|
||||
case CXCursor_Destructor:
|
||||
case CXCursor_ConversionFunction:
|
||||
case CXCursor_FunctionTemplate:
|
||||
case CXCursor_OverloadedDeclRef:
|
||||
case CXCursor_LambdaExpr:
|
||||
return SymbolKind::Func;
|
||||
|
||||
case CXCursor_Namespace:
|
||||
case CXCursor_EnumDecl:
|
||||
case CXCursor_UnionDecl:
|
||||
case CXCursor_StructDecl:
|
||||
case CXCursor_ClassDecl:
|
||||
return SymbolKind::Type;
|
||||
case CXCursor_Namespace:
|
||||
case CXCursor_EnumDecl:
|
||||
case CXCursor_UnionDecl:
|
||||
case CXCursor_StructDecl:
|
||||
case CXCursor_ClassDecl:
|
||||
return SymbolKind::Type;
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,7 +306,9 @@ struct IndexParam {
|
||||
NamespaceHelper ns;
|
||||
ConstructorCache ctors;
|
||||
|
||||
IndexParam(Config* config, ClangTranslationUnit* tu, FileConsumer* file_consumer)
|
||||
IndexParam(Config* config,
|
||||
ClangTranslationUnit* tu,
|
||||
FileConsumer* file_consumer)
|
||||
: config(config), tu(tu), file_consumer(file_consumer) {}
|
||||
|
||||
#if CINDEX_HAVE_PRETTY
|
||||
@ -324,8 +326,8 @@ struct IndexParam {
|
||||
CXPrintingPolicy_TerseOutput, 1);
|
||||
clang_PrintingPolicy_setProperty(print_policy,
|
||||
CXPrintingPolicy_FullyQualifiedName, 1);
|
||||
clang_PrintingPolicy_setProperty(print_policy,
|
||||
CXPrintingPolicy_SuppressInitializers, 1);
|
||||
clang_PrintingPolicy_setProperty(
|
||||
print_policy, CXPrintingPolicy_SuppressInitializers, 1);
|
||||
print_policy_more = clang_getCursorPrintingPolicy(cursor);
|
||||
clang_PrintingPolicy_setProperty(print_policy_more,
|
||||
CXPrintingPolicy_FullyQualifiedName, 1);
|
||||
@ -348,7 +350,8 @@ IndexFile* ConsumeFile(IndexParam* param, CXFile file) {
|
||||
if (param->seen_cx_files.insert(file).second) {
|
||||
std::string file_name = FileName(file);
|
||||
// file_name may be empty when it contains .. and is outside of WorkingDir.
|
||||
// https://reviews.llvm.org/D42893 https://github.com/cquery-project/cquery/issues/413
|
||||
// https://reviews.llvm.org/D42893
|
||||
// https://github.com/cquery-project/cquery/issues/413
|
||||
if (!file_name.empty()) {
|
||||
// Add to all files we have seen so we can generate proper dependency
|
||||
// graph.
|
||||
@ -464,17 +467,17 @@ std::string GetDocumentContentInRange(CXTranslationUnit cx_tu,
|
||||
|
||||
void SetUsePreflight(IndexFile* db, ClangCursor parent) {
|
||||
switch (GetSymbolKind(parent.get_kind())) {
|
||||
case SymbolKind::Func:
|
||||
(void)db->ToFuncId(parent.cx_cursor);
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
(void)db->ToTypeId(parent.cx_cursor);
|
||||
break;
|
||||
case SymbolKind::Var:
|
||||
(void)db->ToVarId(parent.cx_cursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case SymbolKind::Func:
|
||||
(void)db->ToFuncId(parent.cx_cursor);
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
(void)db->ToTypeId(parent.cx_cursor);
|
||||
break;
|
||||
case SymbolKind::Var:
|
||||
(void)db->ToVarId(parent.cx_cursor);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -508,11 +511,11 @@ void SetTypeName(IndexType* type,
|
||||
name = "(anon)";
|
||||
if (!container)
|
||||
parent.cursor = cursor.get_semantic_parent().cx_cursor;
|
||||
// Investigate why clang_getCursorPrettyPrinted gives `struct A {}` `namespace ns {}`
|
||||
// which are not qualified.
|
||||
//type->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor);
|
||||
// Investigate why clang_getCursorPrettyPrinted gives `struct A {}` `namespace
|
||||
// ns {}` which are not qualified.
|
||||
// type->def.detailed_name = param->PrettyPrintCursor(cursor.cx_cursor);
|
||||
type->def.detailed_name =
|
||||
param->ns.QualifiedName(container ? container : &parent, name);
|
||||
param->ns.QualifiedName(container ? container : &parent, name);
|
||||
auto idx = type->def.detailed_name.find(name);
|
||||
assert(idx != std::string::npos);
|
||||
type->def.short_name_offset = idx;
|
||||
@ -584,7 +587,7 @@ void SetVarDetail(IndexVar* var,
|
||||
? param->PrettyPrintCursor(cursor.cx_cursor)
|
||||
:
|
||||
#endif
|
||||
param->ns.QualifiedName(semanticContainer, short_name);
|
||||
param->ns.QualifiedName(semanticContainer, short_name);
|
||||
|
||||
if (cursor.get_kind() == CXCursor_EnumConstantDecl && semanticContainer) {
|
||||
CXType enum_type = clang_getCanonicalType(
|
||||
@ -658,19 +661,22 @@ void OnIndexReference_Function(IndexFile* db,
|
||||
IndexFunc* called = db->Resolve(called_id);
|
||||
parent->def.callees.push_back(
|
||||
SymbolRef(loc, called->id, SymbolKind::Func, role));
|
||||
AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Func, role, {}));
|
||||
AddFuncUse(&called->uses,
|
||||
Use(loc, parent->id, SymbolKind::Func, role, {}));
|
||||
break;
|
||||
}
|
||||
case SymbolKind::Type: {
|
||||
IndexType* parent = db->Resolve(db->ToTypeId(parent_cursor.cx_cursor));
|
||||
IndexFunc* called = db->Resolve(called_id);
|
||||
called = db->Resolve(called_id);
|
||||
AddFuncUse(&called->uses, Use(loc, parent->id, SymbolKind::Type, role, {}));
|
||||
AddFuncUse(&called->uses,
|
||||
Use(loc, parent->id, SymbolKind::Type, role, {}));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
IndexFunc* called = db->Resolve(called_id);
|
||||
AddFuncUse(&called->uses, Use(loc, Id<void>(), SymbolKind::File, role, {}));
|
||||
AddFuncUse(&called->uses,
|
||||
Use(loc, Id<void>(), SymbolKind::File, role, {}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -789,26 +795,31 @@ CXCursor fromContainer(const CXIdxContainerInfo* parent) {
|
||||
return parent ? parent->cursor : clang_getNullCursor();
|
||||
}
|
||||
|
||||
void AddUseSpell(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
ClangCursor cursor) {
|
||||
AddUse(db, uses, cursor.get_spell(),
|
||||
cursor.get_lexical_parent().cx_cursor, Role::Reference);
|
||||
void AddUseSpell(IndexFile* db, std::vector<Use>& uses, ClangCursor cursor) {
|
||||
AddUse(db, uses, cursor.get_spell(), cursor.get_lexical_parent().cx_cursor,
|
||||
Role::Reference);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void UniqueAddUse(IndexFile* db, std::vector<Use>& uses, Range range, Args&&... args) {
|
||||
void UniqueAddUse(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
Range range,
|
||||
Args&&... args) {
|
||||
if (std::find_if(uses.begin(), uses.end(),
|
||||
[&](Use use) { return use.range == range; }) == uses.end())
|
||||
AddUse(db, uses, range, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void UniqueAddUseSpell(IndexFile* db, std::vector<Use>& uses, ClangCursor cursor, Args&&... args) {
|
||||
void UniqueAddUseSpell(IndexFile* db,
|
||||
std::vector<Use>& uses,
|
||||
ClangCursor cursor,
|
||||
Args&&... args) {
|
||||
Range range = cursor.get_spell();
|
||||
if (std::find_if(uses.begin(), uses.end(),
|
||||
[&](Use use) { return use.range == range; }) == uses.end())
|
||||
AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor, std::forward<Args>(args)...);
|
||||
AddUse(db, uses, range, cursor.get_lexical_parent().cx_cursor,
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
IdCache::IdCache(const std::string& primary_file)
|
||||
@ -1292,8 +1303,8 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ref_var = db->Resolve(ref_var_id);
|
||||
ref_var->def.spell = SetUse(db, ref_cursor.get_spell(),
|
||||
sem_parent, Role::Definition);
|
||||
ref_var->def.spell =
|
||||
SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition);
|
||||
ref_var->def.extent =
|
||||
SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
|
||||
ref_var = db->Resolve(ref_var_id);
|
||||
@ -1328,9 +1339,8 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_FunctionTemplate: {
|
||||
IndexFuncId called_id = db->ToFuncId(overloaded.get_usr_hash());
|
||||
OnIndexReference_Function(db, cursor.get_spell(),
|
||||
data->container, called_id,
|
||||
Role::Call);
|
||||
OnIndexReference_Function(db, cursor.get_spell(), data->container,
|
||||
called_id, Role::Call);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1353,11 +1363,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ref_type = db->Resolve(ref_type_id);
|
||||
ref_type->def.spell = SetUse(db, ref_cursor.get_spell(),
|
||||
sem_parent, Role::Definition);
|
||||
ref_type->def.spell =
|
||||
SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition);
|
||||
ref_type->def.extent =
|
||||
SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
|
||||
#if 0&&CINDEX_HAVE_PRETTY
|
||||
#if 0 && CINDEX_HAVE_PRETTY
|
||||
ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor);
|
||||
#else
|
||||
ref_type->def.detailed_name = ref_cursor.get_spell_name();
|
||||
@ -1387,11 +1397,11 @@ ClangCursor::VisitResult TemplateVisitor(ClangCursor cursor,
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ref_type = db->Resolve(ref_type_id);
|
||||
ref_type->def.spell = SetUse(db, ref_cursor.get_spell(),
|
||||
sem_parent, Role::Definition);
|
||||
ref_type->def.spell =
|
||||
SetUse(db, ref_cursor.get_spell(), sem_parent, Role::Definition);
|
||||
ref_type->def.extent =
|
||||
SetUse(db, ref_cursor.get_extent(), lex_parent, Role::None);
|
||||
#if 0&&CINDEX_HAVE_PRETTY
|
||||
#if 0 && CINDEX_HAVE_PRETTY
|
||||
// template<class T> void f(T t){} // weird, the name is empty
|
||||
ref_type->def.detailed_name = param->PrettyPrintCursor(ref_cursor.cx_cursor);
|
||||
#else
|
||||
@ -1523,8 +1533,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
IndexType* ns = db->Resolve(ns_id);
|
||||
ns->def.kind = GetSymbolKind(decl->entityInfo->kind);
|
||||
if (ns->def.detailed_name.empty()) {
|
||||
SetTypeName(ns, cursor, decl->semanticContainer,
|
||||
decl->entityInfo->name, param);
|
||||
SetTypeName(ns, cursor, decl->semanticContainer, decl->entityInfo->name,
|
||||
param);
|
||||
ns->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
|
||||
ns->def.extent =
|
||||
SetUse(db, cursor.get_extent(), lex_parent, Role::None);
|
||||
@ -1592,8 +1602,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
// the function declaration is encountered since we won't receive ParmDecl
|
||||
// declarations for unnamed parameters.
|
||||
// TODO: See if we can remove this function call.
|
||||
AddDeclTypeUsages(db, cursor, var->def.type,
|
||||
decl->semanticContainer, decl->lexicalContainer);
|
||||
AddDeclTypeUsages(db, cursor, var->def.type, decl->semanticContainer,
|
||||
decl->lexicalContainer);
|
||||
|
||||
// We don't need to assign declaring type multiple times if this variable
|
||||
// has already been seen.
|
||||
@ -1687,10 +1697,9 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
// indexing the definition, then there will not be any (ie) outline
|
||||
// information.
|
||||
if (!is_template_specialization) {
|
||||
|
||||
// Build detailed name. The type desc looks like void (void *). We
|
||||
// insert the qualified name before the first '('.
|
||||
// FIXME GetFunctionSignature should set index
|
||||
// Build detailed name. The type desc looks like void (void *). We
|
||||
// insert the qualified name before the first '('.
|
||||
// FIXME GetFunctionSignature should set index
|
||||
#if CINDEX_HAVE_PRETTY
|
||||
func->def.detailed_name = param->PrettyPrintCursor(decl->cursor);
|
||||
#else
|
||||
@ -1802,7 +1811,8 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
}
|
||||
}
|
||||
|
||||
UniqueAddUse(db, type->uses, spell, fromContainer(decl->lexicalContainer));
|
||||
UniqueAddUse(db, type->uses, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1833,14 +1843,16 @@ void OnIndexDeclaration(CXClientData client_data, const CXIdxDeclInfo* decl) {
|
||||
|
||||
if (decl->isDefinition) {
|
||||
type->def.spell = SetUse(db, spell, sem_parent, Role::Definition);
|
||||
type->def.extent = SetUse(db, decl_cursor.get_extent(), lex_parent, Role::None);
|
||||
type->def.extent =
|
||||
SetUse(db, decl_cursor.get_extent(), lex_parent, Role::None);
|
||||
|
||||
if (decl_cursor.get_kind() == CXCursor_EnumDecl) {
|
||||
ClangType enum_type = clang_getEnumDeclIntegerType(decl->cursor);
|
||||
if (!enum_type.is_fundamental()) {
|
||||
IndexType* int_type =
|
||||
db->Resolve(db->ToTypeId(enum_type.get_usr_hash()));
|
||||
AddUse(db, int_type->uses, spell, fromContainer(decl->lexicalContainer));
|
||||
AddUse(db, int_type->uses, spell,
|
||||
fromContainer(decl->lexicalContainer));
|
||||
// type is invalidated.
|
||||
type = db->Resolve(type_id);
|
||||
}
|
||||
@ -1999,8 +2011,10 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
ClangCursor lex_parent = referenced.get_lexical_parent();
|
||||
SetUsePreflight(db, sem_parent);
|
||||
SetUsePreflight(db, lex_parent);
|
||||
ns->def.spell = SetUse(db, referenced.get_spell(), sem_parent, Role::Definition);
|
||||
ns->def.extent = SetUse(db, referenced.get_extent(), lex_parent, Role::None);
|
||||
ns->def.spell =
|
||||
SetUse(db, referenced.get_spell(), sem_parent, Role::Definition);
|
||||
ns->def.extent =
|
||||
SetUse(db, referenced.get_extent(), lex_parent, Role::None);
|
||||
std::string name = referenced.get_spell_name();
|
||||
SetTypeName(ns, referenced, nullptr, name.c_str(), param);
|
||||
}
|
||||
@ -2031,7 +2045,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
Range spell = referenced.get_spell(&referenced_file);
|
||||
if (file == referenced_file) {
|
||||
var->def.spell = SetUse(db, spell, lex_parent, Role::Definition);
|
||||
var->def.extent = SetUse(db, referenced.get_extent(), lex_parent, Role::None);
|
||||
var->def.extent =
|
||||
SetUse(db, referenced.get_extent(), lex_parent, Role::None);
|
||||
|
||||
// TODO Some of the logic here duplicates CXIdxEntity_Variable branch
|
||||
// of OnIndexDeclaration. But there `decl` is of type CXIdxDeclInfo
|
||||
@ -2041,7 +2056,8 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
var->def.kind = lsSymbolKind::Parameter;
|
||||
}
|
||||
}
|
||||
UniqueAddUse(db, var->uses, loc, fromContainer(ref->container), GetRole(ref, Role::Reference));
|
||||
UniqueAddUse(db, var->uses, loc, fromContainer(ref->container),
|
||||
GetRole(ref, Role::Reference));
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2152,7 +2168,7 @@ void OnIndexReference(CXClientData client_data, const CXIdxEntityRefInfo* ref) {
|
||||
case CXIdxEntity_ObjCProtocol:
|
||||
case CXIdxEntity_ObjCClass:
|
||||
case CXIdxEntity_Typedef:
|
||||
case CXIdxEntity_CXXInterface: // MSVC __interface
|
||||
case CXIdxEntity_CXXInterface: // MSVC __interface
|
||||
case CXIdxEntity_CXXTypeAlias:
|
||||
case CXIdxEntity_Enum:
|
||||
case CXIdxEntity_Union:
|
||||
@ -2414,7 +2430,8 @@ void Reflect(Writer& visitor, Reference& value) {
|
||||
if (visitor.Format() == SerializeFormat::Json) {
|
||||
std::string s = value.range.ToString();
|
||||
// RawId(-1) -> "-1"
|
||||
s += '|' + std::to_string(static_cast<std::make_signed<RawId>::type>(value.id.id));
|
||||
s += '|' + std::to_string(
|
||||
static_cast<std::make_signed<RawId>::type>(value.id.id));
|
||||
s += '|' + std::to_string(int(value.kind));
|
||||
s += '|' + std::to_string(int(value.role));
|
||||
Reflect(visitor, s);
|
||||
|
@ -111,19 +111,15 @@ struct Reference {
|
||||
std::tuple<Range, Id<void>, SymbolKind, Role> ToTuple() const {
|
||||
return std::make_tuple(range, id, kind, role);
|
||||
}
|
||||
bool operator==(const Reference& o) const {
|
||||
return ToTuple() == o.ToTuple();
|
||||
}
|
||||
bool operator<(const Reference& o) const {
|
||||
return ToTuple() < o.ToTuple();
|
||||
}
|
||||
bool operator==(const Reference& o) const { return ToTuple() == o.ToTuple(); }
|
||||
bool operator<(const Reference& o) const { return ToTuple() < o.ToTuple(); }
|
||||
};
|
||||
|
||||
// |id,kind| refer to the referenced entity.
|
||||
struct SymbolRef : Reference {
|
||||
SymbolRef() = default;
|
||||
SymbolRef(Range range, Id<void> id, SymbolKind kind, Role role)
|
||||
: Reference{range, id, kind, role} {}
|
||||
: Reference{range, id, kind, role} {}
|
||||
};
|
||||
|
||||
// Represents an occurrence of a variable/type, |id,kind| refer to the lexical
|
||||
@ -133,7 +129,7 @@ struct Use : Reference {
|
||||
Id<QueryFile> file;
|
||||
Use() = default;
|
||||
Use(Range range, Id<void> id, SymbolKind kind, Role role, Id<QueryFile> file)
|
||||
: Reference{range, id, kind, role}, file(file) {}
|
||||
: Reference{range, id, kind, role}, file(file) {}
|
||||
};
|
||||
|
||||
void Reflect(Reader& visitor, Reference& value);
|
||||
@ -184,8 +180,7 @@ struct TypeDefDefinitionData {
|
||||
lsSymbolKind kind = lsSymbolKind::Unknown;
|
||||
|
||||
bool operator==(const TypeDefDefinitionData& o) const {
|
||||
return detailed_name == o.detailed_name &&
|
||||
spell == o.spell &&
|
||||
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||
extent == o.extent && alias_of == o.alias_of &&
|
||||
parents == o.parents && types == o.types && funcs == o.funcs &&
|
||||
vars == o.vars && kind == o.kind && hover == o.hover &&
|
||||
@ -273,12 +268,11 @@ struct FuncDefDefinitionData {
|
||||
StorageClass storage = StorageClass::Invalid;
|
||||
|
||||
bool operator==(const FuncDefDefinitionData& o) const {
|
||||
return detailed_name == o.detailed_name &&
|
||||
spell == o.spell &&
|
||||
extent == o.extent &&
|
||||
declaring_type == o.declaring_type && base == o.base &&
|
||||
locals == o.locals && callees == o.callees && kind == o.kind &&
|
||||
storage == o.storage && hover == o.hover && comments == o.comments;
|
||||
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||
extent == o.extent && declaring_type == o.declaring_type &&
|
||||
base == o.base && locals == o.locals && callees == o.callees &&
|
||||
kind == o.kind && storage == o.storage && hover == o.hover &&
|
||||
comments == o.comments;
|
||||
}
|
||||
bool operator!=(const FuncDefDefinitionData& o) const {
|
||||
return !(*this == o);
|
||||
@ -344,9 +338,7 @@ struct IndexFunc {
|
||||
bool operator<(const IndexFunc& other) const { return id < other.id; }
|
||||
};
|
||||
MAKE_HASHABLE(IndexFunc, t.id);
|
||||
MAKE_REFLECT_STRUCT(IndexFunc::Declaration,
|
||||
spell,
|
||||
param_spellings);
|
||||
MAKE_REFLECT_STRUCT(IndexFunc::Declaration, spell, param_spellings);
|
||||
|
||||
template <typename F>
|
||||
struct VarDefDefinitionData {
|
||||
@ -372,15 +364,12 @@ struct VarDefDefinitionData {
|
||||
// (declaration).
|
||||
StorageClass storage = StorageClass::Invalid;
|
||||
|
||||
bool is_local() const {
|
||||
return kind == lsSymbolKind::Variable;
|
||||
}
|
||||
bool is_local() const { return kind == lsSymbolKind::Variable; }
|
||||
|
||||
bool operator==(const VarDefDefinitionData& o) const {
|
||||
return detailed_name == o.detailed_name && spell == o.spell &&
|
||||
extent == o.extent && type == o.type &&
|
||||
kind == o.kind && storage == o.storage && hover == o.hover &&
|
||||
comments == o.comments;
|
||||
extent == o.extent && type == o.type && kind == o.kind &&
|
||||
storage == o.storage && hover == o.hover && comments == o.comments;
|
||||
}
|
||||
bool operator!=(const VarDefDefinitionData& o) const { return !(*this == o); }
|
||||
|
||||
|
@ -318,7 +318,8 @@ TEST_SUITE("Substring") {
|
||||
REQUIRE(SubsequenceCountSkip("aa", "baa") == std::make_tuple(true, 1));
|
||||
REQUIRE(SubsequenceCountSkip("aA", "aA") == std::make_tuple(true, 0));
|
||||
REQUIRE(SubsequenceCountSkip("aA", "aa") == std::make_tuple(false, 1));
|
||||
REQUIRE(SubsequenceCountSkip("incstdioh", "include <stdio.h>") == std::make_tuple(true, 7));
|
||||
REQUIRE(SubsequenceCountSkip("incstdioh", "include <stdio.h>") ==
|
||||
std::make_tuple(true, 7));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,9 @@ lsPosition CharPos(std::string_view search,
|
||||
char character,
|
||||
int character_offset = 0);
|
||||
|
||||
struct ParseIncludeLineResult
|
||||
{
|
||||
struct ParseIncludeLineResult {
|
||||
bool ok;
|
||||
std::string text; // include the "include" part
|
||||
std::string text; // include the "include" part
|
||||
std::smatch match;
|
||||
};
|
||||
|
||||
|
23
src/maybe.h
23
src/maybe.h
@ -10,7 +10,7 @@ template <typename T>
|
||||
class Maybe {
|
||||
T storage;
|
||||
|
||||
public:
|
||||
public:
|
||||
constexpr Maybe() = default;
|
||||
Maybe(const Maybe&) = default;
|
||||
Maybe(std::nullopt_t) {}
|
||||
@ -23,14 +23,12 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T *operator->() const { return &storage; }
|
||||
T *operator->() { return &storage; }
|
||||
const T* operator->() const { return &storage; }
|
||||
T* operator->() { return &storage; }
|
||||
const T& operator*() const { return storage; }
|
||||
T& operator*() { return storage; }
|
||||
|
||||
bool HasValue() const {
|
||||
return storage.HasValueForMaybe_();
|
||||
}
|
||||
bool HasValue() const { return storage.HasValueForMaybe_(); }
|
||||
explicit operator bool() const { return HasValue(); }
|
||||
operator optional<T>() const {
|
||||
if (HasValue())
|
||||
@ -38,16 +36,9 @@ public:
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
void operator=(optional<T>&& o) {
|
||||
storage = o ? *o : T();
|
||||
}
|
||||
void operator=(optional<T>&& o) { storage = o ? *o : T(); }
|
||||
|
||||
// Does not test if has_value()
|
||||
bool operator==(const Maybe& o) const {
|
||||
return storage == o.storage;
|
||||
}
|
||||
bool operator!=(const Maybe& o) const {
|
||||
return !(*this == o);
|
||||
}
|
||||
|
||||
bool operator==(const Maybe& o) const { return storage == o.storage; }
|
||||
bool operator!=(const Maybe& o) const { return !(*this == o); }
|
||||
};
|
||||
|
@ -56,8 +56,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildInitialCallTree(
|
||||
const QueryFunc::Def* def = root_func.AnyDef();
|
||||
if (!def || !def->spell)
|
||||
return {};
|
||||
optional<lsLocation> def_loc =
|
||||
GetLsLocation(db, working_files, *def->spell);
|
||||
optional<lsLocation> def_loc = GetLsLocation(db, working_files, *def->spell);
|
||||
if (!def_loc)
|
||||
return {};
|
||||
|
||||
@ -82,8 +81,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
||||
|
||||
std::vector<Out_CqueryCallTree::CallEntry> result;
|
||||
|
||||
auto handle_caller = [&](Use caller,
|
||||
Out_CqueryCallTree::CallType call_type) {
|
||||
auto handle_caller = [&](Use caller, Out_CqueryCallTree::CallType call_type) {
|
||||
optional<lsLocation> call_location =
|
||||
GetLsLocation(db, working_files, caller);
|
||||
if (!call_location)
|
||||
@ -133,8 +131,7 @@ std::vector<Out_CqueryCallTree::CallEntry> BuildExpandCallTree(
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Use> base_callers =
|
||||
GetCallersForAllBaseFunctions(db, root_func);
|
||||
std::vector<Use> base_callers = GetCallersForAllBaseFunctions(db, root_func);
|
||||
std::vector<Use> derived_callers =
|
||||
GetCallersForAllDerivedFunctions(db, root_func);
|
||||
result.reserve(root_func.uses.size() + base_callers.size() +
|
||||
|
@ -33,8 +33,9 @@ struct CqueryDerivedHandler : BaseMessageHandler<Ipc_CqueryDerived> {
|
||||
break;
|
||||
} else if (sym.kind == SymbolKind::Func) {
|
||||
QueryFunc& func = db->GetFunc(sym);
|
||||
out.result = GetLsLocationExs(db, working_files, ToUses(db, func.derived),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
out.result =
|
||||
GetLsLocationExs(db, working_files, ToUses(db, func.derived),
|
||||
config->xref.container, config->xref.maxNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -27,9 +27,10 @@ REGISTER_IPC_MESSAGE(Ipc_CqueryIndexFile);
|
||||
struct CqueryIndexFileHandler : BaseMessageHandler<Ipc_CqueryIndexFile> {
|
||||
void Run(Ipc_CqueryIndexFile* request) override {
|
||||
LOG_S(INFO) << "Indexing file " << request->params.path;
|
||||
QueueManager::instance()->index_request.PushBack(Index_Request(
|
||||
NormalizePath(request->params.path), request->params.args,
|
||||
request->params.is_interactive, request->params.contents, ICacheManager::Make(config)));
|
||||
QueueManager::instance()->index_request.PushBack(
|
||||
Index_Request(NormalizePath(request->params.path), request->params.args,
|
||||
request->params.is_interactive, request->params.contents,
|
||||
ICacheManager::Make(config)));
|
||||
}
|
||||
};
|
||||
REGISTER_MESSAGE_HANDLER(CqueryIndexFileHandler);
|
||||
|
@ -69,7 +69,7 @@ BuildInheritanceHierarchyForType(QueryDatabase* db,
|
||||
base.name = "[[Base]]";
|
||||
base.location = entry.location;
|
||||
base.children =
|
||||
BuildParentInheritanceHierarchyForType(db, working_files, root_type);
|
||||
BuildParentInheritanceHierarchyForType(db, working_files, root_type);
|
||||
if (!base.children.empty())
|
||||
entry.children.push_back(base);
|
||||
|
||||
@ -128,8 +128,7 @@ BuildInheritanceHierarchyForFunc(QueryDatabase* db,
|
||||
// Name and location.
|
||||
entry.name = def->detailed_name;
|
||||
if (def->spell)
|
||||
entry.location =
|
||||
GetLsLocation(db, working_files, *def->spell);
|
||||
entry.location = GetLsLocation(db, working_files, *def->spell);
|
||||
|
||||
entry.children.reserve(root_func.derived.size());
|
||||
|
||||
|
@ -67,8 +67,7 @@ ExpandNode(QueryDatabase* db, WorkingFiles* working_files, QueryTypeId root) {
|
||||
entry.name = def1->ShortName();
|
||||
entry.type_id = def1->type ? *def1->type : QueryTypeId();
|
||||
if (def->spell) {
|
||||
optional<lsLocation> loc =
|
||||
GetLsLocation(db, working_files, *def1->spell);
|
||||
optional<lsLocation> loc = GetLsLocation(db, working_files, *def1->spell);
|
||||
// TODO invalid location
|
||||
if (loc)
|
||||
entry.location = *loc;
|
||||
|
@ -19,11 +19,17 @@ const double kDamping = 0.1;
|
||||
template <typename Q>
|
||||
struct Kind;
|
||||
template <>
|
||||
struct Kind<QueryFunc> { static constexpr SymbolKind value = SymbolKind::Func; };
|
||||
struct Kind<QueryFunc> {
|
||||
static constexpr SymbolKind value = SymbolKind::Func;
|
||||
};
|
||||
template <>
|
||||
struct Kind<QueryType> { static constexpr SymbolKind value = SymbolKind::Type; };
|
||||
struct Kind<QueryType> {
|
||||
static constexpr SymbolKind value = SymbolKind::Type;
|
||||
};
|
||||
template <>
|
||||
struct Kind<QueryVar> { static constexpr SymbolKind value = SymbolKind::Var; };
|
||||
struct Kind<QueryVar> {
|
||||
static constexpr SymbolKind value = SymbolKind::Var;
|
||||
};
|
||||
|
||||
template <typename Q>
|
||||
void Add(const std::unordered_map<SymbolIdx, int>& sym2id,
|
||||
@ -109,7 +115,8 @@ struct CqueryRandomHandler : BaseMessageHandler<Ipc_CqueryRandom> {
|
||||
double d = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
d = std::max(d, fabs(x[i] - y[i]));
|
||||
if (d < 1e-5) break;
|
||||
if (d < 1e-5)
|
||||
break;
|
||||
x.swap(y);
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,8 @@ struct lsCompletionOptions {
|
||||
// for
|
||||
// '::' and '>' for '->'. See
|
||||
// https://github.com/Microsoft/language-server-protocol/issues/138.
|
||||
std::vector<std::string> triggerCharacters = {".", ":", ">", "#", "<", "\"", "/"};
|
||||
std::vector<std::string> triggerCharacters = {".", ":", ">", "#",
|
||||
"<", "\"", "/"};
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(lsCompletionOptions, resolveProvider, triggerCharacters);
|
||||
|
||||
@ -572,11 +573,12 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
||||
// Set project root.
|
||||
config->projectRoot = NormalizePath(request->params.rootUri->GetPath());
|
||||
EnsureEndsInSlash(config->projectRoot);
|
||||
// Create two cache directories for files inside and outside of the project.
|
||||
// Create two cache directories for files inside and outside of the
|
||||
// project.
|
||||
MakeDirectoryRecursive(config->cacheDirectory +
|
||||
EscapeFileName(config->projectRoot));
|
||||
MakeDirectoryRecursive(config->cacheDirectory +
|
||||
'@' + EscapeFileName(config->projectRoot));
|
||||
MakeDirectoryRecursive(config->cacheDirectory + '@' +
|
||||
EscapeFileName(config->projectRoot));
|
||||
|
||||
Timer time;
|
||||
|
||||
@ -595,7 +597,7 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
||||
// guess an appropriate value. Default to 80% utilization.
|
||||
const float kDefaultTargetUtilization = 0.8f;
|
||||
config->index.threads = (int)(std::thread::hardware_concurrency() *
|
||||
kDefaultTargetUtilization);
|
||||
kDefaultTargetUtilization);
|
||||
if (config->index.threads <= 0)
|
||||
config->index.threads = 1;
|
||||
}
|
||||
@ -614,19 +616,20 @@ struct InitializeHandler : BaseMessageHandler<Ipc_InitializeRequest> {
|
||||
|
||||
auto* queue = QueueManager::instance();
|
||||
time.Reset();
|
||||
project->ForAllFilteredFiles(config, [&](int i,
|
||||
const Project::Entry& entry) {
|
||||
optional<std::string> content = ReadContent(entry.filename);
|
||||
if (!content) {
|
||||
LOG_S(ERROR) << "When loading project, canont read file "
|
||||
<< entry.filename;
|
||||
return;
|
||||
}
|
||||
bool is_interactive =
|
||||
working_files->GetFileByFilename(entry.filename) != nullptr;
|
||||
queue->index_request.PushBack(Index_Request(
|
||||
entry.filename, entry.args, is_interactive, *content, ICacheManager::Make(config), request->id));
|
||||
});
|
||||
project->ForAllFilteredFiles(
|
||||
config, [&](int i, const Project::Entry& entry) {
|
||||
optional<std::string> content = ReadContent(entry.filename);
|
||||
if (!content) {
|
||||
LOG_S(ERROR) << "When loading project, canont read file "
|
||||
<< entry.filename;
|
||||
return;
|
||||
}
|
||||
bool is_interactive =
|
||||
working_files->GetFileByFilename(entry.filename) != nullptr;
|
||||
queue->index_request.PushBack(Index_Request(
|
||||
entry.filename, entry.args, is_interactive, *content,
|
||||
ICacheManager::Make(config), request->id));
|
||||
});
|
||||
|
||||
// We need to support multiple concurrent index processes.
|
||||
time.ResetAndPrint("[perf] Dispatched initial index requests");
|
||||
|
@ -211,8 +211,8 @@ optional<lsTextEdit> BuildAutoImplementForFunction(QueryDatabase* db,
|
||||
if (func_decl.file == decl_file_id) {
|
||||
int dist = func_decl.range.start.line - decl.range.start.line;
|
||||
if (abs(dist) < abs(best_dist)) {
|
||||
optional<lsLocation> def_loc = GetLsLocation(
|
||||
db, working_files, *def1->extent);
|
||||
optional<lsLocation> def_loc =
|
||||
GetLsLocation(db, working_files, *def1->extent);
|
||||
if (!def_loc)
|
||||
continue;
|
||||
|
||||
|
@ -237,8 +237,7 @@ struct TextDocumentCodeLensHandler
|
||||
}
|
||||
} else {
|
||||
AddCodeLens("base", "base", &common, OffsetStartColumn(use, 1),
|
||||
ToUses(db, def->base),
|
||||
false /*force_display*/);
|
||||
ToUses(db, def->base), false /*force_display*/);
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -122,8 +122,6 @@ void FilterAndSortCompletionResponse(
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
auto& items = complete_response->result.items;
|
||||
|
||||
auto finalize = [&]() {
|
||||
|
@ -24,12 +24,10 @@ struct Out_TextDocumentDefinition
|
||||
};
|
||||
MAKE_REFLECT_STRUCT(Out_TextDocumentDefinition, jsonrpc, id, result);
|
||||
|
||||
std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db,
|
||||
SymbolRef sym) {
|
||||
std::vector<Use> GetGotoDefinitionTargets(QueryDatabase* db, SymbolRef sym) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Var: {
|
||||
std::vector<Use> ret =
|
||||
GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||
std::vector<Use> ret = GetDeclarationsOfSymbolForGotoDefinition(db, sym);
|
||||
// If there is no declaration, jump the its type.
|
||||
if (ret.empty()) {
|
||||
for (auto& def : db->GetVar(sym).def)
|
||||
@ -158,7 +156,8 @@ struct TextDocumentDefinitionHandler
|
||||
}
|
||||
}
|
||||
if (best_i != -1) {
|
||||
Maybe<Use> use = GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]);
|
||||
Maybe<Use> use =
|
||||
GetDefinitionSpellingOfSymbol(db, db->symbols[best_i]);
|
||||
assert(use);
|
||||
if (auto ls_loc = GetLsLocationEx(db, working_files, *use,
|
||||
config->xref.container))
|
||||
|
@ -53,7 +53,8 @@ struct WorkspaceDidChangeWatchedFilesHandler
|
||||
LOG_S(ERROR) << "Unable to read file content after saving " << path;
|
||||
else {
|
||||
QueueManager::instance()->index_request.PushBack(
|
||||
Index_Request(path, entry.args, is_interactive, *content, ICacheManager::Make(config)));
|
||||
Index_Request(path, entry.args, is_interactive, *content,
|
||||
ICacheManager::Make(config)));
|
||||
if (is_interactive)
|
||||
clang_complete->NotifySave(path);
|
||||
}
|
||||
@ -61,7 +62,8 @@ struct WorkspaceDidChangeWatchedFilesHandler
|
||||
}
|
||||
case lsFileChangeType::Deleted:
|
||||
QueueManager::instance()->index_request.PushBack(
|
||||
Index_Request(path, entry.args, is_interactive, std::string(), ICacheManager::Make(config)));
|
||||
Index_Request(path, entry.args, is_interactive, std::string(),
|
||||
ICacheManager::Make(config)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +61,6 @@ MAKE_REFLECT_STRUCT(Out_WorkspaceSymbol, jsonrpc, id, result);
|
||||
|
||||
///// Fuzzy matching
|
||||
|
||||
|
||||
struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
||||
void Run(Ipc_WorkspaceSymbol* request) override {
|
||||
Out_WorkspaceSymbol out;
|
||||
@ -135,7 +134,8 @@ struct WorkspaceSymbolHandler : BaseMessageHandler<Ipc_WorkspaceSymbol> {
|
||||
std::vector<std::pair<int, int>> permutation(result_indices.size());
|
||||
for (int i = 0; i < int(result_indices.size()); i++) {
|
||||
permutation[i] = {
|
||||
FuzzyEvaluate(query, db->GetSymbolDetailedName(result_indices[i]), score, dp),
|
||||
FuzzyEvaluate(query, db->GetSymbolDetailedName(result_indices[i]),
|
||||
score, dp),
|
||||
i};
|
||||
}
|
||||
std::sort(permutation.begin(), permutation.end(),
|
||||
|
@ -37,6 +37,6 @@ class NtString {
|
||||
}
|
||||
bool operator==(const NtString& o) const {
|
||||
return str && o.str ? strcmp(c_str(), o.c_str()) == 0
|
||||
: c_str() == o.c_str();
|
||||
: c_str() == o.c_str();
|
||||
}
|
||||
};
|
||||
|
@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifndef __has_builtin
|
||||
# define __has_builtin(x) 0
|
||||
#define __has_builtin(x) 0
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
@ -21,7 +21,8 @@
|
||||
|
||||
void cquery_unreachable_internal(const char* msg, const char* file, int line);
|
||||
#ifndef NDEBUG
|
||||
#define CQUERY_UNREACHABLE(msg) cquery_unreachable_internal(msg, __FILE__, __LINE__)
|
||||
#define CQUERY_UNREACHABLE(msg) \
|
||||
cquery_unreachable_internal(msg, __FILE__, __LINE__)
|
||||
#else
|
||||
#define CQUERY_UNREACHABLE(msg)
|
||||
#endif
|
||||
|
123
src/project.cc
123
src/project.cc
@ -150,18 +150,19 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
// ie, compiler schedular such as goma. This allows correct parsing for
|
||||
// command lines like "goma clang -c foo".
|
||||
std::string::size_type dot;
|
||||
while (i < entry.args.size() && entry.args[i][0] != '-' &&
|
||||
// Do not skip over main source filename
|
||||
NormalizePathWithTestOptOut(entry.args[i]) != result.filename &&
|
||||
// There may be other filenames (e.g. more than one source filenames)
|
||||
// preceding main source filename. We use a heuristic here. `.` may
|
||||
// occur in both command names and source filenames. If `.` occurs in
|
||||
// the last 4 bytes of entry.args[i] and not followed by a digit, e.g.
|
||||
// .c .cpp, We take it as a source filename. Others (like ./a/b/goma
|
||||
// clang-4.0) are seen as commands.
|
||||
((dot = entry.args[i].rfind('.')) == std::string::npos ||
|
||||
dot + 4 < entry.args[i].size() || isdigit(entry.args[i][dot + 1]) ||
|
||||
!entry.args[i].compare(dot + 1, 3, "exe")))
|
||||
while (
|
||||
i < entry.args.size() && entry.args[i][0] != '-' &&
|
||||
// Do not skip over main source filename
|
||||
NormalizePathWithTestOptOut(entry.args[i]) != result.filename &&
|
||||
// There may be other filenames (e.g. more than one source filenames)
|
||||
// preceding main source filename. We use a heuristic here. `.` may
|
||||
// occur in both command names and source filenames. If `.` occurs in
|
||||
// the last 4 bytes of entry.args[i] and not followed by a digit, e.g.
|
||||
// .c .cpp, We take it as a source filename. Others (like ./a/b/goma
|
||||
// clang-4.0) are seen as commands.
|
||||
((dot = entry.args[i].rfind('.')) == std::string::npos ||
|
||||
dot + 4 < entry.args[i].size() || isdigit(entry.args[i][dot + 1]) ||
|
||||
!entry.args[i].compare(dot + 1, 3, "exe")))
|
||||
++i;
|
||||
}
|
||||
// Compiler driver.
|
||||
@ -174,14 +175,14 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
if (config->mode == ProjectMode::DotCquery &&
|
||||
!AnyStartsWith(entry.args, "-std=")) {
|
||||
switch (SourceFileLanguage(entry.file)) {
|
||||
case LanguageId::C:
|
||||
result.args.push_back("-std=gnu11");
|
||||
break;
|
||||
case LanguageId::Cpp:
|
||||
result.args.push_back("-std=gnu++14");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case LanguageId::C:
|
||||
result.args.push_back("-std=gnu11");
|
||||
break;
|
||||
case LanguageId::Cpp:
|
||||
result.args.push_back("-std=gnu++14");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,17 +307,17 @@ std::vector<Project::Entry> LoadFromDirectoryListing(Config* init_opts,
|
||||
std::unordered_map<std::string, std::vector<std::string>> folder_args;
|
||||
std::vector<std::string> files;
|
||||
|
||||
GetFilesInFolder(
|
||||
config->project_dir, true /*recursive*/, true /*add_folder_to_path*/,
|
||||
[&folder_args, &files](const std::string& path) {
|
||||
if (SourceFileLanguage(path) != LanguageId::Unknown) {
|
||||
files.push_back(path);
|
||||
} else if (GetBaseName(path) == ".cquery") {
|
||||
LOG_S(INFO) << "Using .cquery arguments from " << path;
|
||||
folder_args.emplace(GetDirName(path),
|
||||
ReadCompilerArgumentsFromFile(path));
|
||||
}
|
||||
});
|
||||
GetFilesInFolder(config->project_dir, true /*recursive*/,
|
||||
true /*add_folder_to_path*/,
|
||||
[&folder_args, &files](const std::string& path) {
|
||||
if (SourceFileLanguage(path) != LanguageId::Unknown) {
|
||||
files.push_back(path);
|
||||
} else if (GetBaseName(path) == ".cquery") {
|
||||
LOG_S(INFO) << "Using .cquery arguments from " << path;
|
||||
folder_args.emplace(GetDirName(path),
|
||||
ReadCompilerArgumentsFromFile(path));
|
||||
}
|
||||
});
|
||||
|
||||
const auto& project_dir_args = folder_args[config->project_dir];
|
||||
LOG_IF_S(INFO, !project_dir_args.empty())
|
||||
@ -407,7 +408,7 @@ std::vector<Project::Entry> LoadCompilationEntriesFromDirectory(
|
||||
comp_db_dir.c_str(), &cx_db_load_error);
|
||||
if (!init_opts->compilationDatabaseCommand.empty()) {
|
||||
#ifdef _WIN32
|
||||
// TODO
|
||||
// TODO
|
||||
#else
|
||||
unlink((comp_db_dir + "/compile_commands.json").c_str());
|
||||
rmdir(comp_db_dir.c_str());
|
||||
@ -656,16 +657,16 @@ TEST_SUITE("Project") {
|
||||
CheckFlags(
|
||||
/* raw */ {"clang", "-lstdc++", "myfile.cc"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "/dir/",
|
||||
"-lstdc++", "&/dir/myfile.cc", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
{"clang", "-working-directory", "/dir/", "-lstdc++", "&/dir/myfile.cc",
|
||||
"-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option",
|
||||
"-fparse-all-comments"});
|
||||
|
||||
CheckFlags(
|
||||
/* raw */ {"clang.exe"},
|
||||
/* expected */
|
||||
{"clang.exe", "-working-directory", "/dir/",
|
||||
"-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option",
|
||||
"-fparse-all-comments"});
|
||||
"-fparse-all-comments"});
|
||||
|
||||
CheckFlags(
|
||||
/* raw */ {"goma", "clang"},
|
||||
@ -683,40 +684,36 @@ TEST_SUITE("Project") {
|
||||
}
|
||||
|
||||
TEST_CASE("Windows path normalization") {
|
||||
CheckFlags(
|
||||
"E:/workdir", "E:/workdir/bar.cc", /* raw */ {"clang", "bar.cc"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "E:/workdir",
|
||||
"&E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
CheckFlags("E:/workdir", "E:/workdir/bar.cc", /* raw */ {"clang", "bar.cc"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "E:/workdir",
|
||||
"&E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
|
||||
CheckFlags(
|
||||
"E:/workdir", "E:/workdir/bar.cc",
|
||||
/* raw */ {"clang", "E:/workdir/bar.cc"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "E:/workdir",
|
||||
"&E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
CheckFlags("E:/workdir", "E:/workdir/bar.cc",
|
||||
/* raw */ {"clang", "E:/workdir/bar.cc"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "E:/workdir",
|
||||
"&E:/workdir/bar.cc", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
}
|
||||
|
||||
TEST_CASE("Path in args") {
|
||||
CheckFlags(
|
||||
"/home/user", "/home/user/foo/bar.c",
|
||||
/* raw */ {"cc", "-O0", "foo/bar.c"},
|
||||
/* expected */
|
||||
{"cc", "-working-directory", "/home/user", "-O0",
|
||||
"&/home/user/foo/bar.c", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
CheckFlags("/home/user", "/home/user/foo/bar.c",
|
||||
/* raw */ {"cc", "-O0", "foo/bar.c"},
|
||||
/* expected */
|
||||
{"cc", "-working-directory", "/home/user", "-O0",
|
||||
"&/home/user/foo/bar.c", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
}
|
||||
|
||||
TEST_CASE("Implied binary") {
|
||||
CheckFlags(
|
||||
"/home/user", "/home/user/foo/bar.cc",
|
||||
/* raw */ {"clang", "-DDONT_IGNORE_ME"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "/home/user",
|
||||
"-DDONT_IGNORE_ME", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
CheckFlags("/home/user", "/home/user/foo/bar.cc",
|
||||
/* raw */ {"clang", "-DDONT_IGNORE_ME"},
|
||||
/* expected */
|
||||
{"clang", "-working-directory", "/home/user", "-DDONT_IGNORE_ME",
|
||||
"-resource-dir=/w/resource_dir/", "-Wno-unknown-warning-option",
|
||||
"-fparse-all-comments"});
|
||||
}
|
||||
|
||||
// Checks flag parsing for a random chromium file in comparison to what
|
||||
|
79
src/query.cc
79
src/query.cc
@ -106,9 +106,8 @@ optional<QueryVar::Def> ToQuery(const IdMap& id_map, const IndexVar::Def& var) {
|
||||
// the destination type already exists, it will be combined. This makes merging
|
||||
// updates take longer but reduces import time on the querydb thread.
|
||||
template <typename TId, typename TValue>
|
||||
void AddMergeableRange(
|
||||
std::vector<MergeableUpdate<TId, TValue>>* dest,
|
||||
std::vector<MergeableUpdate<TId, TValue>>&& source) {
|
||||
void AddMergeableRange(std::vector<MergeableUpdate<TId, TValue>>* dest,
|
||||
std::vector<MergeableUpdate<TId, TValue>>&& source) {
|
||||
// TODO: Consider caching the lookup table. It can probably save even more
|
||||
// time at the cost of some additional memory.
|
||||
|
||||
@ -208,7 +207,8 @@ void CompareGroups(std::vector<T>& previous_data,
|
||||
}
|
||||
}
|
||||
|
||||
QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& indexed) {
|
||||
QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map,
|
||||
const IndexFile& indexed) {
|
||||
QueryFile::Def def;
|
||||
def.file = id_map.primary_file;
|
||||
def.path = indexed.path;
|
||||
@ -234,8 +234,7 @@ QueryFile::DefUpdate BuildFileDefUpdate(const IdMap& id_map, const IndexFile& in
|
||||
}();
|
||||
|
||||
auto add_all_symbols = [&](Use use, Id<void> id, SymbolKind kind) {
|
||||
def.all_symbols.push_back(
|
||||
SymbolRef(use.range, id, kind, use.role));
|
||||
def.all_symbols.push_back(SymbolRef(use.range, id, kind, use.role));
|
||||
};
|
||||
auto add_outline = [&](Use use, Id<void> id, SymbolKind kind) {
|
||||
def.outline.push_back(SymbolRef(use.range, id, kind, use.role));
|
||||
@ -440,20 +439,20 @@ QueryVarId IdMap::ToQuery(IndexVarId id) const {
|
||||
Use IdMap::ToQuery(Reference ref) const {
|
||||
Use ret(ref.range, ref.id, ref.kind, ref.role, primary_file);
|
||||
switch (ref.kind) {
|
||||
case SymbolKind::Invalid:
|
||||
break;
|
||||
case SymbolKind::File:
|
||||
ret.id = primary_file;
|
||||
break;
|
||||
case SymbolKind::Func:
|
||||
ret.id = ToQuery(IndexFuncId(ref.id));
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
ret.id = ToQuery(IndexTypeId(ref.id));
|
||||
break;
|
||||
case SymbolKind::Var:
|
||||
ret.id = ToQuery(IndexVarId(ref.id));
|
||||
break;
|
||||
case SymbolKind::Invalid:
|
||||
break;
|
||||
case SymbolKind::File:
|
||||
ret.id = primary_file;
|
||||
break;
|
||||
case SymbolKind::Func:
|
||||
ret.id = ToQuery(IndexFuncId(ref.id));
|
||||
break;
|
||||
case SymbolKind::Type:
|
||||
ret.id = ToQuery(IndexTypeId(ref.id));
|
||||
break;
|
||||
case SymbolKind::Var:
|
||||
ret.id = ToQuery(IndexVarId(ref.id));
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -532,9 +531,9 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
previous_id_map.ToQuery(type->id), {},
|
||||
previous_id_map.ToQuery(type->declarations)));
|
||||
if (!type->derived.empty())
|
||||
types_derived.push_back(QueryType::DerivedUpdate(
|
||||
previous_id_map.ToQuery(type->id), {},
|
||||
previous_id_map.ToQuery(type->derived)));
|
||||
types_derived.push_back(
|
||||
QueryType::DerivedUpdate(previous_id_map.ToQuery(type->id), {},
|
||||
previous_id_map.ToQuery(type->derived)));
|
||||
if (!type->instances.empty())
|
||||
types_instances.push_back(QueryType::InstancesUpdate(
|
||||
previous_id_map.ToQuery(type->id), {},
|
||||
@ -601,13 +600,13 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
previous_id_map.ToQuery(func->id), {},
|
||||
previous_id_map.ToQuery(func->declarations)));
|
||||
if (!func->derived.empty())
|
||||
funcs_derived.push_back(QueryFunc::DerivedUpdate(
|
||||
previous_id_map.ToQuery(func->id), {},
|
||||
previous_id_map.ToQuery(func->derived)));
|
||||
funcs_derived.push_back(
|
||||
QueryFunc::DerivedUpdate(previous_id_map.ToQuery(func->id), {},
|
||||
previous_id_map.ToQuery(func->derived)));
|
||||
if (!func->uses.empty())
|
||||
funcs_uses.push_back(QueryFunc::UsesUpdate(
|
||||
previous_id_map.ToQuery(func->id), {},
|
||||
previous_id_map.ToQuery(func->uses)));
|
||||
funcs_uses.push_back(
|
||||
QueryFunc::UsesUpdate(previous_id_map.ToQuery(func->id), {},
|
||||
previous_id_map.ToQuery(func->uses)));
|
||||
},
|
||||
/*onAdded:*/
|
||||
[this, ¤t_id_map](IndexFunc* func) {
|
||||
@ -643,8 +642,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
current->usr, std::move(*current_remapped_def)));
|
||||
}
|
||||
|
||||
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations,
|
||||
Use);
|
||||
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_declarations, declarations, Use);
|
||||
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_derived, derived, QueryFuncId);
|
||||
PROCESS_UPDATE_DIFF(QueryFuncId, funcs_uses, uses, Use);
|
||||
});
|
||||
@ -663,7 +661,7 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
if (!var->uses.empty())
|
||||
vars_uses.push_back(
|
||||
QueryVar::UsesUpdate(previous_id_map.ToQuery(var->id), {},
|
||||
previous_id_map.ToQuery(var->uses)));
|
||||
previous_id_map.ToQuery(var->uses)));
|
||||
},
|
||||
/*onAdded:*/
|
||||
[this, ¤t_id_map](IndexVar* var) {
|
||||
@ -703,7 +701,8 @@ IndexUpdate::IndexUpdate(const IdMap& previous_id_map,
|
||||
// This function runs on an indexer thread.
|
||||
void IndexUpdate::Merge(IndexUpdate&& update) {
|
||||
#define INDEX_UPDATE_APPEND(name) AddRange(&name, std::move(update.name));
|
||||
#define INDEX_UPDATE_MERGE(name) AddMergeableRange(&name, std::move(update.name));
|
||||
#define INDEX_UPDATE_MERGE(name) \
|
||||
AddMergeableRange(&name, std::move(update.name));
|
||||
|
||||
INDEX_UPDATE_APPEND(files_removed);
|
||||
INDEX_UPDATE_APPEND(files_def_update);
|
||||
@ -987,7 +986,6 @@ std::string_view QueryDatabase::GetSymbolShortName(RawId symbol_idx) const {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
TEST_SUITE("query") {
|
||||
IndexUpdate GetDelta(IndexFile previous, IndexFile current) {
|
||||
QueryDatabase db;
|
||||
@ -1051,11 +1049,9 @@ TEST_SUITE("query") {
|
||||
REQUIRE(update.funcs_uses.size() == 1);
|
||||
REQUIRE(update.funcs_uses[0].id == QueryFuncId(0));
|
||||
REQUIRE(update.funcs_uses[0].to_remove.size() == 1);
|
||||
REQUIRE(update.funcs_uses[0].to_remove[0].range ==
|
||||
Range(Position(1, 0)));
|
||||
REQUIRE(update.funcs_uses[0].to_remove[0].range == Range(Position(1, 0)));
|
||||
REQUIRE(update.funcs_uses[0].to_add.size() == 1);
|
||||
REQUIRE(update.funcs_uses[0].to_add[0].range ==
|
||||
Range(Position(2, 0)));
|
||||
REQUIRE(update.funcs_uses[0].to_add[0].range == Range(Position(2, 0)));
|
||||
}
|
||||
|
||||
TEST_CASE("type usages") {
|
||||
@ -1113,7 +1109,8 @@ TEST_SUITE("query") {
|
||||
|
||||
TEST_CASE("Remove variable with usage") {
|
||||
auto load_index_from_json = [](const char* json) {
|
||||
return Deserialize(SerializeFormat::Json, "foo.cc", json, "<empty>", nullopt);
|
||||
return Deserialize(SerializeFormat::Json, "foo.cc", json, "<empty>",
|
||||
nullopt);
|
||||
};
|
||||
|
||||
auto previous = load_index_from_json(R"RAW(
|
||||
@ -1220,8 +1217,8 @@ TEST_SUITE("query") {
|
||||
// Apply initial file.
|
||||
{
|
||||
IdMap previous_map(&db, previous->id_cache);
|
||||
IndexUpdate import_update =
|
||||
IndexUpdate::CreateDelta(nullptr, &previous_map, nullptr, previous.get());
|
||||
IndexUpdate import_update = IndexUpdate::CreateDelta(
|
||||
nullptr, &previous_map, nullptr, previous.get());
|
||||
db.ApplyIndexUpdate(&import_update);
|
||||
}
|
||||
|
||||
|
31
src/query.h
31
src/query.h
@ -76,7 +76,8 @@ struct WithFileContent {
|
||||
T value;
|
||||
std::string file_content;
|
||||
|
||||
WithFileContent(const T& value, const std::string& file_content) : value(value), file_content(file_content) {}
|
||||
WithFileContent(const T& value, const std::string& file_content)
|
||||
: value(value), file_content(file_content) {}
|
||||
};
|
||||
template <typename TVisitor, typename T>
|
||||
void Reflect(TVisitor& visitor, WithFileContent<T>& value) {
|
||||
@ -144,9 +145,7 @@ struct QueryEntity {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
const Def* AnyDef() const {
|
||||
return const_cast<QueryEntity*>(this)->AnyDef();
|
||||
}
|
||||
const Def* AnyDef() const { return const_cast<QueryEntity*>(this)->AnyDef(); }
|
||||
};
|
||||
|
||||
struct QueryType : QueryEntity<QueryType, TypeDefDefinitionData<QueryFamily>> {
|
||||
@ -296,14 +295,17 @@ struct QueryDatabase {
|
||||
|
||||
// Marks the given Usrs as invalid.
|
||||
void RemoveUsrs(SymbolKind usr_kind, const std::vector<Usr>& to_remove);
|
||||
void RemoveUsrs(SymbolKind usr_kind, const std::vector<WithUsr<QueryFileId>>& to_remove);
|
||||
void RemoveUsrs(SymbolKind usr_kind,
|
||||
const std::vector<WithUsr<QueryFileId>>& to_remove);
|
||||
// Insert the contents of |update| into |db|.
|
||||
void ApplyIndexUpdate(IndexUpdate* update);
|
||||
void ImportOrUpdate(const std::vector<QueryFile::DefUpdate>& updates);
|
||||
void ImportOrUpdate(std::vector<QueryType::DefUpdate>&& updates);
|
||||
void ImportOrUpdate(std::vector<QueryFunc::DefUpdate>&& updates);
|
||||
void ImportOrUpdate(std::vector<QueryVar::DefUpdate>&& updates);
|
||||
void UpdateSymbols(Maybe<Id<void>>* symbol_idx, SymbolKind kind, Id<void> idx);
|
||||
void UpdateSymbols(Maybe<Id<void>>* symbol_idx,
|
||||
SymbolKind kind,
|
||||
Id<void> idx);
|
||||
std::string_view GetSymbolDetailedName(RawId symbol_idx) const;
|
||||
std::string_view GetSymbolShortName(RawId symbol_idx) const;
|
||||
|
||||
@ -313,18 +315,10 @@ struct QueryDatabase {
|
||||
Maybe<QueryFuncId> GetQueryFuncIdFromUsr(Usr usr);
|
||||
Maybe<QueryVarId> GetQueryVarIdFromUsr(Usr usr);
|
||||
|
||||
QueryFile& GetFile(SymbolIdx ref) {
|
||||
return files[ref.id.id];
|
||||
}
|
||||
QueryFunc& GetFunc(SymbolIdx ref) {
|
||||
return funcs[ref.id.id];
|
||||
}
|
||||
QueryType& GetType(SymbolIdx ref) {
|
||||
return types[ref.id.id];
|
||||
}
|
||||
QueryVar& GetVar(SymbolIdx ref) {
|
||||
return vars[ref.id.id];
|
||||
}
|
||||
QueryFile& GetFile(SymbolIdx ref) { return files[ref.id.id]; }
|
||||
QueryFunc& GetFunc(SymbolIdx ref) { return funcs[ref.id.id]; }
|
||||
QueryType& GetType(SymbolIdx ref) { return types[ref.id.id]; }
|
||||
QueryVar& GetVar(SymbolIdx ref) { return vars[ref.id.id]; }
|
||||
};
|
||||
|
||||
template <typename I>
|
||||
@ -377,7 +371,6 @@ struct IdMap {
|
||||
}
|
||||
// clang-format on
|
||||
|
||||
|
||||
private:
|
||||
spp::sparse_hash_map<IndexTypeId, QueryTypeId> cached_type_ids_;
|
||||
spp::sparse_hash_map<IndexFuncId, QueryFuncId> cached_func_ids_;
|
||||
|
@ -40,8 +40,7 @@ std::vector<Use> ToUsesHelper(std::vector<Q>& entities,
|
||||
|
||||
} // namespace
|
||||
|
||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
SymbolIdx sym) {
|
||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db, SymbolIdx sym) {
|
||||
Maybe<Use> ret;
|
||||
EachEntityDef(db, sym, [&](const auto& def) { return !(ret = def.spell); });
|
||||
return ret;
|
||||
@ -102,9 +101,8 @@ std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids) {
|
||||
return ToUsesHelper(db->vars, ids);
|
||||
}
|
||||
|
||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||
QueryDatabase* db,
|
||||
SymbolIdx sym) {
|
||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(QueryDatabase* db,
|
||||
SymbolIdx sym) {
|
||||
switch (sym.kind) {
|
||||
case SymbolKind::Func:
|
||||
return db->GetFunc(sym).declarations;
|
||||
|
@ -5,22 +5,17 @@
|
||||
|
||||
#include <optional.h>
|
||||
|
||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db,
|
||||
SymbolIdx sym);
|
||||
Maybe<Use> GetDefinitionSpellingOfSymbol(QueryDatabase* db, SymbolIdx sym);
|
||||
Maybe<Use> GetDefinitionExtentOfSymbol(QueryDatabase* db, SymbolIdx sym);
|
||||
Maybe<QueryFileId> GetDeclarationFileForSymbol(QueryDatabase* db,
|
||||
SymbolIdx sym);
|
||||
|
||||
std::vector<Use> ToUses(QueryDatabase* db,
|
||||
const std::vector<QueryFuncId>& ids);
|
||||
std::vector<Use> ToUses(QueryDatabase* db,
|
||||
const std::vector<QueryTypeId>& ids);
|
||||
std::vector<Use> ToUses(QueryDatabase* db,
|
||||
const std::vector<QueryVarId>& ids);
|
||||
std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryFuncId>& ids);
|
||||
std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryTypeId>& ids);
|
||||
std::vector<Use> ToUses(QueryDatabase* db, const std::vector<QueryVarId>& ids);
|
||||
|
||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(
|
||||
QueryDatabase* db,
|
||||
SymbolIdx sym);
|
||||
std::vector<Use> GetDeclarationsOfSymbolForGotoDefinition(QueryDatabase* db,
|
||||
SymbolIdx sym);
|
||||
|
||||
bool HasCallersOnSelfOrBaseOrDerived(QueryDatabase* db, QueryFunc& root);
|
||||
std::vector<Use> GetCallersForAllBaseFunctions(QueryDatabase* db,
|
||||
@ -104,7 +99,9 @@ void EachUse(QueryDatabase* db, SymbolIdx sym, bool include_decl, Fn&& fn) {
|
||||
}
|
||||
|
||||
template <typename Q, typename Fn>
|
||||
void EachDefinedEntity(std::vector<Q>& collection, const std::vector<Id<Q>>& ids, Fn&& fn) {
|
||||
void EachDefinedEntity(std::vector<Q>& collection,
|
||||
const std::vector<Id<Q>>& ids,
|
||||
Fn&& fn) {
|
||||
for (Id<Q> x : ids) {
|
||||
Q& obj = collection[x.id];
|
||||
if (!obj.def.empty())
|
||||
|
@ -6,12 +6,13 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
Index_Request::Index_Request(const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool is_interactive,
|
||||
const std::string& contents,
|
||||
const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
lsRequestId id)
|
||||
Index_Request::Index_Request(
|
||||
const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool is_interactive,
|
||||
const std::string& contents,
|
||||
const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
lsRequestId id)
|
||||
: path(path),
|
||||
args(args),
|
||||
is_interactive(is_interactive),
|
||||
@ -19,11 +20,12 @@ Index_Request::Index_Request(const std::string& path,
|
||||
cache_manager(cache_manager),
|
||||
id(id) {}
|
||||
|
||||
Index_DoIdMap::Index_DoIdMap(std::unique_ptr<IndexFile> current,
|
||||
const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
PerformanceImportFile perf,
|
||||
bool is_interactive,
|
||||
bool write_to_disk)
|
||||
Index_DoIdMap::Index_DoIdMap(
|
||||
std::unique_ptr<IndexFile> current,
|
||||
const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
PerformanceImportFile perf,
|
||||
bool is_interactive,
|
||||
bool write_to_disk)
|
||||
: current(std::move(current)),
|
||||
cache_manager(cache_manager),
|
||||
perf(perf),
|
||||
@ -36,10 +38,11 @@ Index_OnIdMapped::File::File(std::unique_ptr<IndexFile> file,
|
||||
std::unique_ptr<IdMap> ids)
|
||||
: file(std::move(file)), ids(std::move(ids)) {}
|
||||
|
||||
Index_OnIdMapped::Index_OnIdMapped(const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
PerformanceImportFile perf,
|
||||
bool is_interactive,
|
||||
bool write_to_disk)
|
||||
Index_OnIdMapped::Index_OnIdMapped(
|
||||
const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
PerformanceImportFile perf,
|
||||
bool is_interactive,
|
||||
bool write_to_disk)
|
||||
: cache_manager(cache_manager),
|
||||
perf(perf),
|
||||
is_interactive(is_interactive),
|
||||
@ -47,7 +50,7 @@ Index_OnIdMapped::Index_OnIdMapped(const std::shared_ptr<ICacheManager>& cache_m
|
||||
|
||||
Index_OnIndexed::Index_OnIndexed(IndexUpdate&& update,
|
||||
PerformanceImportFile perf)
|
||||
: update(std::move(update)), perf(perf) {}
|
||||
: update(std::move(update)), perf(perf) {}
|
||||
|
||||
QueueManager* QueueManager::instance_ = nullptr;
|
||||
|
||||
|
@ -24,7 +24,6 @@ struct Index_Request {
|
||||
std::shared_ptr<ICacheManager> cache_manager;
|
||||
lsRequestId id;
|
||||
|
||||
|
||||
Index_Request(const std::string& path,
|
||||
const std::vector<std::string>& args,
|
||||
bool is_interactive,
|
||||
@ -67,7 +66,7 @@ struct Index_OnIdMapped {
|
||||
bool write_to_disk;
|
||||
|
||||
Index_OnIdMapped(const std::shared_ptr<ICacheManager>& cache_manager,
|
||||
PerformanceImportFile perf,
|
||||
PerformanceImportFile perf,
|
||||
bool is_interactive,
|
||||
bool write_to_disk);
|
||||
};
|
||||
|
@ -18,10 +18,10 @@ void EnableRecording(std::string path) {
|
||||
assert(!g_file_in && !g_file_out);
|
||||
|
||||
// Open the files.
|
||||
g_file_in = new std::ofstream(path + ".in",
|
||||
std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
g_file_out = new std::ofstream(path + ".out",
|
||||
std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
g_file_in = new std::ofstream(
|
||||
path + ".in", std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
g_file_out = new std::ofstream(
|
||||
path + ".out", std::ios::out | std::ios::trunc | std::ios::binary);
|
||||
|
||||
// Make sure we can write to the files.
|
||||
bool bad = false;
|
||||
|
@ -357,11 +357,12 @@ std::string Serialize(SerializeFormat format, IndexFile& file) {
|
||||
return "";
|
||||
}
|
||||
|
||||
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
||||
const std::string& path,
|
||||
const std::string& serialized_index_content,
|
||||
const std::string& file_content,
|
||||
optional<int> expected_version) {
|
||||
std::unique_ptr<IndexFile> Deserialize(
|
||||
SerializeFormat format,
|
||||
const std::string& path,
|
||||
const std::string& serialized_index_content,
|
||||
const std::string& file_content,
|
||||
optional<int> expected_version) {
|
||||
if (serialized_index_content.empty())
|
||||
return nullptr;
|
||||
|
||||
@ -401,7 +402,8 @@ std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
||||
throw std::invalid_argument("Invalid");
|
||||
msgpack::unpacker upk;
|
||||
upk.reserve_buffer(serialized_index_content.size());
|
||||
memcpy(upk.buffer(), serialized_index_content.data(), serialized_index_content.size());
|
||||
memcpy(upk.buffer(), serialized_index_content.data(),
|
||||
serialized_index_content.size());
|
||||
upk.buffer_consumed(serialized_index_content.size());
|
||||
file = MakeUnique<IndexFile>(path, file_content);
|
||||
MessagePackReader reader(&upk);
|
||||
|
@ -358,10 +358,11 @@ void ReflectMember(Writer& visitor, const char* name, T& value) {
|
||||
// API
|
||||
|
||||
std::string Serialize(SerializeFormat format, IndexFile& file);
|
||||
std::unique_ptr<IndexFile> Deserialize(SerializeFormat format,
|
||||
const std::string& path,
|
||||
const std::string& serialized_index_content,
|
||||
const std::string& file_content,
|
||||
optional<int> expected_version);
|
||||
std::unique_ptr<IndexFile> Deserialize(
|
||||
SerializeFormat format,
|
||||
const std::string& path,
|
||||
const std::string& serialized_index_content,
|
||||
const std::string& file_content,
|
||||
optional<int> expected_version);
|
||||
|
||||
void SetTestOutputMode();
|
||||
|
@ -109,8 +109,8 @@ enum class lsSymbolKind : uint8_t {
|
||||
TypeParameter = 26,
|
||||
|
||||
// cquery extensions
|
||||
// See also https://github.com/Microsoft/language-server-protocol/issues/344 for new SymbolKind
|
||||
// clang/Index/IndexSymbol.h clang::index::SymbolKind
|
||||
// See also https://github.com/Microsoft/language-server-protocol/issues/344
|
||||
// for new SymbolKind clang/Index/IndexSymbol.h clang::index::SymbolKind
|
||||
Parameter = 13,
|
||||
StaticMethod = 254,
|
||||
Macro = 255,
|
||||
|
@ -167,10 +167,10 @@ bool RunIndexTests(const std::string& filter_path, bool enable_update) {
|
||||
true /*add_folder_to_path*/)) {
|
||||
bool is_fail_allowed = false;
|
||||
|
||||
if (EndsWithAny(path, { ".m", ".mm" })) {
|
||||
if (EndsWithAny(path, {".m", ".mm"})) {
|
||||
if (!RunObjectiveCIndexTests()) {
|
||||
std::cout << "Skipping \"" << path << "\" since this platform does not "
|
||||
<< "support running Objective-C tests." << std::endl;
|
||||
<< "support running Objective-C tests." << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -209,9 +209,7 @@ struct ThreadedQueue : public BaseThreadQueue {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<T> TryPopFront() {
|
||||
return TryPopFrontHelper(3);
|
||||
}
|
||||
optional<T> TryPopFront() { return TryPopFrontHelper(3); }
|
||||
|
||||
optional<T> TryPopBack() {
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
@ -229,13 +227,9 @@ struct ThreadedQueue : public BaseThreadQueue {
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
optional<T> TryPopFrontLow() {
|
||||
return TryPopFrontHelper(1);
|
||||
}
|
||||
optional<T> TryPopFrontLow() { return TryPopFrontHelper(1); }
|
||||
|
||||
optional<T> TryPopFrontHigh() {
|
||||
return TryPopFrontHelper(2);
|
||||
}
|
||||
optional<T> TryPopFrontHigh() { return TryPopFrontHelper(2); }
|
||||
|
||||
mutable std::mutex mutex_;
|
||||
|
||||
|
@ -123,8 +123,10 @@ std::string GetDirName(std::string path) {
|
||||
if (path.size() && path.back() == '/')
|
||||
path.pop_back();
|
||||
size_t last_slash = path.find_last_of('/');
|
||||
if (last_slash == std::string::npos) return ".";
|
||||
if (last_slash == 0) return "/";
|
||||
if (last_slash == std::string::npos)
|
||||
return ".";
|
||||
if (last_slash == 0)
|
||||
return "/";
|
||||
return path.substr(0, last_slash);
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
@ -33,7 +33,8 @@ bool EndsWithAny(const std::string& value,
|
||||
const std::vector<std::string>& endings);
|
||||
bool FindAnyPartial(const std::string& value,
|
||||
const std::vector<std::string>& values);
|
||||
// Returns the dirname of |path|, i.e. "foo/bar.cc" => "foo", "foo" => ".", "/foo" => "/".
|
||||
// Returns the dirname of |path|, i.e. "foo/bar.cc" => "foo", "foo" => ".",
|
||||
// "/foo" => "/".
|
||||
std::string GetDirName(std::string path);
|
||||
// Returns the basename of |path|, ie, "foo/bar.cc" => "bar.cc".
|
||||
std::string GetBaseName(const std::string& path);
|
||||
|
Loading…
Reference in New Issue
Block a user